General Purpose Configurable Material System

From XNAWiki
Jump to: navigation, search

This is a material sampling system for shaders which is configured through the pre-processor directives displayed in the Sampler Config section.

The sampler can be used by calling into any of the following three functions:

  • SampleDiffuse(texCoord, texRepeat, weights)
  • SampleSpecular(texCoord, texRepeat, weights)
  • SampleNormal(texCoord, texRepeat, weights)

The parameters exposed to the Effect are:

  • Diffuse0, Diffuse1, Diffuse2, Diffuse3 - diffuse textures, depending upon the MATERIAL_COUNT some or all of these may be present.
  • Normal0, Normal1, Normal2, Normal3 - normal map textures, depending upon the MATERIAL_COUNT some or all of these may be present.
  • Specular0, Specular1, Specular2, Specular3 - specular textures, depending upon the MATERIAL_COUNT some or all of these may be present.
// =============================================================================================
//	Sampler Config - all of these are completely optional in the implementing shader
// =============================================================================================
 
//#define DIFFUSE_ADDRESS_U			Wrap
//#define DIFFUSE_ADDRESS_V			Wrap
//#define DIFFUSE_ADDRESS_W			Wrap
//#define DIFFUSE_MIN_FILTER		Linear
//#define DIFFUSE_MAG_FILTER		Linear
//#define DIFFUSE_MIP_FILTER		Linear
//#define DIFFUSE_MAX_ANISOTROPY	16
//#define DIFFUSE_MAX_MIP_LEVEL		0
//#define DIFFUSE_MIP_MAP_LOD_BIAS	0
//#define DIFFUSE_BORDER_COLOR		float4(0, 0, 0, 1)
//#define DIFFUSE_SRGB_TEXTURE		0
 
//#define NORMAL_ADDRESS_U			Wrap
//#define NORMAL_ADDRESS_V			Wrap
//#define NORMAL_ADDRESS_W			Wrap
//#define NORMAL_MIN_FILTER			Linear
//#define NORMAL_MAG_FILTER			Linear
//#define NORMAL_MIP_FILTER			Linear
//#define NORMAL_MAX_ANISOTROPY		16
//#define NORMAL_MAX_MIP_LEVEL		0
//#define NORMAL_MIP_MAP_LOD_BIAS	0
//#define NORMAL_BORDER_COLOR		float4(0, 0, 0, 1)
//#define NORMAL_SRGB_TEXTURE		0
 
//#define SPECULAR_ADDRESS_U		Wrap
//#define SPECULAR_ADDRESS_V		Wrap
//#define SPECULAR_ADDRESS_W		Wrap
//#define SPECULAR_MIN_FILTER		Linear
//#define SPECULAR_MAG_FILTER		Linear
//#define SPECULAR_MIP_FILTER		Linear
//#define SPECULAR_MAX_ANISOTROPY	16
//#define SPECULAR_MAX_MIP_LEVEL	0
//#define SPECULAR_MIP_MAP_LOD_BIAS	0
//#define SPECULAR_BORDER_COLOR		float4(0, 0, 0, 1)
//#define SPECULAR_SRGB_TEXTURE		0
 
//#define MATERIAL_COUNT	1
 
//#define DecodeNormal(sampler, texCoord) (function body)
// OR
//#define DecodeNormal
//float3 DecodeNormal(sampler s, float2 texCoord) { function body }
 
// the sampler functions exposed are:
//	SampleDiffuse(texCoord, texRepeat, weights)
//	SampleSpecular(texCoord, texRepeat, weights)
//	SampleNormal(texCoord, texRepeat, weights)
 
// =============================================================================================
//	Textures & Samplers
// =============================================================================================
 
#if MATERIAL_COUNT > 0
 
