#define NUM_SHADOW_SAMPLES_1D 2.0 #define SHADOW_FILTER_SCALE 1 #define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D SamplerState samplerstate { Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap; AddressW = Wrap; }; float4 offsetSample(float4 uv, float2 offset, float invMapSize) { return float4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w); } float calcDepthShadow(Texture2D shadowMap, float4 uv, float invShadowMapSize) { // 4-sample PCF float shadow = 0.0; float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE; for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE) for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE) { float4 tmpTexcoord = offsetSample(uv, float2(x, y), invShadowMapSize); float depth = shadowMap.Sample(samplerstate, tmpTexcoord.xy / tmpTexcoord.w).x; if (depth >= 1 || depth >= uv.z) shadow += 1.0; } shadow /= SHADOW_SAMPLES; return shadow; } float calcSimpleShadow(Texture2D shadowMap, float4 shadowMapPos) { return shadowMap.Sample(samplerstate, shadowMapPos.xy / shadowMapPos.w ).x; } float calcPSSMDepthShadow(Texture2D shadowMap0, Texture2D shadowMap1, Texture2D shadowMap2, float4 lsPos0, float4 lsPos1, float4 lsPos2, float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2, float4 pssmSplitPoints, float camDepth) { float shadow; float4 splitColour; // calculate shadow if (camDepth <= pssmSplitPoints.y) { splitColour = float4(0.3, 0.0, 0, 0); shadow = calcDepthShadow(shadowMap0, lsPos0, invShadowmapSize0); } else if (camDepth <= pssmSplitPoints.z) { splitColour = float4(0, 0.3, 0, 0); shadow = calcDepthShadow(shadowMap1, lsPos1, invShadowmapSize1); } else { splitColour = float4(0.0, 0.0, 0.3, 0); shadow = calcDepthShadow(shadowMap2, lsPos2, invShadowmapSize2); } return shadow; } float calcPSSMSimpleShadow(Texture2D shadowMap0, Texture2D shadowMap1, Texture2D shadowMap2, float4 lsPos0, float4 lsPos1, float4 lsPos2, float4 pssmSplitPoints, float camDepth) { float shadow; float4 splitColour; // calculate shadow if (camDepth <= pssmSplitPoints.y) { splitColour = float4(0.3, 0.0, 0, 0); shadow = calcSimpleShadow(shadowMap0, lsPos0); } else if (camDepth <= pssmSplitPoints.z) { splitColour = float4(0, 0.3, 0, 0); shadow = calcSimpleShadow(shadowMap1, lsPos1); } else { splitColour = float4(0.0, 0.0, 0.3, 0); shadow = calcSimpleShadow(shadowMap2, lsPos2); } return shadow; } float3 calcPSSMDebugShadow(Texture2D shadowMap0, Texture2D shadowMap1, Texture2D shadowMap2, float4 lsPos0, float4 lsPos1, float4 lsPos2, float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2, float4 pssmSplitPoints, float camDepth) { float4 splitColour; // calculate shadow if (camDepth <= pssmSplitPoints.y) { //splitColour = float4(0.3, 0.0, 0, 0); //splitColour = lsPos0 / lsPos0.w; splitColour.rgb = shadowMap0.Sample(samplerstate, lsPos0.xy / lsPos0.w).xxx; //splitColour = tex2Dproj(shadowMap0, lsPos0); } else if (camDepth <= pssmSplitPoints.z) { //splitColour = float4(0, 0.3, 0, 0); //splitColour = lsPos1 / lsPos1.w; splitColour.rgb = shadowMap1.Sample(samplerstate, lsPos1.xy / lsPos1.w).xxx; //splitColour = tex2Dproj(shadowMap1, lsPos1); } else { //splitColour = float4(0.0, 0.0, 0.3, 0); //splitColour = lsPos2 / lsPos2.w; splitColour.rgb = shadowMap2.Sample(samplerstate, lsPos2.xy / lsPos2.w).xxx; //splitColour = tex2Dproj(shadowMap2, lsPos2); } return splitColour.rgb; }