瀏覽代碼

SSAO shader fixing with depth issues

Benjamin Guignabert 8 年之前
父節點
當前提交
8b68565c03

+ 2 - 2
Tools/Gulp/config.json

@@ -529,8 +529,8 @@
                 "geometry.fragment"
             ],
             "shaderIncludes": [
-                "bonesDeclaration",
-                "instancesDeclaration",
+                "bones300Declaration",
+                "instances300Declaration",
                 "instancesVertex",
                 "bonesVertex"
             ]

File diff suppressed because it is too large
+ 1111 - 1101
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 32 - 32
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 318 - 10
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 1111 - 1101
dist/preview release/babylon.module.d.ts


+ 26 - 10
src/PostProcess/babylon.ssao2RenderingPipeline.ts

@@ -36,6 +36,20 @@
         public totalStrength: number = 1.0;
 
         /**
+        * Maximum depth value to still render AO. A smooth falloff makes the dimming more natural, so there will be no abrupt shading change.
+        * @type {number}
+        */
+        @serialize()
+        public maxZ: number = 100.0;
+
+        /**
+        * In order to save performances, SSAO radius is clamped on close geometry. This ratio changes by how much
+        * @type {number}
+        */
+        @serialize()
+        public minZAspect: number = 0.2;
+
+        /**
         * Number of samples used for the SSAO calculations. Default value is 8
         * @type {number}
         */
@@ -58,7 +72,7 @@
                 this._blurVPostProcess.dispose(camera);
             }
 
-            this._createBlurPostProcess(this._ratio.ssaoRatio);
+            this._createBlurPostProcess(this._ratio.ssaoRatio, this._ratio.blurRatio);
             this.addEffect(new PostProcessRenderEffect(this._scene.getEngine(), this.SSAORenderEffect, () => { return this._ssaoPostProcess; }, true));
             this.addEffect(new PostProcessRenderEffect(this._scene.getEngine(), this.SSAORenderEffect, () => { return this._ssaoPostProcess; }, true));
 
@@ -127,7 +141,7 @@
          * @constructor
          * @param {string} name - The rendering pipeline name
          * @param {BABYLON.Scene} scene - The scene linked to this pipeline