texture Diffuse0;
sampler Diffuse0Sampler = sampler_state
{
	Texture = <Diffuse0>;
	#ifdef DIFFUSE_ADDRESS_U
		AddressU = DIFFUSE_ADDRESS_U;
	#endif
	#ifdef DIFFUSE_ADDRESS_V
		AddressV = DIFFUSE_ADDRESS_V;
	#endif
	#ifdef DIFFUSE_ADDRESS_W
		AddressW = DIFFUSE_ADDRESS_W;
	#endif
	#ifdef DIFFUSE_MIN_FILTER
		MinFilter = DIFFUSE_MIN_FILTER;
	#endif
	#ifdef DIFFUSE_MAG_FILTER
		MagFilter = DIFFUSE_MAG_FILTER;
	#endif
	#ifdef DIFFUSE_MIP_FILTER
		MipFilter = DIFFUSE_MIP_FILTER;
	#endif
	#ifdef DIFFUSE_MAX_ANISOTROPY
		MaxAnisotropy = DIFFUSE_MAX_ANISOTROPY;
	#endif
	#ifdef DIFFUSE_MAX_MIP_LEVEL
		MaxMipLevel = DIFFUSE_MAX_MIP_LEVEL;
	#endif
	#ifdef DIFFUSE_MIP_MAP_LOD_BIAS
		MipMapLodBias = DIFFUSE_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef DIFFUSE_BORDER_COLOR
		BorderColor = DIFFUSE_BORDER_COLOR;
	#endif
	#ifdef DIFFUSE_SRGB_TEXTURE
		SRGBTexture = DIFFUSE_SRGB_TEXTURE;
	#endif
};
texture Normal0;
sampler Normal0Sampler = sampler_state
{
	Texture = <Normal0>;
	#ifdef NORMAL_ADDRESS_U
		AddressU = NORMAL_ADDRESS_U;
	#endif
	#ifdef NORMAL_ADDRESS_V
		AddressV = NORMAL_ADDRESS_V;
	#endif
	#ifdef NORMAL_ADDRESS_W
		AddressW = NORMAL_ADDRESS_W;
	#endif
	#ifdef NORMAL_MIN_FILTER
		MinFilter = NORMAL_MIN_FILTER;
	#endif
	#ifdef NORMAL_MAG_FILTER
		MagFilter = NORMAL_MAG_FILTER;
	#endif
	#ifdef NORMAL_MIP_FILTER
		MipFilter = NORMAL_MIP_FILTER;
	#endif
	#ifdef NORMAL_MAX_ANISOTROPY
		MaxAnisotropy = NORMAL_MAX_ANISOTROPY;
	#endif
	#ifdef NORMAL_MAX_MIP_LEVEL
		MaxMipLevel = NORMAL_MAX_MIP_LEVEL;
	#endif
	#ifdef NORMAL_MIP_MAP_LOD_BIAS
		MipMapLodBias = NORMAL_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef NORMAL_BORDER_COLOR
		BorderColor = NORMAL_BORDER_COLOR;
	#endif
	#ifdef NORMAL_SRGB_TEXTURE
		SRGBTexture = NORMAL_SRGB_TEXTURE;
	#endif
};
texture Specular0;
sampler Specular0Sampler = sampler_state
{
	Texture = <Specular0>;
	#ifdef SPECULAR_ADDRESS_U
		AddressU = SPECULAR_ADDRESS_U;
	#endif
	#ifdef SPECULAR_ADDRESS_V
		AddressV = SPECULAR_ADDRESS_V;
	#endif
	#ifdef SPECULAR_ADDRESS_W
		AddressW = SPECULAR_ADDRESS_W;
	#endif
	#ifdef SPECULAR_MIN_FILTER
		MinFilter = SPECULAR_MIN_FILTER;
	#endif
	#ifdef SPECULAR_MAG_FILTER
		MagFilter = SPECULAR_MAG_FILTER;
	#endif
	#ifdef SPECULAR_MIP_FILTER
		MipFilter = SPECULAR_MIP_FILTER;
	#endif
	#ifdef SPECULAR_MAX_ANISOTROPY
		MaxAnisotropy = SPECULAR_MAX_ANISOTROPY;
	#endif
	#ifdef SPECULAR_MAX_MIP_LEVEL
		MaxMipLevel = SPECULAR_MAX_MIP_LEVEL;
	#endif
	#ifdef SPECULAR_MIP_MAP_LOD_BIAS
		MipMapLodBias = SPECULAR_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef SPECULAR_BORDER_COLOR
		BorderColor = SPECULAR_BORDER_COLOR;
	#endif
	#ifdef SPECULAR_SRGB_TEXTURE
		SRGBTexture = SPECULAR_SRGB_TEXTURE;
	#endif
};
 
