22 OutRectificationToWorldSpace=float4x4(
23 ShadowMapViewToWorldSpace._11, ShadowMapViewToWorldSpace._12, ShadowMapViewToWorldSpace._13, 0.0f,
24 -ShadowMapViewToWorldSpace._21,-ShadowMapViewToWorldSpace._22,-ShadowMapViewToWorldSpace._23, 0.0f,
25 -ShadowMapViewToWorldSpace._31,-ShadowMapViewToWorldSpace._32,-ShadowMapViewToWorldSpace._33, 0.0f,
26 WorldSpaceCameraPosition.x, WorldSpaceCameraPosition.y, WorldSpaceCameraPosition.z, 1.0f
50 void GetRectifiedSpaceFrustumBounds(out float2 OutDistanceMinMax,out float2 OutInclinationMinMax,out float2 OutAzimuthMinMax,float4x4 CameraProjectionToWorldSpace,float4x4 CameraWorldToProjectionSpace,float4x4 RectificationToWorldSpace,float4x4 WorldToRectificationSpace){
51 const float PI=3.1415926535897932384626433832795f;
53 float4 pFarPlaneCorner[4]={
54 float4(-1.0f,-1.0f,1.0f,1.0f),
55 float4(-1.0f, 1.0f,1.0f,1.0f),
56 float4( 1.0f, 1.0f,1.0f,1.0f),
57 float4( 1.0f,-1.0f,1.0f,1.0f)
59 [unroll]
for(
int i=0;i!=4;++i){
60 pFarPlaneCorner[i]=mul(pFarPlaneCorner[i],CameraProjectionToWorldSpace);
61 pFarPlaneCorner[i]=mul(pFarPlaneCorner[i],WorldToRectificationSpace);
62 pFarPlaneCorner[i]/=pFarPlaneCorner[i].w;
65 OutDistanceMinMax=float2(0.0f,0.0f);
66 [unroll]
for(
int i=0;i!=4;++i){
67 OutDistanceMinMax.y=max(OutDistanceMinMax.y,length(pFarPlaneCorner[i].xy));
71 float4 NorthPole=mul(mul(float4(0.0f,0.0f,1.0f,1.0f),RectificationToWorldSpace),CameraWorldToProjectionSpace);
72 bool4 ClipResult=bool4(NorthPole.x<=NorthPole.w,NorthPole.x>=-NorthPole.w,NorthPole.y<=NorthPole.w,NorthPole.y>=-NorthPole.w);
73 bool NorthPoleInFrustum=all(ClipResult);
74 bool SouthPoleInFrustum=all(!ClipResult);
76 if(NorthPoleInFrustum || SouthPoleInFrustum){
77 OutAzimuthMinMax=float2(0.0f,2.0f*PI);
81 float2 pFarPlaneCornerFlat[4];
82 [unroll]
for(
int i=0;i!=4;++i){
83 pFarPlaneCornerFlat[i]=normalize(pFarPlaneCorner[i].xy);
86 float MinDotProduct=2.0f;
88 [unroll]
for(
int i=0;i!=4;++i){
89 [unroll]
for(
int j=0;j!=i;++j){
90 float DotProduct=dot(pFarPlaneCornerFlat[i],pFarPlaneCornerFlat[j]);
91 bool IsMinimal=(DotProduct<MinDotProduct);
92 pCorner[0]=IsMinimal?pFarPlaneCornerFlat[i]:pCorner[0];
93 pCorner[1]=IsMinimal?pFarPlaneCornerFlat[j]:pCorner[1];
94 MinDotProduct=IsMinimal?DotProduct:MinDotProduct;
99 bool FirstIsClockwise=dot(float2(-pCorner[0].y,pCorner[0].x),pCorner[1])>0.0f;
101 float AzimuthRange=acos(MinDotProduct);
102 float2 MinCorner=FirstIsClockwise?pCorner[0]:pCorner[1];
103 OutAzimuthMinMax.x=atan2(MinCorner.y,MinCorner.x);
104 OutAzimuthMinMax.x=(OutAzimuthMinMax.x<0.0f)?(OutAzimuthMinMax.x+2.0f*PI):OutAzimuthMinMax.x;
105 OutAzimuthMinMax.y=OutAzimuthMinMax.x+AzimuthRange;
108 OutInclinationMinMax=float2(PI,0.0f);
109 [unroll]
for(
int i=0;i!=4;++i){
110 float CornerInclination=acos(normalize(pFarPlaneCorner[i].xyz).z);
111 OutInclinationMinMax.x=min(OutInclinationMinMax.x,CornerInclination);
112 OutInclinationMinMax.y=max(OutInclinationMinMax.y,CornerInclination);
116 [unroll]
for(
int i=0;i!=4;++i){
117 float3 Start=pFarPlaneCorner[i].xyz;
118 float3 End=pFarPlaneCorner[(i<3)?(i+1):0].xyz;
119 float3 Offset=End-Start;
121 float InclinationExtremum=(Start.z*dot(Start,Offset)-Offset.z*dot(Start,Start))
122 /(Offset.z*dot(Start,Offset)-Start.z*dot(Offset,Offset));
123 InclinationExtremum=saturate(InclinationExtremum);
125 float3 ExtremumLocation=normalize(lerp(Start,End,InclinationExtremum));
126 float ExtremalLineInclination=acos(ExtremumLocation.z);
127 OutInclinationMinMax.x=min(OutInclinationMinMax.x,ExtremalLineInclination);
128 OutInclinationMinMax.y=max(OutInclinationMinMax.y,ExtremalLineInclination);
132 OutInclinationMinMax.x=NorthPoleInFrustum?0.0f:OutInclinationMinMax.x;
133 OutInclinationMinMax.y=SouthPoleInFrustum?PI:OutInclinationMinMax.y;
135 OutInclinationMinMax=lerp(OutInclinationMinMax.xx,OutInclinationMinMax.yy,float2(-0.05f,1.05f));
136 OutInclinationMinMax=clamp(OutInclinationMinMax,0.0f,PI);
145 void GetPerspectiveDepth1(out
float OutPerspectiveDepth,Texture2DMS<float,1> DepthStencilTexture,int2 TexelIndex){
147 OutPerspectiveDepth=0.0f;
148 [unroll]
for(uint i=0;i!=nSample;++i){
149 OutPerspectiveDepth+=DepthStencilTexture.Load(TexelIndex,i);
151 OutPerspectiveDepth/=nSample;
153 void GetPerspectiveDepth2(out
float OutPerspectiveDepth,Texture2DMS<float,2> DepthStencilTexture,int2 TexelIndex){
155 OutPerspectiveDepth=0.0f;
156 [unroll]
for(uint i=0;i!=nSample;++i){
157 OutPerspectiveDepth+=DepthStencilTexture.Load(TexelIndex,i);
159 OutPerspectiveDepth/=nSample;
161 void GetPerspectiveDepth4(out
float OutPerspectiveDepth,Texture2DMS<float,4> DepthStencilTexture,int2 TexelIndex){
163 OutPerspectiveDepth=0.0f;
164 [unroll]
for(uint i=0;i!=nSample;++i){
165 OutPerspectiveDepth+=DepthStencilTexture.Load(TexelIndex,i);
167 OutPerspectiveDepth/=nSample;
169 void GetPerspectiveDepth8(out
float OutPerspectiveDepth,Texture2DMS<float,8> DepthStencilTexture,int2 TexelIndex){
171 OutPerspectiveDepth=0.0f;
172 [unroll]
for(uint i=0;i!=nSample;++i){
173 OutPerspectiveDepth+=DepthStencilTexture.Load(TexelIndex,i);
175 OutPerspectiveDepth/=nSample;
183 OutExtinctionCoefficient=-log(0.5f)/HalfOpacityDistance;
190 OutViewRayLength=distance(WorldSpacePosition,WorldSpaceCameraPosition);
202 OutReceivedRadiance=OutgoingRadiance*exp(-ExtinctionCoefficient*ViewRayLength);
221 void ComputeViewRayFromProjectionSpace(out
float OutViewRayLength,out float3 OutWorldSpaceRayStart,out float3 OutWorldSpaceRayEnd,float2 TexCoord,
float PerspectiveDepth,float4x4 ProjectionToViewSpace,float4x4 ViewToWorldSpace){
222 float4 ProjectionSpacePosition=float4(TexCoord*float2(2.0f,-2.0f)+float2(-1.0f,1.0f),PerspectiveDepth,1.0f);
223 float4 ViewSpacePosition=mul(ProjectionSpacePosition,ProjectionToViewSpace);
224 ViewSpacePosition/=ViewSpacePosition.w;
225 OutWorldSpaceRayStart=mul(float4(0.0f,0.0f,0.0f,1.0f),ViewToWorldSpace).xyz;
226 OutWorldSpaceRayEnd=mul(ViewSpacePosition,ViewToWorldSpace).xyz;
227 OutViewRayLength=length(ViewSpacePosition.xyz);
235 OutPhaseTimesAlbedoTimesIrradiance=PhaseTimesAlbedo*DirectionalLightIrradiance;
244 OutScatteringRadiance=ScatteringIntegral*PhaseTimesAlbedoTimesIrradiance;
252 OutScatteringColor.rgb=ScatteringRadiance;
253 OutScatteringColor.a=1.0f;
265 OutScatteringIntegral=1.0f-exp(-ExtinctionCoefficient*ViewRayLength);
283 void ComputeSingleScatteringRayMarchingDirectional(out
float OutScatteringIntegral,
float ViewRayLength,float3 WorldSpaceViewRayStart,float3 WorldSpaceViewRayEnd,SSamplerTexturePair2D_float ShadowMapSampler,float4x4 ShadowMapWorldToProjectionSpace,
float ExtinctionCoefficient,
int nSample){
284 OutScatteringIntegral=0.0f;
287 float4 RayStart=mul(float4(WorldSpaceViewRayStart,1.0f),ShadowMapWorldToProjectionSpace);
288 float4 RayEnd=mul(float4(WorldSpaceViewRayEnd,1.0f),ShadowMapWorldToProjectionSpace);
291 RayStart.xy=RayStart.xy*float2(0.5f,-0.5f)+RayStart.w*float2(0.5f,0.5f);
292 RayEnd.xy=RayEnd.xy*float2(0.5f,-0.5f)+RayEnd.w*float2(0.5f,0.5f);
295 float InvSampleCount=1.0f/nSample;
297 float InitialLerpFactor=-RandomOffset*InvSampleCount;
300 float4 SampleOffset=(RayEnd-RayStart)*InvSampleCount;
301 float4 SamplePosition=lerp(RayStart,RayEnd,InitialLerpFactor);
302 float Weight=exp(-ExtinctionCoefficient*InitialLerpFactor*ViewRayLength)-exp(-ExtinctionCoefficient*(InitialLerpFactor+InvSampleCount)*ViewRayLength);
303 float WeightFactor=exp(-ExtinctionCoefficient*ViewRayLength*InvSampleCount);
304 [loop]
for(
int i=0;i!=nSample;++i){
306 SamplePosition+=SampleOffset;
308 float InvSamplePositionW=1.0f/SamplePosition.w;
309 float2 TexCoord=SamplePosition.xy*InvSamplePositionW;
310 float RayDepth=SamplePosition.z*InvSamplePositionW;
311 float ShadowMapDepth=ShadowMapSampler.Texture.SampleLevel(ShadowMapSampler.Sampler,TexCoord,0.0f);
313 bool LightVisible=(RayDepth<ShadowMapDepth || TexCoord.x<0.0f || TexCoord.y<0.0f || TexCoord.x>1.0f || TexCoord.y>1.0f);
314 Weight*=WeightFactor;
315 OutScatteringIntegral+=LightVisible?Weight:0.0f;
337 const float PI=3.1415926535897932384626433832795f;
339 float4 RectificationSpaceViewRayEnd=mul(float4(WorldSpaceViewRayEnd,1.0f),WorldToRectificationSpace);
340 float Distance,Inclination,Azimuth;
343 float InvMaxDistance=1.0f/DistanceMinMax.y;
344 OutRayEndTexCoord.x=Distance*InvMaxDistance;
345 OutRayEndTexCoord.y=Azimuth-AzimuthMinMax.x;
346 OutRayEndTexCoord.y=(OutRayEndTexCoord.y<0.0f)?(OutRayEndTexCoord.y+2.0f*PI):OutRayEndTexCoord.y;
347 float InvAzimuthRange=1.0f/(AzimuthMinMax.y-AzimuthMinMax.x);
348 OutRayEndTexCoord.y*=InvAzimuthRange;
349 OutRayDepth=mad((Inclination-InclinationMinMax.x)/(InclinationMinMax.y-InclinationMinMax.x),2.0f,-1.0f);
362 void ComputePrefilteredSingleScatteringConvolution8(out
float OutScatteringIntegral,float2 RayEndTexCoord,
float RayDepth,
float ScatteringIntegralWithoutOcclusion,SSamplerTexturePair2D ShadowMapSampler0,SSamplerTexturePair2D ShadowMapSampler1,SSamplerTexturePair2D ShadowMapSampler2,SSamplerTexturePair2D ShadowMapSampler3){
363 const float PI=3.1415926535897932384626433832795f;
365 float4 Fourier1_2=ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,RayEndTexCoord);
366 float4 Fourier3_4=ShadowMapSampler1.Texture.Sample(ShadowMapSampler1.Sampler,RayEndTexCoord);
367 float4 Fourier5_6=ShadowMapSampler2.Texture.Sample(ShadowMapSampler2.Sampler,RayEndTexCoord);
368 float4 Fourier7_8=ShadowMapSampler3.Texture.Sample(ShadowMapSampler3.Sampler,RayEndTexCoord);
369 float2 pFourierCoefficient[8]={
370 Fourier1_2.xy*2.0f-1.0f,
371 Fourier1_2.zw*2.0f-1.0f,
372 Fourier3_4.zw*2.0f-1.0f,
373 Fourier3_4.zw*2.0f-1.0f,
374 Fourier5_6.zw*2.0f-1.0f,
375 Fourier5_6.zw*2.0f-1.0f,
376 Fourier7_8.zw*2.0f-1.0f,
377 Fourier7_8.zw*2.0f-1.0f
381 sincos(mad(RayDepth,0.5f*PI,0.5f*PI),Fourier1.y,Fourier1.x);
383 float2 pBasisFunction[8];
384 pBasisFunction[0]=Fourier1;
385 float2 FourierSquare=float2(dot(Fourier1,float2(Fourier1.x,-Fourier1.y)),dot(Fourier1.xy,Fourier1.yx));
386 [unroll]
for(
int i=1;i!=8;++i){
387 float2 LHS=pBasisFunction[i-1];
388 float2 RHS=FourierSquare;
389 pBasisFunction[i]=float2(dot(LHS,float2(RHS.x,-RHS.y)),dot(LHS.xy,RHS.yx));
393 OutScatteringIntegral=0.5f;
394 [unroll]
for(
int i=0;i!=8;++i){
395 float Constant=PI*(2.0f*i+1.0f);
396 float Summand=pBasisFunction[i].y*pFourierCoefficient[i].x-pBasisFunction[i].x*pFourierCoefficient[i].y;
397 OutScatteringIntegral+=Summand*2.0f/Constant;
399 OutScatteringIntegral=saturate(1.0f-OutScatteringIntegral);
400 OutScatteringIntegral*=ScatteringIntegralWithoutOcclusion;
406 void ComputePrefilteredSingleScatteringConvolution16(out
float OutScatteringIntegral,float2 RayEndTexCoord,
float RayDepth,
float ScatteringIntegralWithoutOcclusion,SSamplerTexturePair2D ShadowMapSampler0,SSamplerTexturePair2D ShadowMapSampler1,SSamplerTexturePair2D ShadowMapSampler2,SSamplerTexturePair2D ShadowMapSampler3,SSamplerTexturePair2D ShadowMapSampler4,SSamplerTexturePair2D ShadowMapSampler5,SSamplerTexturePair2D ShadowMapSampler6,SSamplerTexturePair2D ShadowMapSampler7){
407 const float PI=3.1415926535897932384626433832795f;
409 float4 Fourier1_2=ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,RayEndTexCoord);
410 float4 Fourier3_4=ShadowMapSampler1.Texture.Sample(ShadowMapSampler1.Sampler,RayEndTexCoord);
411 float4 Fourier5_6=ShadowMapSampler2.Texture.Sample(ShadowMapSampler2.Sampler,RayEndTexCoord);
412 float4 Fourier7_8=ShadowMapSampler3.Texture.Sample(ShadowMapSampler3.Sampler,RayEndTexCoord);
413 float4 Fourier9_10=ShadowMapSampler4.Texture.Sample(ShadowMapSampler4.Sampler,RayEndTexCoord);
414 float4 Fourier11_12=ShadowMapSampler5.Texture.Sample(ShadowMapSampler5.Sampler,RayEndTexCoord);
415 float4 Fourier13_14=ShadowMapSampler6.Texture.Sample(ShadowMapSampler6.Sampler,RayEndTexCoord);
416 float4 Fourier15_16=ShadowMapSampler7.Texture.Sample(ShadowMapSampler7.Sampler,RayEndTexCoord);
417 float2 pFourierCoefficient[16]={
418 Fourier1_2.xy*2.0f-1.0f,
419 Fourier1_2.zw*2.0f-1.0f,
420 Fourier3_4.zw*2.0f-1.0f,
421 Fourier3_4.zw*2.0f-1.0f,
422 Fourier5_6.zw*2.0f-1.0f,
423 Fourier5_6.zw*2.0f-1.0f,
424 Fourier7_8.zw*2.0f-1.0f,
425 Fourier7_8.zw*2.0f-1.0f,
426 Fourier9_10.xy*2.0f-1.0f,
427 Fourier9_10.zw*2.0f-1.0f,
428 Fourier11_12.xy*2.0f-1.0f,
429 Fourier11_12.zw*2.0f-1.0f,
430 Fourier13_14.xy*2.0f-1.0f,
431 Fourier13_14.zw*2.0f-1.0f,
432 Fourier15_16.xy*2.0f-1.0f,
433 Fourier15_16.zw*2.0f-1.0f
437 sincos(mad(RayDepth,0.5f*PI,0.5f*PI),Fourier1.y,Fourier1.x);
439 float2 pBasisFunction[16];
440 pBasisFunction[0]=Fourier1;
441 float2 FourierSquare=float2(dot(Fourier1,float2(Fourier1.x,-Fourier1.y)),dot(Fourier1.xy,Fourier1.yx));
442 [unroll]
for(
int i=1;i!=16;++i){
443 float2 LHS=pBasisFunction[i-1];
444 float2 RHS=FourierSquare;
445 pBasisFunction[i]=float2(dot(LHS,float2(RHS.x,-RHS.y)),dot(LHS.xy,RHS.yx));
449 OutScatteringIntegral=0.5f;
450 [unroll]
for(
int i=0;i!=16;++i){
451 float Constant=PI*(2.0f*i+1.0f);
452 float Summand=pBasisFunction[i].y*pFourierCoefficient[i].x-pBasisFunction[i].x*pFourierCoefficient[i].y;
453 OutScatteringIntegral+=Summand*2.0f/Constant;
455 OutScatteringIntegral=saturate(1.0f-OutScatteringIntegral);
456 OutScatteringIntegral*=ScatteringIntegralWithoutOcclusion;
474 void ComputeAdaptiveOverestimationWeight(out
float OutOverestimationWeight,float3 WorldSpaceViewRayStart,float3 WorldSpaceViewRayEnd,float3 WorldSpaceLightDirection,float2 OverestimationWeightMinMax){
478 float3 WorldSpaceViewRayDirection=normalize(WorldSpaceViewRayEnd-WorldSpaceViewRayStart);
479 float LightViewZ=dot(WorldSpaceLightDirection,WorldSpaceViewRayDirection);
482 float LerpFactor=mad(LightViewZ,0.5f,0.5f);
483 OutOverestimationWeight=saturate(lerp(OverestimationWeightMinMax.x,OverestimationWeightMinMax.y,LerpFactor));
501 void ComputePrefilteredSingleScattering4Moments(out
float OutScatteringIntegral,float2 RayEndTexCoord,
float RayDepth,
float ScatteringIntegralWithoutOcclusion,SSamplerTexturePair2D ShadowMapSampler0,
float MomentBias,
float OverestimationWeight=0.5f){
502 float4 OptimizedSample=ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,RayEndTexCoord);
504 OutScatteringIntegral*=ScatteringIntegralWithoutOcclusion;
509 void ComputePrefilteredSingleScattering2_4Moments(out
float OutScatteringIntegral,float2 RayEndTexCoord,
float RayDepth,
float ScatteringIntegralWithoutOcclusion,SSamplerTexturePair2D_float2 ShadowMapSampler0,SSamplerTexturePair2D ShadowMapSampler1,
float MomentBias,
float OverestimationWeight=0.5f){
510 float2 OptimizedSample0=ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,RayEndTexCoord);
511 float4 OptimizedSample1=ShadowMapSampler1.Texture.Sample(ShadowMapSampler1.Sampler,RayEndTexCoord);
512 OutScatteringIntegral=1.0f-
EstimateIntegralFrom6Moments(RayDepth,OptimizedSample0,OptimizedSample1,MomentBias,1.0f-OverestimationWeight);
513 OutScatteringIntegral*=ScatteringIntegralWithoutOcclusion;
518 void ComputePrefilteredSingleScattering3_3Moments(out
float OutScatteringIntegral,float2 RayEndTexCoord,
float RayDepth,
float ScatteringIntegralWithoutOcclusion,SSamplerTexturePair2D_float3 ShadowMapSampler0,SSamplerTexturePair2D_float3 ShadowMapSampler1,
float MomentBias,
float OverestimationWeight=0.5f){
519 float3 OptimizedSample0=ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,RayEndTexCoord);
520 float3 OptimizedSample1=ShadowMapSampler1.Texture.Sample(ShadowMapSampler1.Sampler,RayEndTexCoord);
521 OutScatteringIntegral=1.0f-
EstimateIntegralFrom6Moments(RayDepth,OptimizedSample0.xy,float4(OptimizedSample0.z,OptimizedSample1),MomentBias,1.0f-OverestimationWeight);
522 OutScatteringIntegral*=ScatteringIntegralWithoutOcclusion;
539 uint Height=(uint)(TextureSize.y);
540 nOutThreadGroup=uint3(1,nPrefixSumShadowMap*Height/ThreadGroupSize.y,1);
547 float4 ProjectionSpaceCameraPosition=mul(float4(0.0f,0.0f,0.0f,1.0f),RectificationToShadowMapProjectionSpace);
548 float CameraShadowMapDepth=ProjectionSpaceCameraPosition.z/ProjectionSpaceCameraPosition.w;
549 float4 ProjectionSpaceNorthPole=mul(float4(0.0f,0.0f,1.0f,1.0f),RectificationToShadowMapProjectionSpace);
550 float NorthPoleShadowMapDepth=ProjectionSpaceNorthPole.z/ProjectionSpaceNorthPole.w;
551 OutShadowMapToRectificationDepthTransform.x=1.0f/(NorthPoleShadowMapDepth-CameraShadowMapDepth);
552 OutShadowMapToRectificationDepthTransform.y=-CameraShadowMapDepth*OutShadowMapToRectificationDepthTransform.x;
553 OutShadowMapToRectificationDepthTransform.x*=0.5f;
554 OutShadowMapToRectificationDepthTransform.y+=OutShadowMapToRectificationDepthTransform.x;
562 void GetRectifiedDepth(out
float OutRectifiedDepth,SSamplerTexturePair2D_float ShadowMapSampler0,float2 RectifiedTexCoord,float4x4 RectificationToShadowMapProjectionSpace,float2 ShadowMapToRectificationDepthTransform,float2 DistanceMinMax,float2 InclinationMinMax,float2 AzimuthMinMax){
564 float Azimuth=lerp(AzimuthMinMax.x,AzimuthMinMax.y,RectifiedTexCoord.y);
565 float Distance=RectifiedTexCoord.x*DistanceMinMax.y;
566 float2 RectificationSpaceXY;
567 sincos(Azimuth,RectificationSpaceXY.y,RectificationSpaceXY.x);
568 RectificationSpaceXY*=Distance;
569 float4 ShadowMapProjectionSpace=mul(float4(RectificationSpaceXY,0.0f,1.0f),RectificationToShadowMapProjectionSpace);
570 ShadowMapProjectionSpace/=ShadowMapProjectionSpace.w;
571 float2 ShadowMapTexCoord=mad(ShadowMapProjectionSpace.xy,float2(0.5f,-0.5f),float2(0.5f,0.5f));
573 float ShadowMapDepth=mad(ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,ShadowMapTexCoord),2.0f,-1.0f);
575 float RectificationSpaceDepth=mad(ShadowMapDepth,ShadowMapToRectificationDepthTransform.x,ShadowMapToRectificationDepthTransform.y);
576 float Inclination=atan2(Distance,RectificationSpaceDepth);
578 OutRectifiedDepth=saturate((Inclination-InclinationMinMax.x)/(InclinationMinMax.y-InclinationMinMax.x));
579 OutRectifiedDepth=OutRectifiedDepth*2.0f-1.0f;
590 void GetSparseRectifiedRepresentation(out float2 OutRectifiedDepth,out
float OutDepthWeight1,SSamplerTexturePair2D ShadowMapSampler0,float2 RectifiedTexCoord,float4x4 RectificationToShadowMapProjectionSpace,float2 ShadowMapToRectificationDepthTransform,float2 DistanceMinMax,float2 InclinationMinMax,float2 AzimuthMinMax){
592 float Azimuth=lerp(AzimuthMinMax.x,AzimuthMinMax.y,RectifiedTexCoord.y);
593 float Distance=RectifiedTexCoord.x*DistanceMinMax.y;
594 float2 RectificationSpaceXY;
595 sincos(Azimuth,RectificationSpaceXY.y,RectificationSpaceXY.x);
596 RectificationSpaceXY*=Distance;
597 float4 ShadowMapProjectionSpace=mul(float4(RectificationSpaceXY,0.0f,1.0f),RectificationToShadowMapProjectionSpace);
598 ShadowMapProjectionSpace/=ShadowMapProjectionSpace.w;
599 float2 ShadowMapTexCoord=mad(ShadowMapProjectionSpace.xy,float2(0.5f,-0.5f),float2(0.5f,0.5f));
602 float4 OptimizedMoments=ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,ShadowMapTexCoord);
603 float2 ShadowMapDepth;
606 float2 RectificationSpaceDepth=mad(ShadowMapDepth,ShadowMapToRectificationDepthTransform.x,ShadowMapToRectificationDepthTransform.y);
607 float2 Inclination=float2(
608 atan2(Distance,RectificationSpaceDepth[0]),
609 atan2(Distance,RectificationSpaceDepth[1])
612 OutRectifiedDepth=saturate((Inclination-InclinationMinMax.x)/(InclinationMinMax.y-InclinationMinMax.x));
613 OutRectifiedDepth=OutRectifiedDepth*2.0f-1.0f;
625 float4 pCanonicalMoments0[2];
626 [unroll]
for(
int i=0;i!=2;++i){
627 float Depth=RectifiedDepth[i];
628 float SquaredDepth=Depth*Depth;
629 pCanonicalMoments0[i]=float4(Depth,SquaredDepth,SquaredDepth*Depth,SquaredDepth*SquaredDepth);
631 float4 QuantizedMoments0;
633 OutQuantizedMoments0=QuantizedMoments0;
639 float2 QuantizedMoments0;
640 float4 QuantizedMoments1;
642 OutQuantizedMoments0=float3(QuantizedMoments0,QuantizedMoments1.x);
643 OutQuantizedMoments1=QuantizedMoments1.yzw;
650 float2 pCanonicalMoments0[2];
651 float4 pCanonicalMoments1[2];
652 [unroll]
for(
int i=0;i!=2;++i){
653 float Depth=RectifiedDepth[i];
654 float SquaredDepth=Depth*Depth;
655 float CubedDepth=SquaredDepth*Depth;
656 pCanonicalMoments0[i]=float2(Depth,SquaredDepth);
657 pCanonicalMoments1[i]=float4(CubedDepth,SquaredDepth*SquaredDepth,CubedDepth*SquaredDepth,CubedDepth*CubedDepth);
659 float2 QuantizedMoments0;
660 float4 QuantizedMoments1;
662 lerp(pCanonicalMoments0[0],pCanonicalMoments0[1],DepthWeight1),lerp(pCanonicalMoments1[0],pCanonicalMoments1[1],DepthWeight1));
663 OutQuantizedMoments0.xy=QuantizedMoments0;
664 OutQuantizedMoments0.z=QuantizedMoments1.x;
665 OutQuantizedMoments1=QuantizedMoments1.yzw;
677 float2 pCanonicalMoments0[2];
678 float4 pCanonicalMoments1[2];
679 [unroll]
for(
int i=0;i!=2;++i){
680 float Depth=RectifiedDepth[i];
681 float SquaredDepth=Depth*Depth;
682 float CubedDepth=SquaredDepth*Depth;
683 pCanonicalMoments0[i]=float2(Depth,SquaredDepth);
684 pCanonicalMoments1[i]=float4(CubedDepth,SquaredDepth*SquaredDepth,CubedDepth*SquaredDepth,CubedDepth*CubedDepth);
687 lerp(pCanonicalMoments0[0],pCanonicalMoments0[1],DepthWeight1),lerp(pCanonicalMoments1[0],pCanonicalMoments1[1],DepthWeight1));
693 void ApplyTransmittanceWeightedPrefixSumNonLinearRectificationCSM8(inout RWTexture2D<float4> OutFilteredShadowMap0,inout RWTexture2D<float4> OutFilteredShadowMap1,inout RWTexture2D<float4> OutFilteredShadowMap2,inout RWTexture2D<float4> OutFilteredShadowMap3,SSamplerTexturePair2D ShadowMapSampler0,SSamplerTexturePair2D ShadowMapSampler1,SSamplerTexturePair2D ShadowMapSampler2,SSamplerTexturePair2D ShadowMapSampler3,uint3 ThreadID,
float ExtinctionCoefficient,float2 DistanceMinMax,float2 InclinationMinMax){
695 OutFilteredShadowMap0.GetDimensions(Width,Height);
697 uint iShadowMap=ThreadID.y/Height;
698 uint iThreadY=ThreadID.y%Height;
702 else if(iShadowMap==1){
705 else if(iShadowMap==2){
708 else if(iShadowMap==3){
716 void ApplyTransmittanceWeightedPrefixSumNonLinearRectificationCSM16(inout RWTexture2D<float4> OutFilteredShadowMap0,inout RWTexture2D<float4> OutFilteredShadowMap1,inout RWTexture2D<float4> OutFilteredShadowMap2,inout RWTexture2D<float4> OutFilteredShadowMap3,inout RWTexture2D<float4> OutFilteredShadowMap4,inout RWTexture2D<float4> OutFilteredShadowMap5,inout RWTexture2D<float4> OutFilteredShadowMap6,inout RWTexture2D<float4> OutFilteredShadowMap7,SSamplerTexturePair2D ShadowMapSampler0,SSamplerTexturePair2D ShadowMapSampler1,SSamplerTexturePair2D ShadowMapSampler2,SSamplerTexturePair2D ShadowMapSampler3,SSamplerTexturePair2D ShadowMapSampler4,SSamplerTexturePair2D ShadowMapSampler5,SSamplerTexturePair2D ShadowMapSampler6,SSamplerTexturePair2D ShadowMapSampler7,uint3 ThreadID,
float ExtinctionCoefficient,float2 DistanceMinMax,float2 InclinationMinMax){
718 OutFilteredShadowMap0.GetDimensions(Width,Height);
720 uint iShadowMap=ThreadID.y/Height;
721 uint iThreadY=ThreadID.y%Height;
725 else if(iShadowMap==1){
728 else if(iShadowMap==2){
731 else if(iShadowMap==3){
734 else if(iShadowMap==4){
737 else if(iShadowMap==5){
740 else if(iShadowMap==6){
743 else if(iShadowMap==7){
766 OutFilteredShadowMap0.GetDimensions(Width,Height);
776 void ApplyTransmittanceWeightedPrefixSumNonLinearRectificationMSM2_4(inout RWTexture2D<float2> OutFilteredShadowMap0,inout RWTexture2D<float4> OutFilteredShadowMap1,SSamplerTexturePair2D_float2 ShadowMapSampler0,SSamplerTexturePair2D ShadowMapSampler1,uint3 ThreadID,
float ExtinctionCoefficient,float2 DistanceMinMax,float2 InclinationMinMax){
778 OutFilteredShadowMap0.GetDimensions(Width,Height);
781 if(ThreadID.y<Height){
793 void ApplyTransmittanceWeightedPrefixSumNonLinearRectificationMSM3_3(inout RWTexture2D<float3> OutFilteredShadowMap0,inout RWTexture2D<float3> OutFilteredShadowMap1,SSamplerTexturePair2D_float3 ShadowMapSampler0,SSamplerTexturePair2D_float3 ShadowMapSampler1,uint3 ThreadID,
float ExtinctionCoefficient,float2 DistanceMinMax,float2 InclinationMinMax){
795 OutFilteredShadowMap0.GetDimensions(Width,Height);
798 if(ThreadID.y<Height){
float GetRandomNumber(uint Seed)