Browse Source

avoid branching in shaders, avoid sampling center pixel twice in dof blur, move samplers to inside if statements in coc shader

Trevor Baron 7 years ago
parent
commit
3e44745c98

+ 9 - 2
src/PostProcess/babylon.blurPostProcess.ts

@@ -158,10 +158,17 @@
 			let maxVaryingRows = this.getEngine().getCaps().maxVaryingVectors;
 			let freeVaryingVec2 = Math.max(maxVaryingRows, 0.) - 1; // Because of sampleCenter
 
-            let varyingCount = Math.min(offsets.length, freeVaryingVec2);
-        
+			let varyingCount = Math.min(offsets.length, freeVaryingVec2);
+
 			let defines = "";
 			defines+=this._staticDefines;
+
+			// The DOF fragment should ignore the center pixel when looping as it is handled manualy in the fragment shader.
+			if(this._staticDefines.indexOf("DOF") != -1){
+				defines += `#define CENTER_WEIGHT ${this._glslFloat(weights[varyingCount-1])}\r\n`;
+				varyingCount--;
+			}
+			
             for (let i = 0; i < varyingCount; i++) {
                 defines += `#define KERNEL_OFFSET${i} ${this._glslFloat(offsets[i])}\r\n`;
                 defines += `#define KERNEL_WEIGHT${i} ${this._glslFloat(weights[i])}\r\n`;

+ 1 - 6
src/Shaders/ShadersInclude/kernelBlurFragment.fx

@@ -1,10 +1,5 @@
 #ifdef DOF
-    if(sampleCoord{X} == sampleCenter){
-        factor = 1.;
-    }else{
-        factor = sampleCoC(sampleCoord{X});
-    }
-    
+    factor = sampleCoC(sampleCoord{X});    
     computedWeight = KERNEL_WEIGHT{X} * factor;
     sumOfWeights += computedWeight;
 #else

+ 1 - 6
src/Shaders/ShadersInclude/kernelBlurFragment2.fx

@@ -1,10 +1,5 @@
 #ifdef DOF
-    if(sampleCenter + delta * KERNEL_DEP_OFFSET{X} == sampleCenter){
-        factor = 1.;
-    }else{
-        factor = sampleCoC(sampleCenter + delta * KERNEL_DEP_OFFSET{X});
-    }
-
+    factor = sampleCoC(sampleCenter + delta * KERNEL_DEP_OFFSET{X});
     computedWeight = KERNEL_DEP_WEIGHT{X} * factor;
     sumOfWeights += computedWeight;
 #else

+ 11 - 8
src/Shaders/depthOfFieldMerge.fragment.fx

@@ -13,32 +13,35 @@ uniform sampler2D blurStep2;
 
 void main(void)
 {
-    gl_FragColor = texture2D(textureSampler, vUV);
-
     float coc = texture2D(circleOfConfusionSampler, vUV).r;
-    vec4 original = texture2D(textureSampler, vUV);
 #if BLUR_LEVEL == 0
+    vec4 original = texture2D(textureSampler, vUV);
     vec4 blurred0 = texture2D(blurStep0, vUV);
     gl_FragColor = mix(original, blurred0, coc);
 #endif
 #if BLUR_LEVEL == 1
-    vec4 blurred0 = texture2D(blurStep0, vUV);   
-    vec4 blurred1 = texture2D(blurStep1, vUV);
     if(coc < 0.5){
+        vec4 original = texture2D(textureSampler, vUV);
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(original, blurred1, coc/0.5);
     }else{
+        vec4 blurred0 = texture2D(blurStep0, vUV);   
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(blurred1, blurred0, (coc-0.5)/0.5);
     }
 #endif
 #if BLUR_LEVEL == 2
-    vec4 blurred0 = texture2D(blurStep0, vUV);
-    vec4 blurred1 = texture2D(blurStep1, vUV);
-    vec4 blurred2 = texture2D(blurStep2, vUV);
     if(coc < 0.33){
+        vec4 original = texture2D(textureSampler, vUV);
+        vec4 blurred2 = texture2D(blurStep2, vUV);
         gl_FragColor = mix(original, blurred2, coc/0.33);
     }else if(coc < 0.66){
+        vec4 blurred1 = texture2D(blurStep1, vUV);
+        vec4 blurred2 = texture2D(blurStep2, vUV);
         gl_FragColor = mix(blurred2, blurred1, (coc-0.33)/0.33);
     }else{
+        vec4 blurred0 = texture2D(blurStep0, vUV);
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(blurred1, blurred0, (coc-0.66)/0.34);
     }
 #endif

+ 12 - 11
src/Shaders/kernelBlur.fragment.fx

@@ -43,13 +43,6 @@ varying vec2 sampleCenter;
 
 void main(void)
 {
-	#ifdef DOF
-		float sumOfWeights = 0.0; // Since not all values are blended, keep track of sum to devide result by at the end to get an average
-		float sampleDepth = 0.0;
-    	float factor = 0.0;
-		float centerSampleDepth = sampleDistance(sampleCenter);
-	#endif
-
 	float computedWeight = 0.0;
 
 	#ifdef PACKEDFLOAT	
@@ -58,6 +51,18 @@ void main(void)
 		vec4 blend = vec4(0.);
 	#endif
 
+	#ifdef DOF
+		float sumOfWeights = CENTER_WEIGHT; // Since not all values are blended, keep track of sum to devide result by at the end to get an average (start at center weight as center pixel is added by default)
+    	float factor = 0.0;
+
+		// Add center pixel to the blur by default
+		#ifdef PACKEDFLOAT
+			blend += unpack(texture2D(textureSampler, sampleCenter)) * CENTER_WEIGHT;
+		#else
+			blend += texture2D(textureSampler, sampleCenter) * CENTER_WEIGHT;
+		#endif
+	#endif
+
 	#include<kernelBlurFragment>[0..varyingCount]
 	#include<kernelBlurFragment2>[0..depCount]
 
@@ -68,10 +73,6 @@ void main(void)
 	#endif
 
 	#ifdef DOF
-		// If there are no samples to blend, make pixel black.
-		if(sumOfWeights == 0.0){
-			gl_FragColor = vec4(0.0,0.0,0.0,1.0);
-		}
 		gl_FragColor /= sumOfWeights;
 	#endif
 }