#endif
 
#if MATERIAL_COUNT > 1
 
texture Diffuse1;
sampler Diffuse1Sampler = sampler_state
{
	Texture = <Diffuse1>;
	#ifdef DIFFUSE_ADDRESS_U
		AddressU = DIFFUSE_ADDRESS_U;
	#endif
	#ifdef DIFFUSE_ADDRESS_V
		AddressV = DIFFUSE_ADDRESS_V;
	#endif
	#ifdef DIFFUSE_ADDRESS_W
		AddressW = DIFFUSE_ADDRESS_W;
	#endif
	#ifdef DIFFUSE_MIN_FILTER
		MinFilter = DIFFUSE_MIN_FILTER;
	#endif
	#ifdef DIFFUSE_MAG_FILTER
		MagFilter = DIFFUSE_MAG_FILTER;
	#endif
	#ifdef DIFFUSE_MIP_FILTER
		MipFilter = DIFFUSE_MIP_FILTER;
	#endif
	#ifdef DIFFUSE_MAX_ANISOTROPY
		MaxAnisotropy = DIFFUSE_MAX_ANISOTROPY;
	#endif
	#ifdef DIFFUSE_MAX_MIP_LEVEL
		MaxMipLevel = DIFFUSE_MAX_MIP_LEVEL;
	#endif
	#ifdef DIFFUSE_MIP_MAP_LOD_BIAS
		MipMapLodBias = DIFFUSE_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef DIFFUSE_BORDER_COLOR
		BorderColor = DIFFUSE_BORDER_COLOR;
	#endif
	#ifdef DIFFUSE_SRGB_TEXTURE
		SRGBTexture = DIFFUSE_SRGB_TEXTURE;
	#endif
};
texture Normal1;
sampler Normal1Sampler = sampler_state
{
	Texture = <Normal1>;
	#ifdef NORMAL_ADDRESS_U
		AddressU = NORMAL_ADDRESS_U;
	#endif
	#ifdef NORMAL_ADDRESS_V
		AddressV = NORMAL_ADDRESS_V;
	#endif
	#ifdef NORMAL_ADDRESS_W
		AddressW = NORMAL_ADDRESS_W;
	#endif
	#ifdef NORMAL_MIN_FILTER
		MinFilter = NORMAL_MIN_FILTER;
	#endif
	#ifdef NORMAL_MAG_FILTER
		MagFilter = NORMAL_MAG_FILTER;
	#endif
	#ifdef NORMAL_MIP_FILTER
		MipFilter = NORMAL_MIP_FILTER;
	#endif
	#ifdef NORMAL_MAX_ANISOTROPY
		MaxAnisotropy = NORMAL_MAX_ANISOTROPY;
	#endif
	#ifdef NORMAL_MAX_MIP_LEVEL
		MaxMipLevel = NORMAL_MAX_MIP_LEVEL;
	#endif
	#ifdef NORMAL_MIP_MAP_LOD_BIAS
		MipMapLodBias = NORMAL_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef NORMAL_BORDER_COLOR
		BorderColor = NORMAL_BORDER_COLOR;
	#endif
	#ifdef NORMAL_SRGB_TEXTURE
		SRGBTexture = NORMAL_SRGB_TEXTURE;
	#endif
};
texture Specular1;
sampler Specular1Sampler = sampler_state
{
	Texture = <Specular1>;
	#ifdef SPECULAR_ADDRESS_U
		AddressU = SPECULAR_ADDRESS_U;
	#endif
	#ifdef SPECULAR_ADDRESS_V
		AddressV = SPECULAR_ADDRESS_V;
	#endif
	#ifdef SPECULAR_ADDRESS_W
		AddressW = SPECULAR_ADDRESS_W;
	#endif
	#ifdef SPECULAR_MIN_FILTER
		MinFilter = SPECULAR_MIN_FILTER;
	#endif
	#ifdef SPECULAR_MAG_FILTER
		MagFilter = SPECULAR_MAG_FILTER;
	#endif
	#ifdef SPECULAR_MIP_FILTER
		MipFilter = SPECULAR_MIP_FILTER;
	#endif
	#ifdef SPECULAR_MAX_ANISOTROPY
		MaxAnisotropy = SPECULAR_MAX_ANISOTROPY;
	#endif
	#ifdef SPECULAR_MAX_MIP_LEVEL
		MaxMipLevel = SPECULAR_MAX_MIP_LEVEL;
	#endif
	#ifdef SPECULAR_MIP_MAP_LOD_BIAS
		MipMapLodBias = SPECULAR_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef SPECULAR_BORDER_COLOR
		BorderColor = SPECULAR_BORDER_COLOR;
	#endif
	#ifdef SPECULAR_SRGB_TEXTURE
		SRGBTexture = SPECULAR_SRGB_TEXTURE;
	#endif
};
 
