@@ -26,7 +26,7 @@ float sampleNoPCF(sampler2DArray shadow_map, float shadowDepth, int cascade, vec
2626 return computeShadowFactor(shadowDepth, sampleShadowMap(shadow_map, shadowUV[cascade].xy, vec2(0.0, 0.0), cascade, 1.0/1024.0), 0.05);
2727}
2828
29- float samplePoissonPCF(sampler2DArray shadow_map, float shadowDepth, int cascade, vec4 shadowUV[4], bool use_simple_pass )
29+ float samplePoissonPCF(sampler2DArray shadow_map, float shadowDepth, int cascade, vec4 shadowUV[4], bool cockpit_shadow_bias )
3030{
3131 if(cascade > 3 || cascade < 0) return 1.0;
3232
@@ -55,30 +55,16 @@ float samplePoissonPCF(sampler2DArray shadow_map, float shadowDepth, int cascade
5555 maxUVOffset[2] = 1.0/200.0;
5656 maxUVOffset[3] = 1.0/200.0;
5757
58- if (use_simple_pass) {
59- // internal cockpit shadows
60- // bias is a bit smaller to pick up on close/sharp cockpit geometry
61- // favors shadow over light to avoid complex geometry halos
62- float visibility = 1.0f;
63- for (int i=0; i<16; i++) {
64- vec2 shadow_sample = sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[i], cascade, maxUVOffset[cascade]);
65- // extra bias value tuned for this distance
66- if( ((shadow_sample.x - 0.002f) > shadowDepth) ) {
67- visibility -= (1.0f/16.0f);
68- }
69- }
70- return visibility;
71- } else {
72- // default external shadows
73- // bias is a bit larger to only pick up larger geometry
74- // favors light over shadow to avoid flickering/spotty shadows
75- vec2 sum = vec2(0.0f);
76- for (int i=0; i<16; i++) {
77- sum += sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[i], cascade, maxUVOffset[cascade]);
78- }
79- return computeShadowFactor(shadowDepth, sum*(1.0f/16.0f), 0.1f);
58+ // default external shadows
59+ // bias is a bit larger to only pick up larger geometry
60+ // favors light over shadow to avoid flickering/spotty shadows
61+ // compute Chebyshev per-sample to avoid halos from moment-averaging at occluder edges
62+ float visibility = 0.0f;
63+ for (int i=0; i<16; i++) {
64+ vec2 shadow_sample = sampleShadowMap(shadow_map, shadowUV[cascade].xy, poissonDisc[i], cascade, maxUVOffset[cascade]);
65+ visibility += computeShadowFactor(shadowDepth, shadow_sample, cockpit_shadow_bias ? 0.01f : 0.1f);
8066 }
81-
67+ return visibility * (1.0f/16.0f);
8268}
8369
8470float getShadowValue(sampler2DArray shadow_map, float depth, float shadowDepth, vec4 shadowUV[4], float fardist,
@@ -98,19 +84,19 @@ float getShadowValue(sampler2DArray shadow_map, float depth, float shadowDepth,
9884 cascade_start_dist[4] = fardist;
9985 if(cascade > 3 || cascade < 0) return 1.0;
10086
101- bool use_simple_pass ;
87+ bool cockpit_shadow_bias ;
10288 if (fardist < 50.0f) {
10389 // internal cockpit shadows
104- use_simple_pass = true;
90+ cockpit_shadow_bias = true;
10591 } else {
10692 // default external shadows
107- use_simple_pass = false;
93+ cockpit_shadow_bias = false;
10894 }
10995
11096 float dist_threshold = (cascade_start_dist[cascade+1] - cascade_start_dist[cascade])*0.2;
11197 if(cascade_start_dist[cascade+1] - dist_threshold > depth)
112- return samplePoissonPCF(shadow_map, shadowDepth, cascade, shadowUV, use_simple_pass );
113- return mix(samplePoissonPCF(shadow_map, shadowDepth, cascade, shadowUV, use_simple_pass ), samplePoissonPCF(shadow_map, shadowDepth, cascade+1, shadowUV, use_simple_pass ),
98+ return samplePoissonPCF(shadow_map, shadowDepth, cascade, shadowUV, cockpit_shadow_bias );
99+ return mix(samplePoissonPCF(shadow_map, shadowDepth, cascade, shadowUV, cockpit_shadow_bias ), samplePoissonPCF(shadow_map, shadowDepth, cascade+1, shadowUV, cockpit_shadow_bias ),
114100 smoothstep(cascade_start_dist[cascade+1] - dist_threshold, cascade_start_dist[cascade+1], depth));
115101}
116102
0 commit comments