https://github.com/fschutt/moment-shadow-mapping
Moment shadow mapping walkthrough (description only)
https://github.com/fschutt/moment-shadow-mapping
Last synced: 3 months ago
JSON representation
Moment shadow mapping walkthrough (description only)
- Host: GitHub
- URL: https://github.com/fschutt/moment-shadow-mapping
- Owner: fschutt
- Created: 2018-03-19T07:49:29.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2018-03-19T07:51:50.000Z (over 8 years ago)
- Last Synced: 2025-10-14T07:18:21.608Z (8 months ago)
- Size: 5.86 KB
- Stars: 29
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Moment shadow mapping
- Idea: Store various exponentials of the depth in a texture,
and apply a gaussian blur to each one of them. Then recombine
them back together.
- Goal: prevent light leaking + shadow acne by using not one, but four
exponents of the depth, combined in various ways
- RGBA texture = 4 channels for storing the z-depth from the lights POV:
- See https://www.gdcvault.com/play/1023808/Rendering-Antialiased-Shadows-with-Moment
```
R: ((-3/2) * z) + (2 * (z ^ 3)) + (1/2)
G: 4 * ((z ^ 2) - (z ^ 4))
B: (sqrt(3) * (((1/2) * z) - ((2/9) * z ^ 3))) + (1/2)
A: (1/2) * ((z ^ 2) + (z ^ 4))
```
# Implementation
1. Render the scene from the lights view to a multisampled depth buffer (do multisampling here)
2. Compute the RGBA texture (R16G16B16A16 normalized uint, 1024², no mipmaps):
```
R = [[ 1.5 ], [ 0.0 ], [ -2.0 ], [ 0.0 ]] * [ z ] + [0.5]
G = [[ 0.0 ], [ 4.0 ], [ 0.0 ], [ -4.0 ]] * [z^2] + [0.0]
B = [[ sqrt(3)/2 ], [ 0.0 ], [-sqrt(12)/9], [ 0.0 ]] * [z^3] + [0.5]
A = [[ 0.0 ], [ 0.5 ], [ 0.0 ], [ 0.5 ]] * [z^4] + [0.0]
```
3. 2-pass gaussian filter over the RGBA texture
4. In view-space, shade the final pixel by sampling the RGBA texture and reversing the matrix:
```
b.x = [[ -(1/3) ], [ 0.0 ], [ sqrt(3) ], [ 0.0 ]] * [[r] - [0.5]]
b.y = [[ 0.0 ], [ 0.125 ], [ 0.0 ], [ 1.0 ]] * [[g] - [0.0]]
b.z = [[ -0.75 ], [ 0.0 ], [0.75 * sqrt(3)], [ 0.0 ]] * [[b] - [0.5]]
b.w = [[ 0.0 ], [ -0.125 ], [ 0.0 ], [ 1.0 ]] * [[a] - [0.0]]
```
5. Invalidate rounding errors by multiplying:
```
a = 0.15;
// a = 6 ⋅ pow(10, −5); // 4 * 16 bit ???
b' = 1.0 − (a ⋅ b) + (a ⋅ pow(vec4(0.0, 0.63, 0.0, 0.63), T))
```
6. Put the final b value through the following function
Original HLSL:
```hlsl
float ComputeMSMShadowIntensity(float4 b,float FragmentDepth) {
float L32D22=mad(-b[0],b[1],b[2]);
float D22=mad(-b[0],b[0], b[1]);
float SquaredDepthVariance=mad(-b[1],b[1], b[3]);
float D33D22=dot(float2(SquaredDepthVariance,-L32D22), float2(D22, L32D22));
float InvD22=1.0f/D22;
float L32=L32D22*InvD22;
float3 z;
z[0]=FragmentDepth;
float3 c=float3(1.0f,z[0],z[0]*z[0]);
c[1]-=b.x;
c[2]-=b.y+L32*c[1];
c[1]*=InvD22;
c[2]*=D22/D33D22;
c[1]-=L32*c[2];
c[0]-=dot(c.yz,b.xy);
float InvC2=1.0f/c[2];
float p=c[1]*InvC2;
float q=c[0]*InvC2;
float r=sqrt((p*p*0.25f)-q);
z[1]=-p*0.5f-r;
z[2]=-p*0.5f+r;
float4 Switch=
(z[2]