#endif
 
#if MATERIAL_COUNT > 2
 
texture Diffuse2;
sampler Diffuse2Sampler = sampler_state
{
	Texture = <Diffuse2>;
	#ifdef DIFFUSE_ADDRESS_U
		AddressU = DIFFUSE_ADDRESS_U;
	#endif
	#ifdef DIFFUSE_ADDRESS_V
		AddressV = DIFFUSE_ADDRESS_V;
	#endif
	#ifdef DIFFUSE_ADDRESS_W
		AddressW = DIFFUSE_ADDRESS_W;
	#endif
	#ifdef DIFFUSE_MIN_FILTER
		MinFilter = DIFFUSE_MIN_FILTER;
	#endif
	#ifdef DIFFUSE_MAG_FILTER
		MagFilter = DIFFUSE_MAG_FILTER;
	#endif
	#ifdef DIFFUSE_MIP_FILTER
		MipFilter = DIFFUSE_MIP_FILTER;
	#endif
	#ifdef DIFFUSE_MAX_ANISOTROPY
		MaxAnisotropy = DIFFUSE_MAX_ANISOTROPY;
	#endif
	#ifdef DIFFUSE_MAX_MIP_LEVEL
		MaxMipLevel = DIFFUSE_MAX_MIP_LEVEL;
	#endif
	#ifdef DIFFUSE_MIP_MAP_LOD_BIAS
		MipMapLodBias = DIFFUSE_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef DIFFUSE_BORDER_COLOR
		BorderColor = DIFFUSE_BORDER_COLOR;
	#endif
	#ifdef DIFFUSE_SRGB_TEXTURE
		SRGBTexture = DIFFUSE_SRGB_TEXTURE;
	#endif
};
texture Normal2;
sampler Normal2Sampler = sampler_state
{
	Texture = <Normal2>;
	#ifdef NORMAL_ADDRESS_U
		AddressU = NORMAL_ADDRESS_U;
	#endif
	#ifdef NORMAL_ADDRESS_V
		AddressV = NORMAL_ADDRESS_V;
	#endif
	#ifdef NORMAL_ADDRESS_W
		AddressW = NORMAL_ADDRESS_W;
	#endif
	#ifdef NORMAL_MIN_FILTER
		MinFilter = NORMAL_MIN_FILTER;
	#endif
	#ifdef NORMAL_MAG_FILTER
		MagFilter = NORMAL_MAG_FILTER;
	#endif
	#ifdef NORMAL_MIP_FILTER
		MipFilter = NORMAL_MIP_FILTER;
	#endif
	#ifdef NORMAL_MAX_ANISOTROPY
		MaxAnisotropy = NORMAL_MAX_ANISOTROPY;
	#endif
	#ifdef NORMAL_MAX_MIP_LEVEL
		MaxMipLevel = NORMAL_MAX_MIP_LEVEL;
	#endif
	#ifdef NORMAL_MIP_MAP_LOD_BIAS
		MipMapLodBias = NORMAL_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef NORMAL_BORDER_COLOR
		BorderColor = NORMAL_BORDER_COLOR;
	#endif
	#ifdef NORMAL_SRGB_TEXTURE
		SRGBTexture = NORMAL_SRGB_TEXTURE;
	#endif
};
texture Specular2;
sampler Specular2Sampler = sampler_state
{
	Texture = <Specular2>;
	#ifdef SPECULAR_ADDRESS_U
		AddressU = SPECULAR_ADDRESS_U;
	#endif
	#ifdef SPECULAR_ADDRESS_V
		AddressV = SPECULAR_ADDRESS_V;
	#endif
	#ifdef SPECULAR_ADDRESS_W
		AddressW = SPECULAR_ADDRESS_W;
	#endif
	#ifdef SPECULAR_MIN_FILTER
		MinFilter = SPECULAR_MIN_FILTER;
	#endif
	#ifdef SPECULAR_MAG_FILTER
		MagFilter = SPECULAR_MAG_FILTER;
	#endif
	#ifdef SPECULAR_MIP_FILTER
		MipFilter = SPECULAR_MIP_FILTER;
	#endif
	#ifdef SPECULAR_MAX_ANISOTROPY
		MaxAnisotropy = SPECULAR_MAX_ANISOTROPY;
	#endif
	#ifdef SPECULAR_MAX_MIP_LEVEL
		MaxMipLevel = SPECULAR_MAX_MIP_LEVEL;
	#endif
	#ifdef SPECULAR_MIP_MAP_LOD_BIAS
		MipMapLodBias = SPECULAR_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef SPECULAR_BORDER_COLOR
		BorderColor = SPECULAR_BORDER_COLOR;
	#endif
	#ifdef SPECULAR_SRGB_TEXTURE
		SRGBTexture = SPECULAR_SRGB_TEXTURE;
	#endif
};
 
