I have a problem with my shader, it compiles and works and is pretty on pixel shader 3, but fails on 2!
This is the shader:
float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 LightView;
float4x4 LightProjection;
static const float SHADOW_EPSILON = 0.00005f;
static float SMAP_SIZE = 2048.0f;
void BuildShadowMapVS(float4 posL : POSITION,
out float4 posH : POSITION0,
out float2 depth : TEXCOORD0)
{
// Render from light's perspective.
float4x4 Transform;
Transform = mul(World, LightView);
Transform = mul(Transform, LightProjection);
posH = mul(posL, Transform);
// Propagate z- and w-coordinates.
depth = posH.zw;
}
float4 BuildShadowMapPS(float2 depth : TEXCOORD0) : COLOR
{
// Each pixel in the shadow map stores the pixel depth from the
// light source in normalized device coordinates.
return depth.x / depth.y; // z / w
}
technique BuildShadowMapTech
{
pass P0
{
vertexShader = compile vs_2_0 BuildShadowMapVS();
pixelShader = compile ps_2_0 BuildShadowMapPS();
}
}
struct Mtrl
{
float4 diffuse;
float4 ambient;
float4 spec;
float4 Emissive;
float specPower;
};
struct SpotLight
{
float4 ambient;
float4 diffuse;
float4 spec;
float3 posW;
float3 dirW;
float spotPower;
};
//uniform extern float4x4 gWVP;
Mtrl Material;
SpotLight gSpotLight;
float3 gEyePosW;
texture gTex0;
texture gShadowMap;
sampler Tex0S = sampler_state
{
Texture = <gTex0>;
MinFilter = Anisotropic;
MagFilter = LINEAR;
MipFilter = LINEAR;
MaxAnisotropy = 8;
AddressU = WRAP;
AddressV = WRAP;
};
sampler ShadowMapS = sampler_state
{
Texture = <gShadowMap>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = POINT;
AddressU = CLAMP;
AddressV = CLAMP;
};
void LightShadowVS(float4 posL : POSITION,
float3 normalL : NORMAL0,
float2 tex0 : TEXCOORD0,
out float4 oPosH : POSITION0,
out float3 oPosW : TEXCOORD0,
out float3 oNormalW : TEXCOORD1,
out float3 oToEyeW : TEXCOORD2,
out float2 oTex0 : TEXCOORD3,
out float4 oProjTex : TEXCOORD4)
{
// Transform to homogeneous clip space.
oPosH = mul(posL, mul(mul(World, View), Projection));
// Transform vertex position to world space.
oPosW = mul(posL, World).xyz;
// Transform normal to world space (assume no non-uniform scaling).
oNormalW = mul(float4(normalL, 0.0f), World).xyz;
// Compute the unit vector from the vertex to the eye.
oToEyeW = gEyePosW - oPosW;
// Pass on texture coords to PS
oTex0 = tex0;
// Generate projective texture coordinates.
oProjTex = mul(posL, mul(mul(World, LightView), LightProjection));
}
float4 LightShadowPS(float3 posW : TEXCOORD0,
float3 normalW : TEXCOORD1,
float3 toEyeW : TEXCOORD2,
float2 tex0 : TEXCOORD3,
float4 projTex : TEXCOORD4) : COLOR
{
// Interpolated normals can become unnormal--so normalize.
normalW = normalize(normalW);
toEyeW = normalize(toEyeW);
// Light vector is from pixel to spotlight position.
float3 lightVecW = normalize(gSpotLight.posW - posW);
// Compute the reflection vector.
float3 r = reflect(-lightVecW, normalW);
// Determine how much (if any) specular light makes it into the eye.
float t = pow(max(dot(r, toEyeW), 0.0f), Material.specPower);
// Determine the diffuse light intensity that strikes the vertex.
float s = max(dot(lightVecW, normalW), 0.0f);
// Compute the ambient, diffuse and specular terms separately.
float3 spec = t*(Material.spec*gSpotLight.spec).rgb;
float3 diffuse = s*(Material.diffuse*gSpotLight.diffuse.rgb);
float3 ambient = Material.ambient*gSpotLight.ambient;
// Compute spotlight coefficient.
float spot = pow(max( dot(-lightVecW, gSpotLight.dirW), 0.0f), gSpotLight.spotPower);
// Sample decal map.
float4 texColor = tex2D(Tex0S, tex0);
// Project the texture coords and scale/offset to [0, 1].
projTex.xy /= projTex.w;
projTex.x = 0.5f*projTex.x + 0.5f;
projTex.y = -0.5f*projTex.y + 0.5f;
// Compute pixel depth for shadowing.
float depth = projTex.z / projTex.w;
// Transform to texel space
float2 texelpos = SMAP_SIZE * projTex.xy;
// Determine the lerp amounts.
float2 lerps = frac( texelpos );
// 3x3 percentage closest filter.
float dx = 1.0f / SMAP_SIZE;
float2 vTexCoords[9];
// Sample each of them checking whether the pixel under test is shadowed or not
vTexCoords[0] = projTex;
vTexCoords[1] = projTex + float2( -dx, 0.0f );
vTexCoords[2] = projTex + float2( dx, 0.0f );
vTexCoords[3] = projTex + float2( 0.0f, dx );
vTexCoords[4] = projTex + float2( 0.0f, -dx );
vTexCoords[5] = projTex + float2( dx, dx );
vTexCoords[6] = projTex + float2( -dx, dx );
vTexCoords[7] = projTex + float2( dx, -dx );
vTexCoords[8] = projTex + float2( -dx, -dx);
float fShadowTerms[9];
float fShadowTerm = 0.0f;
int count = 0;
for( int i = 0; i < 9; i++ )
{
float A = tex2D(ShadowMapS , vTexCoords[i] ).r;
// Texel is shadowed
fShadowTerms[i] = (A + SHADOW_EPSILON < depth) ? 0.0f : 1.0f;
fShadowTerm += fShadowTerms[i];
}
// Get the average
fShadowTerm /= 9.0f;
// Light/Texture pixel. Note that shadow coefficient only affects diffuse/spec.
float3 litColor = spot*ambient*texColor.rgb + spot*fShadowTerm*(diffuse*texColor.rgb + spec);
return float4(litColor, Material.diffuse.a*texColor.a);
}
technique LightShadowTech
{
pass P0
{
// Specify the vertex and pixel shader associated with this pass.
vertexShader = compile vs_3_0 LightShadowVS();
pixelShader = compile ps_3_0 LightShadowPS();
}
}
Now, I know the problem is related to this bit:
float fShadowTerms[9];
float fShadowTerm = 0.0f;
int count = 0;
for( int i = 0; i < 9; i++ )
{
float A = tex2D(ShadowMapS , vTexCoords[i] ).r;
// Texel is shadowed
fShadowTerms[i] = (A + SHADOW_EPSILON < depth) ? 0.0f : 1.0f;
fShadowTerm += fShadowTerms[i];
}
// Get the average
fShadowTerm /= 9.0f;
On shader 2, it fails to compile of the loop goes beyond 5!
Hopefully someone can find what is wrong :)
thanks!











