瀏覽代碼

New option for soft shadows.

David Catuhe 10 年之前
父節點
當前提交
db3708b841

+ 43 - 10
Babylon/Lights/Shadows/babylon.shadowGenerator.js

@@ -5,9 +5,10 @@ var BABYLON;
             var _this = this;
             // Members
             this.filter = ShadowGenerator.FILTER_NONE;
-            this.blurSize = 2;
+            this.blurScale = 2;
+            this._blurBoxOffset = 0;
             this._darkness = 0;
-            this._bias = 0.0001;
+            this._bias = 0.00005;
             this._transparencyShadow = false;
             this._viewMatrix = BABYLON.Matrix.Zero();
             this._projectionMatrix = BABYLON.Matrix.Zero();
@@ -15,6 +16,7 @@ var BABYLON;
             this._worldViewProjection = BABYLON.Matrix.Zero();
             this._light = light;
             this._scene = light.getScene();
+            this._mapSize = mapSize;
             light._shadowGenerator = this;
             // Render target
             this._shadowMap = new BABYLON.RenderTargetTexture(light.name + "_shadowMap", mapSize, this._scene, false);
@@ -22,21 +24,18 @@ var BABYLON;
             this._shadowMap.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
             this._shadowMap.renderParticles = false;
             this._shadowMap.onAfterUnbind = function () {
-                if (_this.filter !== ShadowGenerator.FILTER_BLURVARIANCESHADOWMAP) {
+                if (!_this.useBlurVarianceShadowMap) {
                     return;
                 }
                 if (!_this._shadowMap2) {
                     _this._shadowMap2 = new BABYLON.RenderTargetTexture(light.name + "_shadowMap", mapSize, _this._scene, false);
                     _this._shadowMap2.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
                     _this._shadowMap2.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
-                    _this._downSamplePostprocess = new BABYLON.PassPostProcess("downScale", 1.0 / _this.blurSize, null, BABYLON.Texture.NEAREST_SAMPLINGMODE, _this._scene.getEngine());
+                    _this._downSamplePostprocess = new BABYLON.PassPostProcess("downScale", 1.0 / _this.blurScale, null, BABYLON.Texture.NEAREST_SAMPLINGMODE, _this._scene.getEngine());
                     _this._downSamplePostprocess.onApply = function (effect) {
                         effect.setTexture("textureSampler", _this._shadowMap);
                     };
-                    _this._boxBlurPostprocess = new BABYLON.PostProcess("DepthBoxBlur", "depthBoxBlur", ["screenSize"], [], 1.0 / _this.blurSize, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, _this._scene.getEngine());
-                    _this._boxBlurPostprocess.onApply = function (effect) {
-                        effect.setFloat2("screenSize", mapSize / _this.blurSize, mapSize / _this.blurSize);
-                    };
+                    _this.blurBoxOffset = 1;
                 }
                 _this._scene.postProcessManager.directRender([_this._downSamplePostprocess, _this._boxBlurPostprocess], _this._shadowMap2.getInternalTexture());
             };
@@ -90,6 +89,14 @@ var BABYLON;
                     }
                 }
             };