#endif
 
#if MATERIAL_COUNT > 3
 
texture Diffuse3;
sampler Diffuse3Sampler = sampler_state
{
	Texture = <Diffuse3>;
	#ifdef DIFFUSE_ADDRESS_U
		AddressU = DIFFUSE_ADDRESS_U;
	#endif
	#ifdef DIFFUSE_ADDRESS_V
		AddressV = DIFFUSE_ADDRESS_V;
	#endif
	#ifdef DIFFUSE_ADDRESS_W
		AddressW = DIFFUSE_ADDRESS_W;
	#endif
	#ifdef DIFFUSE_MIN_FILTER
		MinFilter = DIFFUSE_MIN_FILTER;
	#endif
	#ifdef DIFFUSE_MAG_FILTER
		MagFilter = DIFFUSE_MAG_FILTER;
	#endif
	#ifdef DIFFUSE_MIP_FILTER
		MipFilter = DIFFUSE_MIP_FILTER;
	#endif
	#ifdef DIFFUSE_MAX_ANISOTROPY
		MaxAnisotropy = DIFFUSE_MAX_ANISOTROPY;
	#endif
	#ifdef DIFFUSE_MAX_MIP_LEVEL
		MaxMipLevel = DIFFUSE_MAX_MIP_LEVEL;
	#endif
	#ifdef DIFFUSE_MIP_MAP_LOD_BIAS
		MipMapLodBias = DIFFUSE_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef DIFFUSE_BORDER_COLOR
		BorderColor = DIFFUSE_BORDER_COLOR;
	#endif
	#ifdef DIFFUSE_SRGB_TEXTURE
		SRGBTexture = DIFFUSE_SRGB_TEXTURE;
	#endif
};
texture Normal3;
sampler Normal3Sampler = sampler_state
{
	Texture = <Normal3>;
	#ifdef NORMAL_ADDRESS_U
		AddressU = NORMAL_ADDRESS_U;
	#endif
	#ifdef NORMAL_ADDRESS_V
		AddressV = NORMAL_ADDRESS_V;
	#endif
	#ifdef NORMAL_ADDRESS_W
		AddressW = NORMAL_ADDRESS_W;
	#endif
	#ifdef NORMAL_MIN_FILTER
		MinFilter = NORMAL_MIN_FILTER;
	#endif
	#ifdef NORMAL_MAG_FILTER
		MagFilter = NORMAL_MAG_FILTER;
	#endif
	#ifdef NORMAL_MIP_FILTER
		MipFilter = NORMAL_MIP_FILTER;
	#endif
	#ifdef NORMAL_MAX_ANISOTROPY
		MaxAnisotropy = NORMAL_MAX_ANISOTROPY;
	#endif
	#ifdef NORMAL_MAX_MIP_LEVEL
		MaxMipLevel = NORMAL_MAX_MIP_LEVEL;
	#endif
	#ifdef NORMAL_MIP_MAP_LOD_BIAS
		MipMapLodBias = NORMAL_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef NORMAL_BORDER_COLOR
		BorderColor = NORMAL_BORDER_COLOR;
	#endif
	#ifdef NORMAL_SRGB_TEXTURE
		SRGBTexture = NORMAL_SRGB_TEXTURE;
	#endif
};
texture Specular3;
sampler Specular3Sampler = sampler_state
{
	Texture = <Specular3>;
	#ifdef SPECULAR_ADDRESS_U
		AddressU = SPECULAR_ADDRESS_U;
	#endif
	#ifdef SPECULAR_ADDRESS_V
		AddressV = SPECULAR_ADDRESS_V;
	#endif
	#ifdef SPECULAR_ADDRESS_W
		AddressW = SPECULAR_ADDRESS_W;
	#endif
	#ifdef SPECULAR_MIN_FILTER
		MinFilter = SPECULAR_MIN_FILTER;
	#endif
	#ifdef SPECULAR_MAG_FILTER
		MagFilter = SPECULAR_MAG_FILTER;
	#endif
	#ifdef SPECULAR_MIP_FILTER
		MipFilter = SPECULAR_MIP_FILTER;
	#endif
	#ifdef SPECULAR_MAX_ANISOTROPY
		MaxAnisotropy = SPECULAR_MAX_ANISOTROPY;
	#endif
	#ifdef SPECULAR_MAX_MIP_LEVEL
		MaxMipLevel = SPECULAR_MAX_MIP_LEVEL;
	#endif
	#ifdef SPECULAR_MIP_MAP_LOD_BIAS
		MipMapLodBias = SPECULAR_MIP_MAP_LOD_BIAS;
	#endif
	#ifdef SPECULAR_BORDER_COLOR
		BorderColor = SPECULAR_BORDER_COLOR;
	#endif
	#ifdef SPECULAR_SRGB_TEXTURE
		SRGBTexture = SPECULAR_SRGB_TEXTURE;
	#endif
};
 
