Просмотр исходного кода

Merge pull request #7414 from Popov72/csm-optim-blendcascade

CSM speed optimization when cascade blending is not used
sebavan 5 лет назад
Родитель
Сommit
ad6b58d327

+ 3 - 2
dist/preview release/what's new.md

@@ -16,7 +16,7 @@
 - Added support for Offscreen canvas [Doc](https://doc.babylonjs.com/how_to/using_offscreen_canvas) ([Deltakosh](https://github.com/deltakosh/)
 - Added support for multiple canvases with one engine [Doc](https://doc.babylonjs.com/how_to/multi_canvases) ([Deltakosh](https://github.com/deltakosh/)
 - Added useReverseDepthBuffer to Engine which can provide greater z depth for distant objects without the cost of a logarithmic depth buffer ([BenAdams](https://github.com/benaadams/))
-- Added the "Cascaded Shadow Mapping" (CSM) shadow rendering technic ([Popov72](https://github.com/Popov72) (initiated by [lockphase](https://github.com/lockphase/)))
+- Added the "Cascaded Shadow Mapping" (CSM) shadow rendering technique ([Popov72](https://github.com/Popov72) (initiated by [lockphase](https://github.com/lockphase/)))
 
 ## Updates
 
@@ -54,7 +54,8 @@
 - Device orientation event permissions for iOS 13+ ([RaananW](https://github.com/RaananW/))
 - Added `DirectionalLight.autoCalcShadowZBounds` to automatically compute the `shadowMinZ` and `shadowMaxZ` values ([Popov72](https://github.com/Popov72))
 - Added `CascadedShadowGenerator.autoCalcDepthBounds` to improve the shadow quality rendering ([Popov72](https://github.com/Popov72))
-- Improved cascade blending in CSM shadow technic ([Popov72](https://github.com/Popov72))
+- Improved cascade blending in CSM shadow technique ([Popov72](https://github.com/Popov72))
+- Speed optimization when cascade blending is not used in CSM shadow technique ([Popov72](https://github.com/Popov72))
 
 ### Engine
 

+ 15 - 1
src/Lights/Shadows/cascadedShadowGenerator.ts

@@ -628,6 +628,7 @@ export class CascadedShadowGenerator implements IShadowGenerator {
             return;
         }
         this._shadowMaxZ = value;
+        this._light._markMeshesAsLightDirty();
         this._breaksAreDirty = true;
     }
 
@@ -664,11 +665,20 @@ export class CascadedShadowGenerator implements IShadowGenerator {
         this._depthClamp = value;
     }
 
+    private _cascadeBlendPercentage: number = 0.1;
+
     /**
      * Gets or sets the percentage of blending between two cascades (value between 0. and 1.).
      * It defaults to 0.1 (10% blending).
      */
-    public cascadeBlendPercentage: number = 0.1;
+    public get cascadeBlendPercentage(): number {
+        return this._cascadeBlendPercentage;
+    }
+
+    public set cascadeBlendPercentage(value: number) {
+        this._cascadeBlendPercentage = value;
+        this._light._markMeshesAsLightDirty();
+    }
 
     private _lambda = 0.5;
 
@@ -1506,6 +1516,10 @@ export class CascadedShadowGenerator implements IShadowGenerator {
             defines["SHADOWCSMUSESHADOWMAXZ" + lightIndex] = true;
         }
 
+        if (this.cascadeBlendPercentage === 0) {
+            defines["SHADOWCSMNOBLEND" + lightIndex] = true;
+        }
+
         if (this.useContactHardeningShadow) {
             defines["SHADOWPCSS" + lightIndex] = true;
             if (this._filteringQuality === CascadedShadowGenerator.QUALITY_LOW) {

+ 2 - 0
src/Materials/materialHelper.ts

@@ -347,6 +347,7 @@ export class MaterialHelper {
         defines["SHADOWCSMDEBUG" + lightIndex] = false;
         defines["SHADOWCSMNUM_CASCADES" + lightIndex] = false;
         defines["SHADOWCSMUSESHADOWMAXZ" + lightIndex] = false;
+        defines["SHADOWCSMNOBLEND" + lightIndex] = false;
         defines["SHADOWPCF" + lightIndex] = false;
         defines["SHADOWPCSS" + lightIndex] = false;
         defines["SHADOWPOISSON" + lightIndex] = false;
@@ -429,6 +430,7 @@ export class MaterialHelper {
                 defines["SHADOWCSMDEBUG" + index] = false;
                 defines["SHADOWCSMNUM_CASCADES" + index] = false;
                 defines["SHADOWCSMUSESHADOWMAXZ" + index] = false;
+                defines["SHADOWCSMNOBLEND" + index] = false;
                 defines["SHADOWPCF" + index] = false;
                 defines["SHADOWPCSS" + index] = false;
                 defines["SHADOWPOISSON" + index] = false;

+ 30 - 28
src/Shaders/ShadersInclude/lightFragment.fx

@@ -139,7 +139,6 @@
             if (index{X} >= 0)
             #endif
             {
-                float frustumLength = frustumLengths{X}[index{X}];
                 #if defined(SHADOWPCF{X})
                     #if defined(SHADOWLOWQUALITY{X})
                         shadow = computeShadowWithCSMPCF1(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
@@ -164,36 +163,39 @@
                     shadowDebug{X} = vec3(shadow) * vCascadeColorsMultiplier{X}[index{X}];
                 #endif
 
-                float diffRatio = clamp(diff{X} / frustumLength, 0., 1.) * cascadeBlendFactor{X};
-                if (index{X} < (SHADOWCSMNUM_CASCADES{X} - 1) && diffRatio < 1.)
-                {
-                    index{X} += 1;
-                    float nextShadow = 0.;
-                    #if defined(SHADOWPCF{X})
-                        #if defined(SHADOWLOWQUALITY{X})
-                            nextShadow = computeShadowWithCSMPCF1(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
-                        #elif defined(SHADOWMEDIUMQUALITY{X})
-                            nextShadow = computeShadowWithCSMPCF3(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.yz, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                #ifndef SHADOWCSMNOBLEND{X}
+                    float frustumLength = frustumLengths{X}[index{X}];
+                    float diffRatio = clamp(diff{X} / frustumLength, 0., 1.) * cascadeBlendFactor{X};
+                    if (index{X} < (SHADOWCSMNUM_CASCADES{X} - 1) && diffRatio < 1.)
+                    {
+                        index{X} += 1;
+                        float nextShadow = 0.;
+                        #if defined(SHADOWPCF{X})
+                            #if defined(SHADOWLOWQUALITY{X})
+                                nextShadow = computeShadowWithCSMPCF1(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                            #elif defined(SHADOWMEDIUMQUALITY{X})
+                                nextShadow = computeShadowWithCSMPCF3(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.yz, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                            #else
+                                nextShadow = computeShadowWithCSMPCF5(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.yz, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                            #endif
+                        #elif defined(SHADOWPCSS{X})
+                            #if defined(SHADOWLOWQUALITY{X})
+                                nextShadow = computeShadowWithCSMPCSS16(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                            #elif defined(SHADOWMEDIUMQUALITY{X})
+                                nextShadow = computeShadowWithCSMPCSS32(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                            #else
+                                nextShadow = computeShadowWithCSMPCSS64(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                            #endif
                         #else
-                            nextShadow = computeShadowWithCSMPCF5(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.yz, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                            nextShadow = computeShadowCSM(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
                         #endif
-                    #elif defined(SHADOWPCSS{X})
-                        #if defined(SHADOWLOWQUALITY{X})
-                            nextShadow = computeShadowWithCSMPCSS16(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
-                        #elif defined(SHADOWMEDIUMQUALITY{X})
-                            nextShadow = computeShadowWithCSMPCSS32(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
-                        #else
-                            nextShadow = computeShadowWithCSMPCSS64(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
-                        #endif
-                    #else
-                        nextShadow = computeShadowCSM(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
-                    #endif
 
-                    shadow = mix(nextShadow, shadow, diffRatio);
-                    #ifdef SHADOWCSMDEBUG{X}
-                        shadowDebug{X} = mix(vec3(nextShadow) * vCascadeColorsMultiplier{X}[index{X}], shadowDebug{X}, diffRatio);
-                    #endif
-                }
+                        shadow = mix(nextShadow, shadow, diffRatio);
+                        #ifdef SHADOWCSMDEBUG{X}
+                            shadowDebug{X} = mix(vec3(nextShadow) * vCascadeColorsMultiplier{X}[index{X}], shadowDebug{X}, diffRatio);
+                        #endif
+                    }
+                #endif
             }
         #elif defined(SHADOWCLOSEESM{X})
             #if defined(SHADOWCUBE{X})