+            this._shadowMap.onClear = function (engine) {
+                if (_this.useBlurVarianceShadowMap || _this.useVarianceShadowMap) {
+                    engine.clear(new BABYLON.Color4(0, 0, 0, 0), true, true);
+                }
+                else {
+                    engine.clear(new BABYLON.Color4(1.0, 1.0, 1.0, 1.0), true, true);
+                }
+            };
         }
         Object.defineProperty(ShadowGenerator, "FILTER_NONE", {
             // Static
@@ -120,6 +127,27 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(ShadowGenerator.prototype, "blurBoxOffset", {
+            get: function () {
+                return this._blurBoxOffset;
+            },
+            set: function (value) {
+                var _this = this;
+                if (this._blurBoxOffset === value) {
+                    return;
+                }
+                this._blurBoxOffset = value;
+                if (this._boxBlurPostprocess) {
+                    this._boxBlurPostprocess.dispose();
+                }
+                this._boxBlurPostprocess = new BABYLON.PostProcess("DepthBoxBlur", "depthBoxBlur", ["screenSize", "boxOffset"], [], 1.0 / this.blurScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define OFFSET " + value);
+                this._boxBlurPostprocess.onApply = function (effect) {
+                    effect.setFloat2("screenSize", _this._mapSize / _this.blurScale, _this._mapSize / _this.blurScale);
+                };
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(ShadowGenerator.prototype, "useVarianceShadowMap", {
             get: function () {
                 return this.filter === ShadowGenerator.FILTER_VARIANCESHADOWMAP && this._light.supportsVSM();
@@ -132,7 +160,7 @@ var BABYLON;
         });
         Object.defineProperty(ShadowGenerator.prototype, "usePoissonSampling", {
             get: function () {
-                return this.filter === ShadowGenerator.FILTER_POISSONSAMPLING;
+                return this.filter === ShadowGenerator.FILTER_POISSONSAMPLING || (!this._light.supportsVSM() && (this.filter === ShadowGenerator.FILTER_VARIANCESHADOWMAP || this.filter === ShadowGenerator.FILTER_BLURVARIANCESHADOWMAP));
             },
             set: function (value) {
                 this.filter = (value ? ShadowGenerator.FILTER_POISSONSAMPLING : ShadowGenerator.FILTER_NONE);
@@ -221,7 +249,7 @@ var BABYLON;
                 this._cachedPosition = lightPosition.clone();
                 this._cachedDirection = lightDirection.clone();
                 BABYLON.Matrix.LookAtLHToRef(lightPosition, this._light.position.add(lightDirection), BABYLON.Vector3.Up(), this._viewMatrix);
-                this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, this.getShadowMap().renderList, this.filter === ShadowGenerator.FILTER_VARIANCESHADOWMAP || this.filter === ShadowGenerator.FILTER_BLURVARIANCESHADOWMAP);
+                this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, this.getShadowMap().renderList);
                 this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
             }
             return this._transformMatrix;
@@ -246,6 +274,11 @@ var BABYLON;
         ShadowGenerator.prototype.setTransparencyShadow = function (hasShadow) {
             this._transparencyShadow = hasShadow;
         };
+        ShadowGenerator.prototype._packHalf = function (depth) {
+            var scale = depth * 255.0;
+            var fract = scale - Math.floor(scale);
+            return new BABYLON.Vector2(depth - fract / 255.0, fract);
+        };
         ShadowGenerator.prototype.dispose = function () {
             this._shadowMap.dispose();
             if (this._shadowMap2) {

+ 50 - 10
Babylon/Lights/Shadows/babylon.shadowGenerator.ts

@@ -24,7 +24,29 @@
 
         // Members
         public filter = ShadowGenerator.FILTER_NONE;
-        public blurSize = 2;
+        public blurScale = 2;
+        private _blurBoxOffset = 0;
+
+        public get blurBoxOffset(): number {
+            return this._blurBoxOffset;
+        }
+
+        public set blurBoxOffset(value:number) {
+            if (this._blurBoxOffset === value) {
+                return;
+            }
+
+            this._blurBoxOffset = value;
+
+            if (this._boxBlurPostprocess) {
+                this._boxBlurPostprocess.dispose();
+            }
+
+            this._boxBlurPostprocess = new PostProcess("DepthBoxBlur", "depthBoxBlur", ["screenSize", "boxOffset"], [], 1.0 / this.blurScale, null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define OFFSET " + value);
+            this._boxBlurPostprocess.onApply = effect => {
+                effect.setFloat2("screenSize", this._mapSize / this.blurScale, this._mapSize / this.blurScale);
+            };
+        }
 
         public get useVarianceShadowMap(): boolean {
             return this.filter === ShadowGenerator.FILTER_VARIANCESHADOWMAP && this._light.supportsVSM();
@@ -34,7 +56,11 @@
         }
 
         public get usePoissonSampling(): boolean {
-            return this.filter === ShadowGenerator.FILTER_POISSONSAMPLING;
+            return this.filter === ShadowGenerator.FILTER_POISSONSAMPLING ||
+                (!this._light.supportsVSM() && (
+                    this.filter === ShadowGenerator.FILTER_VARIANCESHADOWMAP ||
+                    this.filter === ShadowGenerator.FILTER_BLURVARIANCESHADOWMAP
+                ));
         }
         public set usePoissonSampling(value: boolean) {
             this.filter = (value ? ShadowGenerator.FILTER_POISSONSAMPLING : ShadowGenerator.FILTER_NONE);
@@ -52,7 +78,7 @@
         private _shadowMap: RenderTargetTexture;
         private _shadowMap2: RenderTargetTexture;
         private _darkness = 0;
-        private _bias = 0.0001;
+        private _bias = 0.00005;
         private _transparencyShadow = false;
         private _effect: Effect;
 
@@ -66,10 +92,12 @@
         private _currentRenderID: number;
         private _downSamplePostprocess: PassPostProcess;
         private _boxBlurPostprocess: PostProcess;
+        private _mapSize: number;
 
         constructor(mapSize: number, light: IShadowLight) {
             this._light = light;
             this._scene = light.getScene();
+            this._mapSize = mapSize;
 
             light._shadowGenerator = this;
 
@@ -80,7 +108,7 @@
             this._shadowMap.renderParticles = false;
 
             this._shadowMap.onAfterUnbind = () => {
-                if (this.filter !== ShadowGenerator.FILTER_BLURVARIANCESHADOWMAP) {
+                if (!this.useBlurVarianceShadowMap) {
                     return;
                 }
 
@@ -89,14 +117,12 @@
                     this._shadowMap2.wrapU = Texture.CLAMP_ADDRESSMODE;
                     this._shadowMap2.wrapV = Texture.CLAMP_ADDRESSMODE;
                     
-                    this._downSamplePostprocess = new PassPostProcess("downScale", 1.0 / this.blurSize, null, Texture.NEAREST_SAMPLINGMODE, this._scene.getEngine());
+                    this._downSamplePostprocess = new PassPostProcess("downScale", 1.0 / this.blurScale, null, Texture.NEAREST_SAMPLINGMODE, this._scene.getEngine());
                     this._downSamplePostprocess.onApply = effect => {
                         effect.setTexture("textureSampler", this._shadowMap);
                     };
-                    this._boxBlurPostprocess = new PostProcess("DepthBoxBlur", "depthBoxBlur", ["screenSize"], [], 1.0 / this.blurSize, null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine());
-                    this._boxBlurPostprocess.onApply = effect => {
-                        effect.setFloat2("screenSize", mapSize / this.blurSize, mapSize / this.blurSize);
-                    };
+
+                    this.blurBoxOffset = 1;
                 }
 
                 this._scene.postProcessManager.directRender([this._downSamplePostprocess, this._boxBlurPostprocess], this._shadowMap2.getInternalTexture());
@@ -166,6 +192,13 @@
                 }
             };
 
+            this._shadowMap.onClear = (engine: Engine) => {
+                if (this.useBlurVarianceShadowMap || this.useVarianceShadowMap) {
+                    engine.clear(new Color4(0, 0, 0, 0), true, true);
+                } else {
+                    engine.clear(new Color4(1.0, 1.0, 1.0, 1.0), true, true);
+                }
+            }
         }
 
         public isReady(subMesh: SubMesh, useInstances: boolean): boolean {
@@ -262,7 +295,7 @@
 
                 Matrix.LookAtLHToRef(lightPosition, this._light.position.add(lightDirection), Vector3.Up(), this._viewMatrix);
 
-                this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, this.getShadowMap().renderList, this.filter === ShadowGenerator.FILTER_VARIANCESHADOWMAP || this.filter === ShadowGenerator.FILTER_BLURVARIANCESHADOWMAP);
+                this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, this.getShadowMap().renderList);
 
                 this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
             }
@@ -295,6 +328,13 @@
             this._transparencyShadow = hasShadow;
         }
 
+        private _packHalf(depth: number): Vector2 { 
+            var scale = depth * 255.0;
+            var fract = scale - Math.floor(scale);
+
+            return new Vector2(depth - fract / 255.0, fract);
+        }
+
         public dispose(): void {
             this._shadowMap.dispose();
 

+ 5 - 16
Babylon/Lights/babylon.directionalLight.js

@@ -11,8 +11,7 @@ var BABYLON;
         function DirectionalLight(name, direction, scene) {
             _super.call(this, name, scene);
             this.direction = direction;
-            this.shadowOrthoScale = 1.1;
-            this.shadowOrthoDepthScale = 3;
+            this.shadowOrthoScale = 0.1;
             this.position = direction.scale(-1);
         }
         DirectionalLight.prototype.getAbsolutePosition = function () {
@@ -22,13 +21,11 @@ var BABYLON;
             this.direction = BABYLON.Vector3.Normalize(target.subtract(this.position));
             return this.direction;
         };
-        DirectionalLight.prototype.setShadowProjectionMatrix = function (matrix, viewMatrix, renderList, useVSM) {
+        DirectionalLight.prototype.setShadowProjectionMatrix = function (matrix, viewMatrix, renderList) {
             var orthoLeft = Number.MAX_VALUE;
             var orthoRight = Number.MIN_VALUE;
             var orthoTop = Number.MIN_VALUE;
             var orthoBottom = Number.MAX_VALUE;
-            var orthoNear = Number.MAX_VALUE;
-            var orthoFar = Number.MIN_VALUE;
             var tempVector3 = BABYLON.Vector3.Zero();
             var activeCamera = this.getScene().activeCamera;
             for (var meshIndex = 0; meshIndex < renderList.length; meshIndex++) {
@@ -43,19 +40,11 @@ var BABYLON;
                         orthoRight = tempVector3.x;
                     if (tempVector3.y > orthoTop)
                         orthoTop = tempVector3.y;
-                    if (tempVector3.z < orthoNear)
-                        orthoNear = tempVector3.z;
-                    if (tempVector3.z > orthoFar)
-                        orthoFar = tempVector3.z;
                 }
             }
-            var orthoWidth = Math.max(Math.abs(orthoRight), Math.abs(orthoLeft)) * this.shadowOrthoScale;
-            var orthoHeight = Math.max(Math.abs(orthoTop), Math.abs(orthoBottom)) * this.shadowOrthoScale;
-            var orthoDepth = Math.max(Math.abs(orthoNear), Math.abs(orthoFar)) * this.shadowOrthoDepthScale;
-            BABYLON.Matrix.OrthoOffCenterLHToRef(-orthoWidth, orthoWidth, -orthoHeight, orthoHeight, useVSM ? -orthoDepth : activeCamera.minZ, orthoDepth, matrix);
-        };
-        DirectionalLight.prototype.getVSMOffset = function () {
-            return 0.55;
+            var xOffset = orthoRight - orthoLeft;
+            var yOffset = orthoTop - orthoBottom;
+            BABYLON.Matrix.OrthoOffCenterLHToRef(orthoLeft - xOffset * this.shadowOrthoScale, orthoRight + xOffset * this.shadowOrthoScale, orthoBottom - yOffset * this.shadowOrthoScale, orthoTop + yOffset * this.shadowOrthoScale, -activeCamera.maxZ, activeCamera.maxZ, matrix);
         };
         DirectionalLight.prototype.supportsVSM = function () {
             return true;

+ 8 - 19
Babylon/Lights/babylon.directionalLight.ts

@@ -6,8 +6,7 @@
         public transformedPosition: Vector3;
         private _worldMatrix: Matrix;
 
-        public shadowOrthoScale = 1.1;
-        public shadowOrthoDepthScale = 3;
+        public shadowOrthoScale = 0.1;
 
         constructor(name: string, public direction: Vector3, scene: Scene) {
             super(name, scene);
@@ -24,13 +23,11 @@
             return this.direction;
         }
 
-        public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>, useVSM: boolean): void {
+        public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void {
             var orthoLeft = Number.MAX_VALUE;
             var orthoRight = Number.MIN_VALUE;
             var orthoTop = Number.MIN_VALUE;
             var orthoBottom = Number.MAX_VALUE;
-            var orthoNear = Number.MAX_VALUE;
-            var orthoFar = Number.MIN_VALUE;
 
             var tempVector3 = Vector3.Zero();
 
@@ -52,25 +49,17 @@
                         orthoRight = tempVector3.x;
                     if (tempVector3.y > orthoTop)
                         orthoTop = tempVector3.y;
-
-                    if (tempVector3.z < orthoNear)
-                        orthoNear = tempVector3.z;
-                    if (tempVector3.z > orthoFar)
-                        orthoFar = tempVector3.z;
                 }
             }
 
-            var orthoWidth = Math.max(Math.abs(orthoRight), Math.abs(orthoLeft)) * this.shadowOrthoScale;
-            var orthoHeight = Math.max(Math.abs(orthoTop), Math.abs(orthoBottom)) * this.shadowOrthoScale;
-            var orthoDepth = Math.max(Math.abs(orthoNear), Math.abs(orthoFar)) * this.shadowOrthoDepthScale;
-
-            Matrix.OrthoOffCenterLHToRef(-orthoWidth, orthoWidth, -orthoHeight, orthoHeight, useVSM ? -orthoDepth : activeCamera.minZ, orthoDepth, matrix);
-        }
+            var xOffset = orthoRight - orthoLeft;
+            var yOffset = orthoTop - orthoBottom;
 
-        public getVSMOffset(): number {
-            return 0.55;
+            Matrix.OrthoOffCenterLHToRef(   orthoLeft - xOffset * this.shadowOrthoScale, orthoRight + xOffset * this.shadowOrthoScale,
+                                            orthoBottom - yOffset * this.shadowOrthoScale, orthoTop + yOffset * this.shadowOrthoScale,
+                                            -activeCamera.maxZ, activeCamera.maxZ, matrix);
         }
-
+        
         public supportsVSM(): boolean {
             return true;
         }

+ 1 - 2
Babylon/Lights/babylon.light.ts

@@ -9,9 +9,8 @@
         computeTransformedPosition(): boolean;
         getScene(): Scene;
 
-        setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>, useVSM: boolean): void;
+        setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void;
 
-        getVSMOffset(): number;
         supportsVSM(): boolean;
         needRefreshPerFrame(): boolean;
 

+ 1 - 4
Babylon/Lights/babylon.spotLight.js

@@ -18,13 +18,10 @@ var BABYLON;
         SpotLight.prototype.getAbsolutePosition = function () {
             return this.transformedPosition ? this.transformedPosition : this.position;
         };
-        SpotLight.prototype.setShadowProjectionMatrix = function (matrix, viewMatrix, renderList, useVSM) {
+        SpotLight.prototype.setShadowProjectionMatrix = function (matrix, viewMatrix, renderList) {
             var activeCamera = this.getScene().activeCamera;
             BABYLON.Matrix.PerspectiveFovLHToRef(this.angle, 1.0, activeCamera.minZ, activeCamera.maxZ, matrix);
         };
-        SpotLight.prototype.getVSMOffset = function () {
-            return 0.2;
-        };
         SpotLight.prototype.supportsVSM = function () {
             return true;
         };

+ 1 - 4
Babylon/Lights/babylon.spotLight.ts

@@ -14,14 +14,11 @@
             return this.transformedPosition ? this.transformedPosition : this.position;
         }
 
-        public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>, useVSM: boolean): void {
+        public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void {
             var activeCamera = this.getScene().activeCamera;
             Matrix.PerspectiveFovLHToRef(this.angle, 1.0, activeCamera.minZ, activeCamera.maxZ, matrix);
         }
 
-        public getVSMOffset(): number {
-            return 0.2;
-        }
 
         public supportsVSM(): boolean {
             return true;

+ 8 - 2
Babylon/Loading/Plugins/babylon.babylonFileLoader.js

@@ -215,8 +215,14 @@ var BABYLON;
             if (parsedShadowGenerator.usePoissonSampling) {
                 shadowGenerator.usePoissonSampling = true;
             }
-            else {
-                shadowGenerator.useVarianceShadowMap = parsedShadowGenerator.useVarianceShadowMap;
+            else if (parsedShadowGenerator.useVarianceShadowMap) {
+                shadowGenerator.useVarianceShadowMap = true;
+            }
+            else if (parsedShadowGenerator.useBlurVarianceShadowMap) {
+                shadowGenerator.useBlurVarianceShadowMap = true;
+            }
+            if (parsedShadowGenerator.bias) {
+                shadowGenerator.setBias(parsedShadowGenerator.bias);
             }
             return shadowGenerator;
         };

+ 11 - 5
Babylon/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -1,6 +1,6 @@
 module BABYLON.Internals {
 
-    var checkColors4 = (colors: number[], count:number): number[] => {
+    var checkColors4 = (colors: number[], count: number): number[]=> {
         // Check if color3 was used
         if (colors.length === count * 3) {
             var colors4 = [];
@@ -269,8 +269,14 @@
 
         if (parsedShadowGenerator.usePoissonSampling) {
             shadowGenerator.usePoissonSampling = true;
-        } else {
-            shadowGenerator.useVarianceShadowMap = parsedShadowGenerator.useVarianceShadowMap;
+        } else if (parsedShadowGenerator.useVarianceShadowMap) {
+            shadowGenerator.useVarianceShadowMap = true;
+        } else if (parsedShadowGenerator.useBlurVarianceShadowMap) {
+            shadowGenerator.useBlurVarianceShadowMap = true;
+        }
+
+        if (parsedShadowGenerator.bias) {
+            shadowGenerator.setBias(parsedShadowGenerator.bias);
         }
 
         return shadowGenerator;
@@ -967,7 +973,7 @@
     var parseSound = (parsedSound, scene: Scene, rootUrl) => {
         var soundName = parsedSound.name;
         var soundUrl = rootUrl + soundName;
-        
+
         var options = {
             autoplay: parsedSound.autoplay, loop: parsedSound.loop, volume: parsedSound.volume,
             spatialSound: parsedSound.spatialSound, maxDistance: parsedSound.maxDistance,
@@ -978,7 +984,7 @@
             playbackRate: parsedSound.playbackRate
         };
 
-        var newSound = new BABYLON.Sound(soundName, soundUrl, scene, () => { scene._removePendingData(newSound); }, options);
+        var newSound = new BABYLON.Sound(soundName, soundUrl, scene,() => { scene._removePendingData(newSound); }, options);
         scene._addPendingData(newSound);
 
         if (parsedSound.position) {

+ 6 - 1
Babylon/Materials/Textures/babylon.renderTargetTexture.js

@@ -120,7 +120,12 @@ var BABYLON;
                 this.onBeforeRender();
             }
             // Clear
-            engine.clear(scene.clearColor, true, true);
+            if (this.onClear) {
+                this.onClear(engine);
+            }
+            else {
+                engine.clear(scene.clearColor, true, true);
+            }
             if (!this._doNotChangeAspectRatio) {
                 scene.updateTransformMatrix(true);
             }

+ 6 - 1
Babylon/Materials/Textures/babylon.renderTargetTexture.ts

@@ -7,6 +7,7 @@
         public onBeforeRender: () => void;
         public onAfterRender: () => void;
         public onAfterUnbind: () => void;
+        public onClear: (engine: Engine) => void;
         public activeCamera: Camera;
         public customRenderFunction: (opaqueSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, beforeTransparents?: () => void) => void;
 
@@ -142,7 +143,11 @@
             }
 
             // Clear
-            engine.clear(scene.clearColor, true, true);
+            if (this.onClear) {
+                this.onClear(engine);
+            } else {
+                engine.clear(scene.clearColor, true, true);
+            }
 
             if (!this._doNotChangeAspectRatio) {
                 scene.updateTransformMatrix(true);

+ 1 - 1
Babylon/Materials/babylon.standardMaterial.js

@@ -477,7 +477,7 @@ var BABYLON;
                         if (mesh.receiveShadows && shadowGenerator) {
                             this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
                             this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                            this._effect.setFloat4("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.getBias(), shadowGenerator.getLight().getVSMOffset());
+                            this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.getBias());
                         }
                     }
                     lightIndex++;

+ 1 - 1
Babylon/Materials/babylon.standardMaterial.ts

@@ -585,7 +585,7 @@
                         if (mesh.receiveShadows && shadowGenerator) {
                             this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
                             this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
-                            this._effect.setFloat4("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.getBias(), shadowGenerator.getLight().getVSMOffset());
+                            this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.getBias());
                         }
                     }
 

+ 15 - 14
Babylon/Shaders/default.fragment.fx

@@ -35,7 +35,7 @@ uniform vec3 vLightSpecular0;
 #ifdef SHADOW0
 varying vec4 vPositionFromLight0;
 uniform sampler2D shadowSampler0;
-uniform vec4 shadowsInfo0;
+uniform vec3 shadowsInfo0;
 #endif
 #ifdef SPOTLIGHT0
 uniform vec4 vLightDirection0;
@@ -52,7 +52,7 @@ uniform vec3 vLightSpecular1;
 #ifdef SHADOW1
 varying vec4 vPositionFromLight1;
 uniform sampler2D shadowSampler1;
-uniform vec4 shadowsInfo1;
+uniform vec3 shadowsInfo1;
 #endif
 #ifdef SPOTLIGHT1
 uniform vec4 vLightDirection1;
@@ -69,7 +69,7 @@ uniform vec3 vLightSpecular2;
 #ifdef SHADOW2
 varying vec4 vPositionFromLight2;
 uniform sampler2D shadowSampler2;
-uniform vec4 shadowsInfo2;
+uniform vec3 shadowsInfo2;
 #endif
 #ifdef SPOTLIGHT2
 uniform vec4 vLightDirection2;
@@ -86,7 +86,7 @@ uniform vec3 vLightSpecular3;
 #ifdef SHADOW3
 varying vec4 vPositionFromLight3;
 uniform sampler2D shadowSampler3;
-uniform vec4 shadowsInfo3;
+uniform vec3 shadowsInfo3;
 #endif
 #ifdef SPOTLIGHT3
 uniform vec4 vLightDirection3;
@@ -260,21 +260,22 @@ float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, flo
 }
 
 // Thanks to http://devmaster.net/
-float ChebychevInequality(vec2 moments, float t, float offset)
+float ChebychevInequality(vec2 moments, float t, float bias)
 {
 	if (t <= moments.x)
 	{
-		return 1.0;
+		return 0.0;
 	}
 
 	float variance = moments.y - (moments.x * moments.x);
-	variance = max(variance, 0.02);
+	variance = max(variance, 0.02 + bias);
 
 	float d = t - moments.x;
-	return clamp(variance / (variance + d * d) - offset, 0., 1.0);
+
+	return clamp(variance / (variance + d * d) - 0.05, 0.0, 1.0);
 }
 
-float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float offset)
+float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias)
 {
 	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
 	vec2 uv = 0.5 * depth.xy + vec2(0.5, 0.5);
@@ -287,7 +288,7 @@ float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, flo
 	vec4 texel = texture2D(shadowSampler, uv);
 
 	vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-	return 1.0 - ChebychevInequality(moments, depth.z, offset);
+	return 1.0 - ChebychevInequality(moments, depth.z, bias);
 }
 #endif
 
@@ -531,7 +532,7 @@ void main(void) {
 #endif
 #ifdef SHADOW0
 #ifdef SHADOWVSM0
-	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.w);
+	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.z);
 #else
 	#ifdef SHADOWPCF0
 		shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z);
@@ -558,7 +559,7 @@ void main(void) {
 #endif
 #ifdef SHADOW1
 #ifdef SHADOWVSM1
-	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1, shadowsInfo1.w);
+	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1, shadowsInfo1.z);
 #else
 	#ifdef SHADOWPCF1
 		shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z);
@@ -585,7 +586,7 @@ void main(void) {
 #endif
 #ifdef SHADOW2
 #ifdef SHADOWVSM2
-	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2, shadowsInfo2.w);
+	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2, shadowsInfo2.z);
 #else
 	#ifdef SHADOWPCF2
 		shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z);
@@ -612,7 +613,7 @@ void main(void) {
 #endif
 #ifdef SHADOW3
 #ifdef SHADOWVSM3
-	shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.w);
+	shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z);
 #else
 	#ifdef SHADOWPCF3
 		shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z);

