11 void ComputePCFShadowIntensity(out
float OutShadowIntensity,Texture2D ShadowMap,SamplerState ShadowMapSampler,float2 ShadowMapTexCoord,
float FragmentDepth,float4 ShadowMapSize,
const float StandardDeviation,
const int KernelRadius,
float DepthBias){
12 float BiasedDepth=mad(FragmentDepth-DepthBias,0.5f,0.5f);
15 const int iFirstSample=-KernelRadius-1;
16 const int iLastSample=KernelRadius;
18 const float InvVariance=1.0f/(StandardDeviation*StandardDeviation);
19 ShadowMapTexCoord+=ShadowMapSize.zw*0.5f;
20 float2 TexelCoord=frac(ShadowMapTexCoord*ShadowMapSize.xy);
21 OutShadowIntensity=0.0f;
22 float TotalWeight=0.0f;
26 [unroll]
for(
int x=iFirstSample;x<=iLastSample;++x){
29 float HorizontalWeight=lerp((x==iLastSample)?0.0f:exp(-0.5f*(x+1)*(x+1)*InvVariance),(x==iFirstSample)?0.0f:exp(-0.5f*x*x*InvVariance),TexelCoord.x);
30 [unroll]
for(
int y=iFirstSample;y<=iLastSample;++y){
32 float2 OffsetTexCoord=ShadowMapTexCoord+ShadowMapSize.zw*float2(x,y);
33 float SampledShadowMapDepth=ShadowMap.Sample(ShadowMapSampler,OffsetTexCoord);
34 float Summand=(SampledShadowMapDepth<BiasedDepth)?1.0f:0.0f;
36 float VerticalWeight=lerp((y==iLastSample)?0.0f:exp(-0.5f*(y+1)*(y+1)*InvVariance),(y==iFirstSample)?0.0f:exp(-0.5f*y*y*InvVariance),TexelCoord.y);
37 float Weight=HorizontalWeight*VerticalWeight;
38 OutShadowIntensity+=Weight*Summand;
42 OutShadowIntensity/=TotalWeight;
48 void ComputePCFShadowIntensityBilinear(out
float OutShadowIntensity,Texture2D<float> ShadowMap,SamplerComparisonState ShadowMapSampler,float2 ShadowMapTexCoord,
float FragmentDepth,float4 ShadowMapSize,
const float StandardDeviation,
const int KernelRadius,
float DepthBias){
49 float BiasedDepth=mad(FragmentDepth-DepthBias,0.5f,0.5f);
53 const int iFirstSample=-KernelRadius-1;
54 const int iLastSample=KernelRadius;
58 const float InvVariance=1.0f/(StandardDeviation*StandardDeviation);
59 ShadowMapTexCoord+=ShadowMapSize.zw*0.5f;
60 float2 TexelCoord=frac(ShadowMapTexCoord*ShadowMapSize.xy);
61 ShadowMapTexCoord-=ShadowMapSize.zw*TexelCoord-ShadowMapSize.zw*0.5f;
62 OutShadowIntensity=0.0f;
63 float TotalWeight=0.0f;
66 [unroll]
for(
int x=iFirstSample;x<=iLastSample;x+=2){
69 float LeftWeight=lerp(exp(-0.5f*(LeftX+1)*(LeftX+1)*InvVariance),(LeftX==iFirstSample)?0.0f:exp(-0.5f*LeftX*LeftX*InvVariance),TexelCoord.x);
71 float RightWeight=lerp((RightX==iLastSample)?0.0f:exp(-0.5f*(RightX+1)*(RightX+1)*InvVariance),exp(-0.5f*RightX*RightX*InvVariance),TexelCoord.x);
74 float HorizontalWeight=LeftWeight+RightWeight;
75 float RelativeHorizontalWeight=RightWeight/HorizontalWeight;
76 [unroll]
for(
int y=iFirstSample;y<=iLastSample;y+=2){
79 float TopWeight=lerp(exp(-0.5f*(TopY+1)*(TopY+1)*InvVariance),(TopY==iFirstSample)?0.0f:exp(-0.5f*TopY*TopY*InvVariance),TexelCoord.y);
81 float BottomWeight=lerp((BottomY==iLastSample)?0.0f:exp(-0.5f*(BottomY+1)*(BottomY+1)*InvVariance),exp(-0.5f*BottomY*BottomY*InvVariance),TexelCoord.y);
82 float VerticalWeight=TopWeight+BottomWeight;
83 float RelativeVerticalWeight=BottomWeight/VerticalWeight;
86 float2 OffsetTexCoord=ShadowMapTexCoord+ShadowMapSize.zw*float2(x+RelativeHorizontalWeight,y+RelativeVerticalWeight);
87 float Summand=ShadowMap.SampleCmpLevelZero(ShadowMapSampler,OffsetTexCoord,BiasedDepth);
88 float Weight=HorizontalWeight*VerticalWeight;
89 OutShadowIntensity+=Weight*Summand;
93 OutShadowIntensity/=TotalWeight;
102 float Scaling=1.0f/Coefficients[2];
103 float p=Coefficients[1]*Scaling;
104 float q=Coefficients[0]*Scaling;
107 return float2(-0.5f*p-r,-0.5f*p+r);
114 float L21D11=mad(-Moments[0],Moments[1],Moments[2]);
115 float D11=mad(-Moments[0],Moments[0], Moments[1]);
116 float SquaredDepthVariance=mad(-Moments[1],Moments[1], Moments[3]);
117 return dot(float2(SquaredDepthVariance,-L21D11),float2(D11,L21D11));
125 float D11=mad(-Moments[0],Moments[0],Moments[1]);
126 float L21D11=mad(-Moments[0],Moments[1],Moments[2]);
127 float L21=L21D11/D11;
128 float SquaredDepthVariance=mad(-Moments[1],Moments[1],Moments[3]);
129 return mad(-L21D11,L21,SquaredDepthVariance);
float GetFourthMomentOffset(float4 Moments)
float GetHankelDeterminant(float4 Moments)
void ComputePCFShadowIntensity(out float OutShadowIntensity, Texture2D ShadowMap, SamplerState ShadowMapSampler, float2 ShadowMapTexCoord, float FragmentDepth, float4 ShadowMapSize, const float StandardDeviation, const int KernelRadius, float DepthBias)
void ComputePCFShadowIntensityBilinear(out float OutShadowIntensity, Texture2D< float > ShadowMap, SamplerComparisonState ShadowMapSampler, float2 ShadowMapTexCoord, float FragmentDepth, float4 ShadowMapSize, const float StandardDeviation, const int KernelRadius, float DepthBias)