#endif
 
#if MATERIAL_COUNT == 1
 
#define SampleDiffuse(texCoord, texRepeat, weights) \
( \
  tex2D(Diffuse0Sampler, ####texCoord * ##texRepeat) * ##weights.r \
)
 
#define SampleSpecular(texCoord, texRepeat, weights) \
( \
  tex2D(Specular0Sampler, ####texCoord * ##texRepeat) * ##weights.r \
)
 
#ifdef DecodeNormal
#define SampleNormal(texCoord, texRepeat, weights) \
( \
  (DecodeNormal(Normal0Sampler, ##texCoord * ##texRepeat)) * ##weights.r \
)
#else
#define SampleNormal(texCoord, texRepeat, weights) \
( \
  (2 * tex2D(Normal0Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.r \
)
#endif
 
#endif
 
#if MATERIAL_COUNT == 2
 
#define SampleDiffuse(texCoord, texRepeat, weights) \
( \
  tex2D(Diffuse0Sampler, ##texCoord * ##texRepeat) * ##weights.r \
+ tex2D(Diffuse1Sampler, ##texCoord * ##texRepeat) * ##weights.g \
)
 
#define SampleSpecular(texCoord, texRepeat, weights) \
( \
  tex2D(Specular0Sampler, ##texCoord * ##texRepeat) * ##weights.r \
+ tex2D(Specular1Sampler, ##texCoord * ##texRepeat) * ##weights.g \
)
 
#ifdef DecodeNormal
#define SampleNormal(texCoord, texRepeat, weights) \
( \
  (DecodeNormal(Normal0Sampler, ##texCoord * ##texRepeat)) * ##weights.r \
+ (DecodeNormal(Normal1Sampler, ##texCoord * ##texRepeat)) * ##weights.g \
)
#else
#define SampleNormal(texCoord, texRepeat, weights) \
( \
  (2 * tex2D(Normal0Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.r \
+ (2 * tex2D(Normal1Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.g \
)
#endif
 
#endif
 
#if MATERIAL_COUNT == 3
 
#define SampleDiffuse(texCoord, texRepeat, weights) \
( \
  tex2D(Diffuse0Sampler, ##texCoord * ##texRepeat) * ##weights.r \
+ tex2D(Diffuse1Sampler, ##texCoord * ##texRepeat) * ##weights.g \
+ tex2D(Diffuse2Sampler, ##texCoord * ##texRepeat) * ##weights.b \
)
 
#define SampleSpecular(texCoord, texRepeat, weights) \
( \
  tex2D(Specular0Sampler, ##texCoord * ##texRepeat) * ##weights.r \
+ tex2D(Specular1Sampler, ##texCoord * ##texRepeat) * ##weights.g \
+ tex2D(Specular2Sampler, ##texCoord * ##texRepeat) * ##weights.b \
)
 
#ifdef DecodeNormal
#define SampleNormal(texCoord, texRepeat, weights) \
( \
  (DecodeNormal(Normal0Sampler, ##texCoord * ##texRepeat)) * ##weights.r \
+ (DecodeNormal(Normal1Sampler, ##texCoord * ##texRepeat)) * ##weights.g \
+ (DecodeNormal(Normal2Sampler, ##texCoord * ##texRepeat)) * ##weights.b \
)
#else
#define SampleNormal(texCoord, texRepeat, weights) \
( \
  (2 * tex2D(Normal0Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.r \
+ (2 * tex2D(Normal1Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.g \
+ (2 * tex2D(Normal2Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.b \
)
#endif
 
#endif
 
#if MATERIAL_COUNT == 4
 
#define SampleDiffuse(texCoord, texRepeat, weights) \
( \
  tex2D(Diffuse0Sampler, ##texCoord * ##texRepeat) * ##weights.r \
+ tex2D(Diffuse1Sampler, ##texCoord * ##texRepeat) * ##weights.g \
+ tex2D(Diffuse2Sampler, ##texCoord * ##texRepeat) * ##weights.b \
+ tex2D(Diffuse3Sampler, ##texCoord * ##texRepeat) * ##weights.a \
)
 
#define SampleSpecular(texCoord, texRepeat, weights) \
( \
  tex2D(Specular0Sampler, ##texCoord * ##texRepeat) * ##weights.r \
+ tex2D(Specular1Sampler, ##texCoord * ##texRepeat) * ##weights.g \
+ tex2D(Specular2Sampler, ##texCoord * ##texRepeat) * ##weights.b \
+ tex2D(Specular3Sampler, ##texCoord * ##texRepeat) * ##weights.a \
)
 
#ifdef DecodeNormal
#define SampleNormal(texCoord, texRepeat, weights) \
( \
  (DecodeNormal(Normal0Sampler, ##texCoord * ##texRepeat)) * ##weights.r \
+ (DecodeNormal(Normal1Sampler, ##texCoord * ##texRepeat)) * ##weights.g \
+ (DecodeNormal(Normal2Sampler, ##texCoord * ##texRepeat)) * ##weights.b \
+ (DecodeNormal(Normal3Sampler, ##texCoord * ##texRepeat)) * ##weights.a \
)
#else
#define SampleNormal(texCoord, texRepeat, weights) \
( \
  (2 * tex2D(Normal0Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.r \
+ (2 * tex2D(Normal1Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.g \
+ (2 * tex2D(Normal2Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.b \
+ (2 * tex2D(Normal3Sampler, ##texCoord * ##texRepeat).rgb - 1) * ##weights.a \
)
#endif
 
#endif