+ 0 - 19
Babylon/Shaders/depthBoxBlur.fragment.fx

@@ -2,8 +2,6 @@
 precision highp float;
 #endif
 
-#define OFFSET 1
-
 // Samplers
 varying vec2 vUV;
 uniform sampler2D textureSampler;
@@ -11,23 +9,6 @@ uniform sampler2D textureSampler;
 // Parameters
 uniform vec2 screenSize;
 
-vec4 pack(float depth)
-{
-	const vec4 bit_shift = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
-	const vec4 bit_mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
-
-	vec4 res = fract(depth * bit_shift);
-	res -= res.xxyz * bit_mask;
-
-	return res;
-}
-
-float unpack(vec4 color)
-{
-	const vec4 bit_shift = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);
-	return dot(color, bit_shift);
-}
-
 void main(void)
 {
 	vec4 colorDepth = vec4(0.0);

+ 4 - 3
Babylon/Shaders/shadowMap.fragment.fx

@@ -22,9 +22,7 @@ vec2 packHalf(float depth)
 	return color - (color.yy * bitOffset);
 }
 
-#ifndef VSM
 varying vec4 vPosition;
-#endif
 
 #ifdef ALPHATEST
 varying vec2 vUV;
@@ -39,8 +37,11 @@ void main(void)
 #endif
 
 #ifdef VSM
-	float moment1 = gl_FragCoord.z;
+	float depth = vPosition.z / vPosition.w;
+
+	float moment1 = depth;
 	float moment2 = moment1 * moment1;
+
 	gl_FragColor = vec4(packHalf(moment1), packHalf(moment2));
 #else
 	gl_FragColor = pack(vPosition.z / vPosition.w);

+ 1 - 5
Babylon/Shaders/shadowMap.vertex.fx

@@ -24,9 +24,7 @@ uniform mat4 viewProjection;
 uniform mat4 mBones[BonesPerMesh];
 #endif
 
-#ifndef VSM
 varying vec4 vPosition;
-#endif
 
 #ifdef ALPHATEST
 varying vec2 vUV;
@@ -55,10 +53,8 @@ void main(void)
 	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
 #endif
 
-#ifndef VSM
 	vPosition = viewProjection * finalWorld * vec4(position, 1.0);
-#endif
-	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
+	gl_Position = vPosition;
 
 #ifdef ALPHATEST
 #ifdef UV1

文件差異過大導致無法顯示
+ 68 - 38
babylon.2.1-alpha.debug.js


文件差異過大導致無法顯示
+ 13 - 13
babylon.2.1-alpha.js