(Sorry for my bad English.)
I'm new to Stack Overflow and writing a 3D game application with MS Visual C++ 2015 compiler, Direct3D 9 and HLSL(Shader model 3.0).
I've implemented a deferred rendering logic with 4 render target textures. I stored depth values of pixels in a render target texture and created a shadow map. Here are the results. (All meshes have black color because the meshes have small size and close to the camera. The far plane distance value is 1000.0f.)
The depth texture and the shadow map.
I rendered a full screen quad with shadow mapping shaders and outputted shadows with red color to confirm the shader is working correctly. But, It seems that the shaders output wrong results. The shadow map texture output repeats on the mesh surfaces.
https://www.youtube.com/watch?v=1URGgoCR6Zc
Here is the shadow mapping vertex shader to draw the quad.
struct VsInput {
float4 position : POSITION0;
};
struct VsOutput {
float4 position : POSITION0;
float4 cameraViewRay : TEXCOORD0;
};
float4x4 matInverseCameraViewProjection;
float4 cameraWorldPosition;
float farDistance;
VsOutput vs_main(VsInput input) {
VsOutput output = (VsOutput)0;
output.position = input.position;
output.cameraViewRay = mul(float4(input.position.xy, 1.0f, 1.0f) * farDistance, matInverseCameraViewProjection);
output.cameraViewRay /= output.cameraViewRay.w;
output.cameraViewRay.xyz -= cameraWorldPosition.xyz;
return output;
}
And here is the shadow mapping pixel shader to draw the quad.
struct PsInput {
float2 screenPosition : VPOS;
float4 viewRay : TEXCOORD0;
};
struct PsOutput {
float4 color : COLOR0;
};
texture depthMap;
texture shadowMap;
sampler depthMapSampler = sampler_state {
Texture = (depthMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
MipFilter = POINT;
};
sampler shadowMapSampler = sampler_state {
Texture = (shadowMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
MipFilter = POINT;
};
//float4x4 matCameraView;
float4x4 matLightView;
float4x4 matLightProjection;
float4 cameraWorldPosition;
float4 lightWorldPosition;
float2 halfPixel;
float epsilon;
float farDistance;
PsOutput ps_main(PsInput input) {
PsOutput output = (PsOutput)0;
output.color.a = 1.0f;
//Reconstruct the world position using the view-space linear depth value.
float2 textureUv = input.screenPosition * halfPixel * 2.0f - halfPixel;
float viewDepth = tex2D(depthMapSampler, textureUv).r;
float3 eye = input.viewRay.xyz * viewDepth;
float4 worldPosition = float4((eye + cameraWorldPosition.xyz), 1.0f);
//Test if the reconstructed world position has right coordinate values.
//output.color = mul(worldPosition, matCameraView).z / farDistance;
float4 positionInLightView = mul(worldPosition, matLightView);
float lightDepth = positionInLightView.z / farDistance;
float4 positionInLightProjection = mul(positionInLightView, matLightProjection);
positionInLightProjection /= positionInLightProjection.w;
//If-statement doesn't work???
float condition = positionInLightProjection.x >= -1.0f;
condition *= positionInLightProjection.x <= 1.0f;
condition *= positionInLightProjection.y >= -1.0f;
condition *= positionInLightProjection.y <= 1.0f;
condition *= positionInLightProjection.z >= 0.0f;
condition *= positionInLightProjection.z <= 1.0f;
condition *= positionInLightProjection.w > 0.0f;
float2 shadowMapUv = float2(
positionInLightProjection.x * 0.5f + 0.5f,
-positionInLightProjection.y * 0.5f + 0.5f
);
//If-statement doesn't work???
float condition2 = shadowMapUv.x >= 0.0f;
condition2 *= shadowMapUv.x <= 1.0f;
condition2 *= shadowMapUv.y >= 0.0f;
condition2 *= shadowMapUv.y <= 1.0f;
float viewDepthInShadowMap = tex2D(
shadowMapSampler,
shadowMapUv
).r;
output.color.r = lightDepth > viewDepthInShadowMap + epsilon;
output.color.r *= condition;
output.color.r *= condition2;
return output;
}
It seems that the uv for the shadow map has some wrong values, but i can't figure out what's the real problem.
Many thanks for any help.
EDIT : I've updated the shader codes. I decided to use view-space linear depth and confirmed that the world position has right value. I really don't understand why the shadow map coordinate values have wrong values...