Alenet
Newcomer
Hello,
i have a problem on shadows. I am implementing the shadows in Oblivion.
I rendered the shadowmap from directional light (orthomap from the sun view). Here the raw depth map:
Now i am trying to render the shadows on the terrain, so i implemented the terrain shader passing the shadow map. But the shadow lookup is not correct, (see below), the shadows move with the camera and they are repeated for each terrain quad. I think something is wrong with the matrixes but i dont understand what.....
Vertex:
row_major float4x4 ModelViewProj : register(c0);
float3 LightDirection[3] : register(c13);
row_major float4x4 WorldTransform : register(c34);
row_major float4x4 LightViewProjTransform : register(c38);
OUT.position.xyzw = mul(ModelViewProj, IN.position.xyzw);
OUT.texcoord_0.xy = IN.texcoord_0.xy;
OUT.texcoord_1.xy = IN.texcoord_0.xy;
OUT.texcoord_2.xyzw = (IN.color_0.xyzx * const_4.yyyz) + const_4.zzzy;
OUT.texcoord_3.xyz = compress(mul(TanSpaceProj, LightDirection[0].xyz));
OUT.texcoord_4.xyzw = mul(IN.position.xyzw, mul(WorldTransform, LightViewProjTransform));
Pixel:
float4 AmbientColor : register(c1);
float4 PSLightColor[4] : register(c2);
float4 TerrainData : register(c6);
sampler2D BaseMap : register(s0);
sampler2D NormalMap : register(s1);
sampler2D ShadowMapBuffer : register(s4) = sampler_state { };
float GetLightAmount(float4 vPosLight) {
vPosLight.xyz /= vPosLight.w;
//if position is not visible to the light - dont illuminate it
//results in hard light frustum
if( vPosLight.x < -1.0f || vPosLight.x > 1.0f ||
vPosLight.y < -1.0f || vPosLight.y > 1.0f ||
vPosLight.z < 0.0f || vPosLight.z > 1.0f ) return 1;
//transform clip space coords to texture space coords (-1:1 to 0:1)
vPosLight.x = vPosLight.x/2 + 0.5;
vPosLight.y = vPosLight.y/-2 + 0.5;
//sample shadow map - point sampler
float shadowMapDepth = tex2D(ShadowMapBuffer, vPosLight.xy).r;
//if clip space z value greater than shadow map value then pixel is in shadow
if ( shadowMapDepth < vPosLight.z) return 0.5;
return 1;
}
r0.xyz = tex2D(NormalMap, IN.NormalUV.xy).xyz;
r3.xyz = tex2D(BaseMap, IN.BaseUV.xy).xyz;
r0.x = shades((IN.texcoord_3.xyz * 2) - 1, normalize(expand(r0.xyz)));
r0.xyz = r3.xyz * ((GetLightAmount(IN.texcoord_4) * (r0.x * PSLightColor[0].rgb)) + AmbientColor.rgb);
spclr = smoothstep(0.0, 0.25, length(r3.rgb)) * (r3.b * 2.0 * TerrainData.z) + 1.0;
OUT.color_0.a = 1;
OUT.color_0.rgb = r0.xyz * IN.texcoord_2.xyz * spclr;
The problem is the lookup in the GetLightAmount, that gives an incorrect result, but the function is ok. It seems the vPosLight (texcoord_4) that is wrong?!
I should get the shadow map at the model position but looking from the camera view, while the depth shadow map is rendered from the sun view, so OUT.texcoord_4.xyzw = mul(IN.position.xyzw, mul(TESR_WorldTransform, TESR_LightViewProjTransform)); is correct? or i need an other way to get the shadowpos?
Any ideas?
i have a problem on shadows. I am implementing the shadows in Oblivion.
I rendered the shadowmap from directional light (orthomap from the sun view). Here the raw depth map:
Now i am trying to render the shadows on the terrain, so i implemented the terrain shader passing the shadow map. But the shadow lookup is not correct, (see below), the shadows move with the camera and they are repeated for each terrain quad. I think something is wrong with the matrixes but i dont understand what.....
Vertex:
row_major float4x4 ModelViewProj : register(c0);
float3 LightDirection[3] : register(c13);
row_major float4x4 WorldTransform : register(c34);
row_major float4x4 LightViewProjTransform : register(c38);
OUT.position.xyzw = mul(ModelViewProj, IN.position.xyzw);
OUT.texcoord_0.xy = IN.texcoord_0.xy;
OUT.texcoord_1.xy = IN.texcoord_0.xy;
OUT.texcoord_2.xyzw = (IN.color_0.xyzx * const_4.yyyz) + const_4.zzzy;
OUT.texcoord_3.xyz = compress(mul(TanSpaceProj, LightDirection[0].xyz));
OUT.texcoord_4.xyzw = mul(IN.position.xyzw, mul(WorldTransform, LightViewProjTransform));
Pixel:
float4 AmbientColor : register(c1);
float4 PSLightColor[4] : register(c2);
float4 TerrainData : register(c6);
sampler2D BaseMap : register(s0);
sampler2D NormalMap : register(s1);
sampler2D ShadowMapBuffer : register(s4) = sampler_state { };
float GetLightAmount(float4 vPosLight) {
vPosLight.xyz /= vPosLight.w;
//if position is not visible to the light - dont illuminate it
//results in hard light frustum
if( vPosLight.x < -1.0f || vPosLight.x > 1.0f ||
vPosLight.y < -1.0f || vPosLight.y > 1.0f ||
vPosLight.z < 0.0f || vPosLight.z > 1.0f ) return 1;
//transform clip space coords to texture space coords (-1:1 to 0:1)
vPosLight.x = vPosLight.x/2 + 0.5;
vPosLight.y = vPosLight.y/-2 + 0.5;
//sample shadow map - point sampler
float shadowMapDepth = tex2D(ShadowMapBuffer, vPosLight.xy).r;
//if clip space z value greater than shadow map value then pixel is in shadow
if ( shadowMapDepth < vPosLight.z) return 0.5;
return 1;
}
r0.xyz = tex2D(NormalMap, IN.NormalUV.xy).xyz;
r3.xyz = tex2D(BaseMap, IN.BaseUV.xy).xyz;
r0.x = shades((IN.texcoord_3.xyz * 2) - 1, normalize(expand(r0.xyz)));
r0.xyz = r3.xyz * ((GetLightAmount(IN.texcoord_4) * (r0.x * PSLightColor[0].rgb)) + AmbientColor.rgb);
spclr = smoothstep(0.0, 0.25, length(r3.rgb)) * (r3.b * 2.0 * TerrainData.z) + 1.0;
OUT.color_0.a = 1;
OUT.color_0.rgb = r0.xyz * IN.texcoord_2.xyz * spclr;
The problem is the lookup in the GetLightAmount, that gives an incorrect result, but the function is ok. It seems the vPosLight (texcoord_4) that is wrong?!
I should get the shadow map at the model position but looking from the camera view, while the depth shadow map is rendered from the sun view, so OUT.texcoord_4.xyzw = mul(IN.position.xyzw, mul(TESR_WorldTransform, TESR_LightViewProjTransform)); is correct? or i need an other way to get the shadowpos?
Any ideas?