Shaders for Shadows
Shader code for rendering shadows of translucent occluders, soft shadows and single scattering with moment shadow maps.
 All Classes Files Functions Variables Pages
ParticipatingMedia.fx
Go to the documentation of this file.
1 
5 #include "RandomNumbers.fx"
7 
21 void ComputeRectificationToWorldSpaceDirectional(out float4x4 OutRectificationToWorldSpace,float3 WorldSpaceCameraPosition,float4x4 ShadowMapViewToWorldSpace){
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
27  );
28 }
29 
30 
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;
52  // Compute the rectification space corners of the far plane
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)
58  };
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;
63  }
64  // Compute the maximal distance
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));
68  }
69  // Figure out whether one of the poles of the unit sphere lies between the side
70  // clipping planes
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);
75  // Compute the azimuths
76  if(NorthPoleInFrustum || SouthPoleInFrustum){
77  OutAzimuthMinMax=float2(0.0f,2.0f*PI);
78  }
79  else{
80  // Project down to the plane and normalize
81  float2 pFarPlaneCornerFlat[4];
82  [unroll] for(int i=0;i!=4;++i){
83  pFarPlaneCornerFlat[i]=normalize(pFarPlaneCorner[i].xy);
84  }
85  // Compute the biggest pairwise angle
86  float MinDotProduct=2.0f;
87  float2 pCorner[2];
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;
95  }
96  }
97  // Figure out which of the two corners is clockwise of the other (when going
98  // no farther than pi)
99  bool FirstIsClockwise=dot(float2(-pCorner[0].y,pCorner[0].x),pCorner[1])>0.0f;
100  // Compute the angles
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;
106  }
107  // Compute the inclinations. Start with the corner points.
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);
113  }
114  // Now handle the case that one of the lines bounding the far plane holds an
115  // extremum
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;
120  // Determine the location of the extremal inclination on the line
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);
124  // Compute the inclination and update the minima and maxima
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);
129  }
130  // Finally, handle the case that some point in the inner of the far plane is an
131  // extremum
132  OutInclinationMinMax.x=NorthPoleInFrustum?0.0f:OutInclinationMinMax.x;
133  OutInclinationMinMax.y=SouthPoleInFrustum?PI:OutInclinationMinMax.y;
134  // Stretch inclination bounds a little to avoid unnecessary leaking
135  OutInclinationMinMax=lerp(OutInclinationMinMax.xx,OutInclinationMinMax.yy,float2(-0.05f,1.05f));
136  OutInclinationMinMax=clamp(OutInclinationMinMax,0.0f,PI);
137 }
138 
139 
145 void GetPerspectiveDepth1(out float OutPerspectiveDepth,Texture2DMS<float,1> DepthStencilTexture,int2 TexelIndex){
146  uint nSample=1;
147  OutPerspectiveDepth=0.0f;
148  [unroll] for(uint i=0;i!=nSample;++i){
149  OutPerspectiveDepth+=DepthStencilTexture.Load(TexelIndex,i);
150  }
151  OutPerspectiveDepth/=nSample;
152 }
153 void GetPerspectiveDepth2(out float OutPerspectiveDepth,Texture2DMS<float,2> DepthStencilTexture,int2 TexelIndex){
154  uint nSample=2;
155  OutPerspectiveDepth=0.0f;
156  [unroll] for(uint i=0;i!=nSample;++i){
157  OutPerspectiveDepth+=DepthStencilTexture.Load(TexelIndex,i);
158  }
159  OutPerspectiveDepth/=nSample;
160 }
161 void GetPerspectiveDepth4(out float OutPerspectiveDepth,Texture2DMS<float,4> DepthStencilTexture,int2 TexelIndex){
162  uint nSample=4;
163  OutPerspectiveDepth=0.0f;
164  [unroll] for(uint i=0;i!=nSample;++i){
165  OutPerspectiveDepth+=DepthStencilTexture.Load(TexelIndex,i);
166  }
167  OutPerspectiveDepth/=nSample;
168 }
169 void GetPerspectiveDepth8(out float OutPerspectiveDepth,Texture2DMS<float,8> DepthStencilTexture,int2 TexelIndex){
170  uint nSample=8;
171  OutPerspectiveDepth=0.0f;
172  [unroll] for(uint i=0;i!=nSample;++i){
173  OutPerspectiveDepth+=DepthStencilTexture.Load(TexelIndex,i);
174  }
175  OutPerspectiveDepth/=nSample;
176 }
178 
179 
182 void ComputeExtinctionCoefficient(out float OutExtinctionCoefficient,float HalfOpacityDistance){
183  OutExtinctionCoefficient=-log(0.5f)/HalfOpacityDistance;
184 }
185 
186 
189 void ComputeViewRayLengthFromWorldSpace(out float OutViewRayLength,float3 WorldSpacePosition,float3 WorldSpaceCameraPosition){
190  OutViewRayLength=distance(WorldSpacePosition,WorldSpaceCameraPosition);
191 }
192 
193 
201 void ApplyAbsorptionToOutgoingRadiance(out float3 OutReceivedRadiance,float3 OutgoingRadiance,float ViewRayLength,float ExtinctionCoefficient){
202  OutReceivedRadiance=OutgoingRadiance*exp(-ExtinctionCoefficient*ViewRayLength);
203 }
204 
205 
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);
228 }
229 
230 
234 void ComputeSingleScatteringFactors(out float3 OutPhaseTimesAlbedoTimesIrradiance,float3 PhaseTimesAlbedo,float3 DirectionalLightIrradiance){
235  OutPhaseTimesAlbedoTimesIrradiance=PhaseTimesAlbedo*DirectionalLightIrradiance;
236 }
237 
243 void ComputeSingleScatteringRadiance(out float3 OutScatteringRadiance,float ScatteringIntegral,float3 PhaseTimesAlbedoTimesIrradiance){
244  OutScatteringRadiance=ScatteringIntegral*PhaseTimesAlbedoTimesIrradiance;
245 }
246 
251 void ComputeScatteringColor(out float4 OutScatteringColor,float3 ScatteringRadiance){
252  OutScatteringColor.rgb=ScatteringRadiance;
253  OutScatteringColor.a=1.0f;
254 }
255 
256 
264 void ComputeSingleScatteringNoOcclusionDirectional(out float OutScatteringIntegral,float ViewRayLength,float ExtinctionCoefficient){
265  OutScatteringIntegral=1.0f-exp(-ExtinctionCoefficient*ViewRayLength);
266 }
267 
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;
285  // Convert ray start and ray end to projection space and compute the offset
286  // between consecutive samples
287  float4 RayStart=mul(float4(WorldSpaceViewRayStart,1.0f),ShadowMapWorldToProjectionSpace);
288  float4 RayEnd=mul(float4(WorldSpaceViewRayEnd,1.0f),ShadowMapWorldToProjectionSpace);
289  // Convert the projection space coordinates to coordinates that enable immediate
290  // computation of texture coordinates to save two mads within the loop
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);
293  // Implement jittering to avoid banding. Do this using a cheap linear
294  // congruential generator.
295  float InvSampleCount=1.0f/nSample;
296  float RandomOffset=GetRandomNumber(WorldSpaceViewRayEnd);
297  float InitialLerpFactor=-RandomOffset*InvSampleCount;
298  // Prepare variables that can be updated efficiently during iterations of the
299  // loop
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){
305  // Compute the sample position in shadow map projection space
306  SamplePosition+=SampleOffset;
307  // Do the look up in the shadow map
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);
312  // Compute the contribution to the single scattering integral
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;
316  }
317 }
318 
319 
336 void ComputePrefilteredSingleScatteringCoordinatesNonLinearRectification(out float2 OutRayEndTexCoord,out float OutRayDepth,float3 WorldSpaceViewRayEnd,float4x4 WorldToRectificationSpace,float2 DistanceMinMax,float2 InclinationMinMax,float2 AzimuthMinMax){
337  const float PI=3.1415926535897932384626433832795f;
338  // Compute rectified coordinates for the view ray end in rectification space
339  float4 RectificationSpaceViewRayEnd=mul(float4(WorldSpaceViewRayEnd,1.0f),WorldToRectificationSpace);
340  float Distance,Inclination,Azimuth;
341  CartesianToRectified(Distance,Inclination,Azimuth,RectificationSpaceViewRayEnd.xyz);
342  // Normalize the coordinates
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);
350 }
351 
352 
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;
364  // Get the Fourier coefficients from the textures
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
378  };
379  // Evaluate the first complex basis function
380  float2 Fourier1;
381  sincos(mad(RayDepth,0.5f*PI,0.5f*PI),Fourier1.y,Fourier1.x);
382  // Evaluate the other basis functions using complex exponentiation
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));
390  }
391  // Compute the shadow intensity which is a linear combination of the basis
392  // functions using the Fourier coefficients as weights
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;
398  }
399  OutScatteringIntegral=saturate(1.0f-OutScatteringIntegral);
400  OutScatteringIntegral*=ScatteringIntegralWithoutOcclusion;
401 }
402 
403 
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;
408  // Get the Fourier coefficients from the textures
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
434  };
435  // Evaluate the first complex basis function
436  float2 Fourier1;
437  sincos(mad(RayDepth,0.5f*PI,0.5f*PI),Fourier1.y,Fourier1.x);
438  // Evaluate the other basis functions using complex exponentiation
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));
446  }
447  // Compute the shadow intensity which is a linear combination of the basis
448  // functions using the Fourier coefficients as weights
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;
454  }
455  OutScatteringIntegral=saturate(1.0f-OutScatteringIntegral);
456  OutScatteringIntegral*=ScatteringIntegralWithoutOcclusion;
457 }
458 
459 
474 void ComputeAdaptiveOverestimationWeight(out float OutOverestimationWeight,float3 WorldSpaceViewRayStart,float3 WorldSpaceViewRayEnd,float3 WorldSpaceLightDirection,float2 OverestimationWeightMinMax){
475  // Compute the z-coordinate of the normalized view ray direction in an
476  // orthonormal coordinate system where the light direction corresponds to the
477  // positive z-axis
478  float3 WorldSpaceViewRayDirection=normalize(WorldSpaceViewRayEnd-WorldSpaceViewRayStart);
479  float LightViewZ=dot(WorldSpaceLightDirection,WorldSpaceViewRayDirection);
480  // Interpolate linearly between minimal and maximal overestimation weight using
481  // this z-coordinate
482  float LerpFactor=mad(LightViewZ,0.5f,0.5f);
483  OutOverestimationWeight=saturate(lerp(OverestimationWeightMinMax.x,OverestimationWeightMinMax.y,LerpFactor));
484 }
485 
486 
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);
503  OutScatteringIntegral=1.0f-EstimateIntegralFrom4Moments(RayDepth,OptimizedSample,MomentBias,1.0f-OverestimationWeight);
504  OutScatteringIntegral*=ScatteringIntegralWithoutOcclusion;
505 }
506 
507 
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;
514 }
515 
516 
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;
523 }
524 
525 
538 void GetPrefixSumThreadGroupCount(out uint3 nOutThreadGroup,uint3 ThreadGroupSize,uint nPrefixSumShadowMap,float4 TextureSize){
539  uint Height=(uint)(TextureSize.y);
540  nOutThreadGroup=uint3(1,nPrefixSumShadowMap*Height/ThreadGroupSize.y,1);
541 }
542 
543 
546 void GetShadowMapToRectificationDepthTransform(out float2 OutShadowMapToRectificationDepthTransform,float4x4 RectificationToShadowMapProjectionSpace){
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;
555 }
556 
557 
562 void GetRectifiedDepth(out float OutRectifiedDepth,SSamplerTexturePair2D_float ShadowMapSampler0,float2 RectifiedTexCoord,float4x4 RectificationToShadowMapProjectionSpace,float2 ShadowMapToRectificationDepthTransform,float2 DistanceMinMax,float2 InclinationMinMax,float2 AzimuthMinMax){
563  // Convert the rectified texture coordinate to a non-rectified one
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));
572  // Sample the shadow map
573  float ShadowMapDepth=mad(ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,ShadowMapTexCoord),2.0f,-1.0f);
574  // Convert the linear depth to an inclination
575  float RectificationSpaceDepth=mad(ShadowMapDepth,ShadowMapToRectificationDepthTransform.x,ShadowMapToRectificationDepthTransform.y);
576  float Inclination=atan2(Distance,RectificationSpaceDepth);
577  // Now convert to a rectified depth
578  OutRectifiedDepth=saturate((Inclination-InclinationMinMax.x)/(InclinationMinMax.y-InclinationMinMax.x));
579  OutRectifiedDepth=OutRectifiedDepth*2.0f-1.0f;
580 }
581 
582 
590 void GetSparseRectifiedRepresentation(out float2 OutRectifiedDepth,out float OutDepthWeight1,SSamplerTexturePair2D ShadowMapSampler0,float2 RectifiedTexCoord,float4x4 RectificationToShadowMapProjectionSpace,float2 ShadowMapToRectificationDepthTransform,float2 DistanceMinMax,float2 InclinationMinMax,float2 AzimuthMinMax){
591  // Convert the rectified texture coordinate to a non-rectified one
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));
600  // Sample the moment shadow map and represent its first three moments by two
601  // depth
602  float4 OptimizedMoments=ShadowMapSampler0.Texture.Sample(ShadowMapSampler0.Sampler,ShadowMapTexCoord);
603  float2 ShadowMapDepth;
604  GetSparseRepresentation4Moments(ShadowMapDepth,OutDepthWeight1,OptimizedMoments);
605  // Convert the linear depths to inclinations
606  float2 RectificationSpaceDepth=mad(ShadowMapDepth,ShadowMapToRectificationDepthTransform.x,ShadowMapToRectificationDepthTransform.y);
607  float2 Inclination=float2(
608  atan2(Distance,RectificationSpaceDepth[0]),
609  atan2(Distance,RectificationSpaceDepth[1])
610  );
611  // Now convert them to rectified depths
612  OutRectifiedDepth=saturate((Inclination-InclinationMinMax.x)/(InclinationMinMax.y-InclinationMinMax.x));
613  OutRectifiedDepth=OutRectifiedDepth*2.0f-1.0f;
614 }
615 
616 
618 void GetMomentsFromDepth4(out float4 OutQuantizedMoments0,float RectifiedDepth){
619  ComputeMomentVector4MomentsOptimized(OutQuantizedMoments0,RectifiedDepth);
620 }
621 
624 void GetMomentsFromSparseRectifiedRepresentation4(out float4 OutQuantizedMoments0,float2 RectifiedDepth,float DepthWeight1){
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);
630  }
631  float4 QuantizedMoments0;
632  Convert4MomentCanonicalToOptimized(QuantizedMoments0,lerp(pCanonicalMoments0[0],pCanonicalMoments0[1],DepthWeight1));
633  OutQuantizedMoments0=QuantizedMoments0;
634 }
635 
636 
638 void GetMomentsFromDepth3_3(out float3 OutQuantizedMoments0,out float3 OutQuantizedMoments1,float RectifiedDepth){
639  float2 QuantizedMoments0;
640  float4 QuantizedMoments1;
641  ComputeMomentVector6MomentsOptimized(QuantizedMoments0,QuantizedMoments1,RectifiedDepth);
642  OutQuantizedMoments0=float3(QuantizedMoments0,QuantizedMoments1.x);
643  OutQuantizedMoments1=QuantizedMoments1.yzw;
644 }
645 
649 void GetMomentsFromSparseRectifiedRepresentation3_3(out float3 OutQuantizedMoments0,out float3 OutQuantizedMoments1,float2 RectifiedDepth,float DepthWeight1){
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);
658  }
659  float2 QuantizedMoments0;
660  float4 QuantizedMoments1;
661  Convert6MomentCanonicalToOptimized(QuantizedMoments0,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;
666 }
667 
669 void GetMomentsFromDepth2_4(out float2 OutQuantizedMoments0,out float4 OutQuantizedMoments1,float RectifiedDepth){
670  ComputeMomentVector6MomentsOptimized(OutQuantizedMoments0,OutQuantizedMoments1,RectifiedDepth);
671 }
672 
676 void GetMomentsFromSparseRectifiedRepresentation2_4(out float2 OutQuantizedMoments0,out float4 OutQuantizedMoments1,float2 RectifiedDepth,float DepthWeight1){
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);
685  }
686  Convert6MomentCanonicalToOptimized(OutQuantizedMoments0,OutQuantizedMoments1,
687  lerp(pCanonicalMoments0[0],pCanonicalMoments0[1],DepthWeight1),lerp(pCanonicalMoments1[0],pCanonicalMoments1[1],DepthWeight1));
688 }
689 
690 
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){
694  uint Width,Height;
695  OutFilteredShadowMap0.GetDimensions(Width,Height);
696  float TexelTransmittance=ComputeTexelTransmittance(Width,ExtinctionCoefficient,DistanceMinMax,InclinationMinMax);
697  uint iShadowMap=ThreadID.y/Height;
698  uint iThreadY=ThreadID.y%Height;
699  if(iShadowMap==0){
700  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap0,ShadowMapSampler0.Texture,ThreadID.x,iThreadY,TexelTransmittance);
701  }
702  else if(iShadowMap==1){
703  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap1,ShadowMapSampler1.Texture,ThreadID.x,iThreadY,TexelTransmittance);
704  }
705  else if(iShadowMap==2){
706  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap2,ShadowMapSampler2.Texture,ThreadID.x,iThreadY,TexelTransmittance);
707  }
708  else if(iShadowMap==3){
709  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap3,ShadowMapSampler3.Texture,ThreadID.x,iThreadY,TexelTransmittance);
710  }
711 }
712 
713 
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){
717  uint Width,Height;
718  OutFilteredShadowMap0.GetDimensions(Width,Height);
719  float TexelTransmittance=ComputeTexelTransmittance(Width,ExtinctionCoefficient,DistanceMinMax,InclinationMinMax);
720  uint iShadowMap=ThreadID.y/Height;
721  uint iThreadY=ThreadID.y%Height;
722  if(iShadowMap==0){
723  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap0,ShadowMapSampler0.Texture,ThreadID.x,iThreadY,TexelTransmittance);
724  }
725  else if(iShadowMap==1){
726  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap1,ShadowMapSampler1.Texture,ThreadID.x,iThreadY,TexelTransmittance);
727  }
728  else if(iShadowMap==2){
729  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap2,ShadowMapSampler2.Texture,ThreadID.x,iThreadY,TexelTransmittance);
730  }
731  else if(iShadowMap==3){
732  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap3,ShadowMapSampler3.Texture,ThreadID.x,iThreadY,TexelTransmittance);
733  }
734  else if(iShadowMap==4){
735  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap4,ShadowMapSampler4.Texture,ThreadID.x,iThreadY,TexelTransmittance);
736  }
737  else if(iShadowMap==5){
738  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap5,ShadowMapSampler5.Texture,ThreadID.x,iThreadY,TexelTransmittance);
739  }
740  else if(iShadowMap==6){
741  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap6,ShadowMapSampler6.Texture,ThreadID.x,iThreadY,TexelTransmittance);
742  }
743  else if(iShadowMap==7){
744  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap7,ShadowMapSampler7.Texture,ThreadID.x,iThreadY,TexelTransmittance);
745  }
746 }
747 
748 
764 void ApplyTransmittanceWeightedPrefixSumNonLinearRectificationMSM4(inout RWTexture2D<float4> OutFilteredShadowMap0,SSamplerTexturePair2D ShadowMapSampler0,uint3 ThreadID,float ExtinctionCoefficient,float2 DistanceMinMax,float2 InclinationMinMax){
765  uint Width,Height;
766  OutFilteredShadowMap0.GetDimensions(Width,Height);
767  float TexelTransmittance=ComputeTexelTransmittance(Width,ExtinctionCoefficient,DistanceMinMax,InclinationMinMax);
768  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap0,ShadowMapSampler0.Texture,ThreadID.x,ThreadID.y,TexelTransmittance);
769 }
770 
771 
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){
777  uint Width,Height;
778  OutFilteredShadowMap0.GetDimensions(Width,Height);
779  float TexelTransmittance=ComputeTexelTransmittance(Width,ExtinctionCoefficient,DistanceMinMax,InclinationMinMax);
780  // Different threads handle different textures
781  if(ThreadID.y<Height){
782  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap0,ShadowMapSampler0.Texture,ThreadID.x,ThreadID.y,TexelTransmittance);
783  }
784  else{
785  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap1,ShadowMapSampler1.Texture,ThreadID.x,ThreadID.y-Height,TexelTransmittance);
786  }
787 }
788 
789 
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){
794  uint Width,Height;
795  OutFilteredShadowMap0.GetDimensions(Width,Height);
796  float TexelTransmittance=ComputeTexelTransmittance(Width,ExtinctionCoefficient,DistanceMinMax,InclinationMinMax);
797  // Different threads handle different textures
798  if(ThreadID.y<Height){
799  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap0,ShadowMapSampler0.Texture,ThreadID.x,ThreadID.y,TexelTransmittance);
800  }
801  else{
802  ApplyTransmittanceWeightedPrefixSum(OutFilteredShadowMap1,ShadowMapSampler1.Texture,ThreadID.x,ThreadID.y-Height,TexelTransmittance);
803  }
804 }
void CartesianToRectified(out float OutDistance, out float OutInclination, out float OutAzimuth, float3 CartesianCoordinates)
void ComputeMomentVector6MomentsOptimized(out float2 OutQuantizedMoments0, out float4 OutQuantizedMoments1, float Depth)
void ComputePrefilteredSingleScatteringConvolution8(out float OutScatteringIntegral, float2 RayEndTexCoord, float RayDepth, float ScatteringIntegralWithoutOcclusion, SSamplerTexturePair2D ShadowMapSampler0, SSamplerTexturePair2D ShadowMapSampler1, SSamplerTexturePair2D ShadowMapSampler2, SSamplerTexturePair2D ShadowMapSampler3)
void GetMomentsFromSparseRectifiedRepresentation4(out float4 OutQuantizedMoments0, float2 RectifiedDepth, float DepthWeight1)
void ApplyTransmittanceWeightedPrefixSum(inout RWTexture2D< TEXEL_TYPE > OutFilteredShadowMap, Texture2D< TEXEL_TYPE > FilterableShadowMap, uint iThreadX, uint iThreadY, float TexelTransmittance)
void ComputeSingleScatteringRadiance(out float3 OutScatteringRadiance, float ScatteringIntegral, float3 PhaseTimesAlbedoTimesIrradiance)
void ApplyTransmittanceWeightedPrefixSumNonLinearRectificationMSM2_4(inout RWTexture2D< float2 > OutFilteredShadowMap0, inout RWTexture2D< float4 > OutFilteredShadowMap1, SSamplerTexturePair2D_float2 ShadowMapSampler0, SSamplerTexturePair2D ShadowMapSampler1, uint3 ThreadID, float ExtinctionCoefficient, float2 DistanceMinMax, float2 InclinationMinMax)
void GetMomentsFromSparseRectifiedRepresentation3_3(out float3 OutQuantizedMoments0, out float3 OutQuantizedMoments1, float2 RectifiedDepth, float DepthWeight1)
void ComputePrefilteredSingleScatteringCoordinatesNonLinearRectification(out float2 OutRayEndTexCoord, out float OutRayDepth, float3 WorldSpaceViewRayEnd, float4x4 WorldToRectificationSpace, float2 DistanceMinMax, float2 InclinationMinMax, float2 AzimuthMinMax)
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)
void ComputeAdaptiveOverestimationWeight(out float OutOverestimationWeight, float3 WorldSpaceViewRayStart, float3 WorldSpaceViewRayEnd, float3 WorldSpaceLightDirection, float2 OverestimationWeightMinMax)
void ComputePrefilteredSingleScattering2_4Moments(out float OutScatteringIntegral, float2 RayEndTexCoord, float RayDepth, float ScatteringIntegralWithoutOcclusion, SSamplerTexturePair2D_float2 ShadowMapSampler0, SSamplerTexturePair2D ShadowMapSampler1, float MomentBias, float OverestimationWeight=0.5f)
void ComputeViewRayLengthFromWorldSpace(out float OutViewRayLength, float3 WorldSpacePosition, float3 WorldSpaceCameraPosition)
void ComputeSingleScatteringRayMarchingDirectional(out float OutScatteringIntegral, float ViewRayLength, float3 WorldSpaceViewRayStart, float3 WorldSpaceViewRayEnd, SSamplerTexturePair2D_float ShadowMapSampler, float4x4 ShadowMapWorldToProjectionSpace, float ExtinctionCoefficient, int nSample)
float ComputeTexelTransmittance(uint ShadowMapWidth, float ExtinctionCoefficient, float2 DistanceMinMax, float2 InclinationMinMax)
void ComputeRectificationToWorldSpaceDirectional(out float4x4 OutRectificationToWorldSpace, float3 WorldSpaceCameraPosition, float4x4 ShadowMapViewToWorldSpace)
void GetPrefixSumThreadGroupCount(out uint3 nOutThreadGroup, uint3 ThreadGroupSize, uint nPrefixSumShadowMap, float4 TextureSize)
void GetSparseRectifiedRepresentation(out float2 OutRectifiedDepth, out float OutDepthWeight1, SSamplerTexturePair2D ShadowMapSampler0, float2 RectifiedTexCoord, float4x4 RectificationToShadowMapProjectionSpace, float2 ShadowMapToRectificationDepthTransform, float2 DistanceMinMax, float2 InclinationMinMax, float2 AzimuthMinMax)
void Convert4MomentCanonicalToOptimized(out float4 OutQuantizedMoments0, float4 CanonicalMoments0)
void Convert6MomentCanonicalToOptimized(out float2 OutQuantizedMoments0, out float4 OutQuantizedMoments1, float2 CanonicalMoments0, float4 CanonicalMoments1)
void ComputePrefilteredSingleScattering4Moments(out float OutScatteringIntegral, float2 RayEndTexCoord, float RayDepth, float ScatteringIntegralWithoutOcclusion, SSamplerTexturePair2D ShadowMapSampler0, float MomentBias, float OverestimationWeight=0.5f)
void ComputePrefilteredSingleScattering3_3Moments(out float OutScatteringIntegral, float2 RayEndTexCoord, float RayDepth, float ScatteringIntegralWithoutOcclusion, SSamplerTexturePair2D_float3 ShadowMapSampler0, SSamplerTexturePair2D_float3 ShadowMapSampler1, float MomentBias, float OverestimationWeight=0.5f)
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)
void GetRectifiedDepth(out float OutRectifiedDepth, SSamplerTexturePair2D_float ShadowMapSampler0, float2 RectifiedTexCoord, float4x4 RectificationToShadowMapProjectionSpace, float2 ShadowMapToRectificationDepthTransform, float2 DistanceMinMax, float2 InclinationMinMax, float2 AzimuthMinMax)
void GetMomentsFromDepth3_3(out float3 OutQuantizedMoments0, out float3 OutQuantizedMoments1, float RectifiedDepth)
void ComputeViewRayFromProjectionSpace(out float OutViewRayLength, out float3 OutWorldSpaceRayStart, out float3 OutWorldSpaceRayEnd, float2 TexCoord, float PerspectiveDepth, float4x4 ProjectionToViewSpace, float4x4 ViewToWorldSpace)
void ComputeSingleScatteringFactors(out float3 OutPhaseTimesAlbedoTimesIrradiance, float3 PhaseTimesAlbedo, float3 DirectionalLightIrradiance)
void ComputeMomentVector4MomentsOptimized(out float4 OutQuantizedMoments0, float Depth)
void ComputeSingleScatteringNoOcclusionDirectional(out float OutScatteringIntegral, float ViewRayLength, float ExtinctionCoefficient)
void ComputeScatteringColor(out float4 OutScatteringColor, float3 ScatteringRadiance)
float EstimateIntegralFrom6Moments(float IntervalEnd, float2 OptimizedMoments0, float4 OptimizedMoments1, float MomentBias, float OverestimationWeight)
void GetMomentsFromSparseRectifiedRepresentation2_4(out float2 OutQuantizedMoments0, out float4 OutQuantizedMoments1, float2 RectifiedDepth, float DepthWeight1)
void GetPerspectiveDepth1(out float OutPerspectiveDepth, Texture2DMS< float, 1 > DepthStencilTexture, int2 TexelIndex)
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)
void ApplyAbsorptionToOutgoingRadiance(out float3 OutReceivedRadiance, float3 OutgoingRadiance, float ViewRayLength, float ExtinctionCoefficient)
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)
float EstimateIntegralFrom4Moments(float IntervalEnd, float4 OptimizedMoments, float MomentBias, float OverestimationWeight)
void GetMomentsFromDepth4(out float4 OutQuantizedMoments0, float RectifiedDepth)
void GetShadowMapToRectificationDepthTransform(out float2 OutShadowMapToRectificationDepthTransform, float4x4 RectificationToShadowMapProjectionSpace)
void ComputeExtinctionCoefficient(out float OutExtinctionCoefficient, float HalfOpacityDistance)
void GetMomentsFromDepth2_4(out float2 OutQuantizedMoments0, out float4 OutQuantizedMoments1, float RectifiedDepth)
void GetRectifiedSpaceFrustumBounds(out float2 OutDistanceMinMax, out float2 OutInclinationMinMax, out float2 OutAzimuthMinMax, float4x4 CameraProjectionToWorldSpace, float4x4 CameraWorldToProjectionSpace, float4x4 RectificationToWorldSpace, float4x4 WorldToRectificationSpace)
void GetSparseRepresentation4Moments(out float2 OutDepth, out float OutWeight1, float4 OptimizedMoments)
void ApplyTransmittanceWeightedPrefixSumNonLinearRectificationMSM4(inout RWTexture2D< float4 > OutFilteredShadowMap0, SSamplerTexturePair2D ShadowMapSampler0, uint3 ThreadID, float ExtinctionCoefficient, float2 DistanceMinMax, float2 InclinationMinMax)
float GetRandomNumber(uint Seed)