Texture2D DepthMapTextures[3]; SamplerState DepthMapSampler; cbuffer LightConstBuffer { float3 lightDirection; }; cbuffer DepthTestBuffer { float3 depthBounds; }; struct VS_to_PS { float4 position : SV_POSITION; float2 texCoord0 : TEXCOORD0; float3 normal : NORMAL; float4 lightPosition1 : TEXCOORD1; float4 lightPosition2 : TEXCOORD2; float4 lightPosition3 : TEXCOORD3; }; float SampleDepthMap(Texture2D texArr[3], int index, float2 coord) { if(index == 0) { return texArr[0].Sample(DepthMapSampler, float2(coord.x, coord.y)).r; } else if(index == 1) { return texArr[1].Sample(DepthMapSampler, coord).r; } return texArr[2].Sample(DepthMapSampler, coord).r; } float4 ShadowPixelShader(VS_to_PS input) : SV_TARGET { float3 lightDir = -lightDirection; float4 color = float4(0.3, 0.3, 0.3, 1.0); //you can use whatever color you want for shadows float shadowBias = 0.0005; float lightIntensity; float inputPositionInv = 1.0 / input.position.w; float lightPositionInv1 = 1.0 / input.lightPosition1.w; float lightPositionInv2 = 1.0 / input.lightPosition2.w; float lightPositionInv3 = 1.0 / input.lightPosition3.w; float depthTest = input.position.z * inputPositionInv; float2 shadowCoords[3] = { float2( input.lightPosition1.x * lightPositionInv1 * 0.5 + 0.5, -input.lightPosition1.y * lightPositionInv1 * 0.5 + 0.5), float2( input.lightPosition2.x * lightPositionInv2 * 0.5 + 0.5, -input.lightPosition2.y * lightPositionInv2 * 0.5 + 0.5), float2( input.lightPosition3.x * lightPositionInv3 * 0.5 + 0.5, -input.lightPosition3.y * lightPositionInv3 * 0.5 + 0.5) }; float lightDepthValues[3]; lightDepthValues[0] = input.lightPosition1.z * lightPositionInv1; lightDepthValues[1] = input.lightPosition2.z * lightPositionInv2; lightDepthValues[2] = input.lightPosition3.z * lightPositionInv3; int shadowIndex = 3; if((saturate(shadowCoords[0].x) == shadowCoords[0].x) && (saturate(shadowCoords[0].y) == shadowCoords[0].y) && (depthTest > (1.0f - (depthBounds.x * inputPositionInv)))) { shadowIndex = 0; } else if((saturate(shadowCoords[1].x) == shadowCoords[1].x) && (saturate(shadowCoords[1].y) == shadowCoords[1].y) && (depthTest > (1.0f - (depthBounds.y * inputPositionInv)))) { shadowIndex = 1; } else if((saturate(shadowCoords[2].x) == shadowCoords[2].x) && (saturate(shadowCoords[2].y) == shadowCoords[2].y) && (depthTest > (1.0f - (depthBounds.z * inputPositionInv)))) { shadowIndex = 2; } if( shadowIndex != 3 ) //we are in a shadow map { float depthVal = SampleDepthMap(DepthMapTextures, shadowIndex, shadowCoords[shadowIndex]); if((lightDepthValues[shadowIndex]-shadowBias) < depthVal) { lightIntensity = saturate(dot(input.normal, lightDir)); if(lightIntensity > 0.0f) { color = float4(1.0, 1.0, 1.0, 1.0); } } } else { lightIntensity = saturate(dot(input.normal, lightDir)); if(lightIntensity > 0.0f) { color = float4(1.0, 1.0, 1.0, 1.0); //not in any shadow map, but is facing the light, so we light it. } } return color; }