-         * @param {any} ratio - The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, combineRatio: 1.0 }
+         * @param {any} ratio - The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, blurRatio: 1.0 }
          * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to
          */
         constructor(name: string, scene: Scene, ratio: any, cameras?: Camera[]) {
@@ -136,10 +150,10 @@
             this._scene = scene;
 
             var ssaoRatio = ratio.ssaoRatio || ratio;
-            var combineRatio = ratio.combineRatio || ratio;
+            var blurRatio = ratio.blurRatio || ratio;
             this._ratio = {
                 ssaoRatio: ssaoRatio,
-                combineRatio: combineRatio
+                blurRatio: blurRatio
             };
 
             // Set up assets
@@ -149,8 +163,8 @@
 
             this._originalColorPostProcess = new PassPostProcess("SSAOOriginalSceneColor", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
             this._createSSAOPostProcess(1.0);
-            this._createBlurPostProcess(ssaoRatio);
-            this._createSSAOCombinePostProcess(ssaoRatio);
+            this._createBlurPostProcess(ssaoRatio, blurRatio);
+            this._createSSAOCombinePostProcess(blurRatio);
 
             // Set up pipeline
             this.addEffect(new PostProcessRenderEffect(scene.getEngine(), this.SSAOOriginalSceneColorEffect, () => { return this._originalColorPostProcess; }, true));
@@ -192,7 +206,7 @@
         }
 
         // Private Methods
-        private _createBlurPostProcess(ratio: number): void {
+        private _createBlurPostProcess(ssaoRatio: number, blurRatio: number): void {
             var samples = 16;
             var samplerOffsets = [];
             var expensive = this.expensiveBlur;
@@ -201,7 +215,7 @@
                 samplerOffsets.push(i * 2);
             }
 
-            this._blurHPostProcess = new PostProcess("BlurH", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], ratio, null, Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_H\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
+            this._blurHPostProcess = new PostProcess("BlurH", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], ssaoRatio, null, Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_H\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
             this._blurHPostProcess.onApply = (effect: Effect) => {
                 effect.setFloat("outSize", this._ssaoCombinePostProcess.width);
                 effect.setFloat("near", this._scene.activeCamera.minZ);
@@ -214,7 +228,7 @@
                 }
             };
 
-            this._blurVPostProcess = new PostProcess("BlurV", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], ratio, null, Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
+            this._blurVPostProcess = new PostProcess("BlurV", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], blurRatio, null, Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
             this._blurVPostProcess.onApply = (effect: Effect) => {
                 effect.setFloat("outSize", this._ssaoCombinePostProcess.height);
                 effect.setFloat("near", this._scene.activeCamera.minZ);
@@ -275,7 +289,7 @@
                                                     [
                                                         "sampleSphere", "samplesFactor", "randTextureTiles", "totalStrength", "radius",
                                                         "base", "range", "projection", "near", "far", "texelSize",
-                                                        "xViewport", "yViewport"
+                                                        "xViewport", "yViewport", "maxZ", "minZAspect"
                                                     ],
                                                     ["randomSampler", "normalSampler"],
                                                     ratio, null, Texture.BILINEAR_SAMPLINGMODE,
@@ -292,6 +306,8 @@
                 effect.setFloat("totalStrength", this.totalStrength);
                 effect.setFloat2("texelSize", 1 / this._ssaoPostProcess.width, 1 / this._ssaoPostProcess.height);
                 effect.setFloat("radius", this.radius);
+                effect.setFloat("maxZ", this.maxZ);
+                effect.setFloat("minZAspect", this.minZAspect);
                 effect.setFloat("base", this.base);
                 effect.setFloat("near", this._scene.activeCamera.minZ);
                 effect.setFloat("far", this._scene.activeCamera.maxZ);

+ 1 - 1
src/Rendering/babylon.geometryRenderer.ts

@@ -25,7 +25,7 @@ module BABYLON {
             
             // set default depth value to 1.0 (far away)
             this._multiRenderTarget.onClearObservable.add((engine: Engine) => {
-                engine.clear(new Color4(1.0, 1.0, 1.0, 1.0), true, true, true);
+                engine.clear(new Color4(0.0, 0.0, 0.0, 1.0), true, true, true);
             });
 
             // Custom render function

+ 10 - 0
src/Shaders/ShadersInclude/bones300Declaration.fx

@@ -0,0 +1,10 @@
+#if NUM_BONE_INFLUENCERS > 0
+	uniform mat4 mBones[BonesPerMesh];
+
+	in vec4 matricesIndices;
+	in vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		in vec4 matricesIndicesExtra;
+		in vec4 matricesWeightsExtra;
+	#endif
+#endif

+ 8 - 0
src/Shaders/ShadersInclude/instances300Declaration.fx

@@ -0,0 +1,8 @@
+#ifdef INSTANCES
+	in vec4 world0;
+	in vec4 world1;
+	in vec4 world2;
+	in vec4 world3;
+#else
+	uniform mat4 world;
+#endif

+ 2 - 2
src/Shaders/geometry.vertex.fx

@@ -3,8 +3,8 @@
 precision highp float;
 precision highp int;
 
-#include<bonesDeclaration>
-#include<instancesDeclaration>
+#include<bones300Declaration>
+#include<instances300Declaration>
 
 in vec3 position;
 in vec3 normal;

+ 14 - 7
src/Shaders/ssao2.fragment.fx

@@ -1,4 +1,4 @@
-// SSAO Shader
+// SSAO 2 Shader
 precision highp float;
 uniform sampler2D textureSampler;
 uniform float near;
@@ -31,6 +31,8 @@ uniform float totalStrength;
 uniform float base;
 uniform float xViewport;
 uniform float yViewport;
+uniform float maxZ;
+uniform float minZAspect;
 uniform vec2 texelSize;
 
 uniform mat4 projection;
@@ -40,9 +42,9 @@ void main()
 	vec3 random = texture2D(randomSampler, vUV * randTextureTiles).rgb;
 	float depth = texture(textureSampler, vUV).r;
 	float linearDepth = - perspectiveDepthToViewZ(depth, near, far);
-	vec3 normal = texture2D(normalSampler, vUV, 0.0).rgb; 
+	vec3 normal = texture2D(normalSampler, vUV).rgb; 
 	float occlusion = 0.0;
-	float correctedRadius = min(radius, 0.2 * linearDepth / near);
+	float correctedRadius = min(radius, minZAspect * linearDepth / near);
 
 	vec3 vViewRay = vec3((vUV.x * 2.0 - 1.0)*xViewport, (vUV.y * 2.0 - 1.0)*yViewport, 1.0);
 	vec3 origin = vViewRay * linearDepth;
@@ -54,6 +56,11 @@ void main()
 
 	float difference;
 
+	if (linearDepth > maxZ) {
+		gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+		return;
+	}
+
 	for (int i = 0; i < SAMPLES; ++i) {
 		// get sample position:
 	   vec3 samplePosition = tbn * sampleSphere[i];
@@ -70,10 +77,10 @@ void main()
 	   float linearSampleDepth = - perspectiveDepthToViewZ(sampleDepth, near, far);
 		// range check & accumulate:
 	   float rangeCheck = abs(linearDepth - linearSampleDepth) < correctedRadius ? 1.0 : 0.0;
-	  	difference = samplePosition.z - linearSampleDepth;
-	  	//occlusion += step(fallOff, difference) * (1.0 - smoothstep(fallOff, area, difference)) * rangeCheck;
-	  	occlusion += (difference > 0.0 ? 1.0 : 0.0) * rangeCheck;
-
+	   difference = samplePosition.z - linearSampleDepth;
+	   float errorFactor = max(0.0, pow((maxZ-linearDepth) / maxZ, 0.25));
+	  //occlusion += step(fallOff, difference) * (1.0 - smoothstep(fallOff, area, difference)) * rangeCheck * errorFactor;
+	   occlusion += (difference >= 1e-5 ? 1.0 : 0.0) * rangeCheck * errorFactor;
 	}
 
 

+ 1 - 1
src/Shaders/ssaoCombine.fragment.fx

@@ -7,5 +7,5 @@ void main(void) {
 	vec4 ssaoColor = texture2D(textureSampler, vUV);
 	vec4 sceneColor = texture2D(originalColor, vUV);
 
-	gl_FragColor = sceneColor * ssaoColor;
+	gl_FragColor = ssaoColor;
 }