Przeglądaj źródła

Full Float generator and shaders

= 9 lat temu
rodzic
commit
06fd1c2b88

+ 18 - 2
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -126,6 +126,8 @@
         private _currentFaceIndex = 0;
         private _currentFaceIndexCache = 0;
 
+        private _useFullFloat = true;
+
         constructor(mapSize: number, light: IShadowLight) {
             this._light = light;
             this._scene = light.getScene();
@@ -133,15 +135,25 @@
 
             light._shadowGenerator = this;
 
+            // Texture type fallback from float to int if not supported.
+            var textureType: number;
+            if (this._scene.getEngine().getCaps().textureFloat) {
+                this._useFullFloat = true;
+                textureType = Engine.TEXTURETYPE_FLOAT;
+            }
+            else {
+                this._useFullFloat = false;
+                textureType = Engine.TEXTURETYPE_UNSIGNED_INT;
+            }
+            
             // Render target
-            this._shadowMap = new RenderTargetTexture(light.name + "_shadowMap", mapSize, this._scene, false, true, Engine.TEXTURETYPE_UNSIGNED_INT, light.needCube());
+            this._shadowMap = new RenderTargetTexture(light.name + "_shadowMap", mapSize, this._scene, false, true, textureType, light.needCube());
             this._shadowMap.wrapU = Texture.CLAMP_ADDRESSMODE;
             this._shadowMap.wrapV = Texture.CLAMP_ADDRESSMODE;
             this._shadowMap.anisotropicFilteringLevel = 1;
             this._shadowMap.updateSamplingMode(Texture.NEAREST_SAMPLINGMODE);
             this._shadowMap.renderParticles = false;
 
-
             this._shadowMap.onBeforeRenderObservable.add((faceIndex: number) => {
                 this._currentFaceIndex = faceIndex;
             });
@@ -257,6 +269,10 @@
         public isReady(subMesh: SubMesh, useInstances: boolean): boolean {
             var defines = [];
 
+            if (this._useFullFloat) {
+                defines.push("#define FULLFLOAT");
+            }
+
             if (this.useVarianceShadowMap || this.useBlurVarianceShadowMap) {
                 defines.push("#define VSM");
             }

+ 8 - 0
src/Materials/babylon.materialHelper.ts

@@ -105,6 +105,14 @@
                     break;
             }
 
+            if (scene.getEngine().getCaps().textureFloat) {
+                if (defines["FULLFLOAT"] === undefined) {
+                    needRebuild = true;
+                }
+
+                defines["FULLFLOAT"] = true;
+            }
+
             if (needRebuild) {
                 defines.rebuild();
             }

+ 52 - 21
src/Shaders/ShadersInclude/pbrShadowFunctions.fx

@@ -1,11 +1,13 @@
 // Shadows
 #ifdef SHADOWS
 
-    float unpack(vec4 color)
-    {
-        const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
-        return dot(color, bit_shift);
-    }
+	#ifndef FULLFLOAT
+        float unpack(vec4 color)
+        {
+            const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
+            return dot(color, bit_shift);
+        }
+    #endif
 
     uniform vec2 depthValues;
 
@@ -18,7 +20,11 @@
         directionToLight = normalize(directionToLight);
         directionToLight.y = - directionToLight.y;
 
-        float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+		#ifndef FULLFLOAT
+            float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+        #else
+            float shadow = textureCube(shadowSampler, directionToLight).x + bias;
+        #endif
 
         if (depth > shadow)
         {
@@ -53,10 +59,17 @@
         // Poisson Sampling
         float biasedDepth = depth - bias;
 
-        if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
-        if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
-        if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
-        if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
+		#ifndef FULLFLOAT
+            if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
+            if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
+            if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
+            if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
+        #else
+            if (textureCube(shadowSampler, directionToLight + poissonDisk[0] * mapSize).x < biasedDepth) visibility -= 0.25;
+            if (textureCube(shadowSampler, directionToLight + poissonDisk[1] * mapSize).x < biasedDepth) visibility -= 0.25;
+            if (textureCube(shadowSampler, directionToLight + poissonDisk[2] * mapSize).x < biasedDepth) visibility -= 0.25;
+            if (textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize).x < biasedDepth) visibility -= 0.25;
+        #endif
 
         #ifdef OVERLOADEDSHADOWVALUES
             return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
@@ -76,7 +89,11 @@
             return 1.0;
         }
 
-        float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
+		#ifndef FULLFLOAT
+            float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
+        #else
+            float shadow = texture2D(shadowSampler, uv).x + bias;
+        #endif
 
         if (depth.z > shadow)
         {
@@ -111,10 +128,17 @@
         // Poisson Sampling
         float biasedDepth = depth.z - bias;
 
-        if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
-        if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
-        if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
-        if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
+		#ifndef FULLFLOAT
+            if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
+            if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
+            if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
+            if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
+        #else
+            if (texture2D(shadowSampler, uv + poissonDisk[0] * mapSize).x < biasedDepth) visibility -= 0.25;
+            if (texture2D(shadowSampler, uv + poissonDisk[1] * mapSize).x < biasedDepth) visibility -= 0.25;
+            if (texture2D(shadowSampler, uv + poissonDisk[2] * mapSize).x < biasedDepth) visibility -= 0.25;
+            if (texture2D(shadowSampler, uv + poissonDisk[3] * mapSize).x < biasedDepth) visibility -= 0.25;
+        #endif
 
         #ifdef OVERLOADEDSHADOWVALUES
             return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
@@ -123,11 +147,13 @@
         #endif
     }
 
-    // Thanks to http://devmaster.net/
-    float unpackHalf(vec2 color)
-    {
-        return color.x + (color.y / 255.0);
-    }
+	#ifndef FULLFLOAT
+        // Thanks to http://devmaster.net/
+        float unpackHalf(vec2 color)
+        {
+            return color.x + (color.y / 255.0);
+        }
+    #endif
 
     float linstep(float low, float high, float v) {
         return clamp((v - low) / (high - low), 0.0, 1.0);
@@ -156,7 +182,12 @@
 
         vec4 texel = texture2D(shadowSampler, uv);
 
-        vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
+        #ifndef FULLFLOAT
+            vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
+        #else
+            vec2 moments = texel.xy;
+        #endif
+
         #ifdef OVERLOADEDSHADOWVALUES
             return min(1.0, mix(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness, vOverloadedShadowIntensity.x));
         #else

+ 53 - 22
src/Shaders/ShadersInclude/shadowsFragmentFunctions.fx

@@ -1,9 +1,11 @@
 #ifdef SHADOWS
-	float unpack(vec4 color)
-	{
-		const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
-		return dot(color, bit_shift);
-	}
+	#ifndef FULLFLOAT
+		float unpack(vec4 color)
+		{
+			const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
+			return dot(color, bit_shift);
+		}
+	#endif
 
 	uniform vec2 depthValues;
 
@@ -16,8 +18,12 @@
 
 		directionToLight = normalize(directionToLight);
 		directionToLight.y = -directionToLight.y;
-
-		float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+		
+		#ifndef FULLFLOAT
+			float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+		#else
+			float shadow = textureCube(shadowSampler, directionToLight).x + bias;
+		#endif
 
 		if (depth > shadow)
 		{
@@ -48,10 +54,17 @@
 		// Poisson Sampling
 		float biasedDepth = depth - bias;
 
-		if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
-		if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
-		if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
-		if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
+		#ifndef FULLFLOAT
+			if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
+			if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
+			if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
+			if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
+		#else
+			if (textureCube(shadowSampler, directionToLight + poissonDisk[0] * mapSize).x < biasedDepth) visibility -= 0.25;
+			if (textureCube(shadowSampler, directionToLight + poissonDisk[1] * mapSize).x < biasedDepth) visibility -= 0.25;
+			if (textureCube(shadowSampler, directionToLight + poissonDisk[2] * mapSize).x < biasedDepth) visibility -= 0.25;
+			if (textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize).x < biasedDepth) visibility -= 0.25;
+		#endif
 
 		return  min(1.0, visibility + darkness);
 	}
@@ -67,7 +80,11 @@
 			return 1.0;
 		}
 
-		float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
+		#ifndef FULLFLOAT
+			float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
+		#else
+			float shadow = texture2D(shadowSampler, uv).x + bias;
+		#endif
 
 		if (depth.z > shadow)
 		{
@@ -98,19 +115,28 @@
 		// Poisson Sampling
 		float biasedDepth = depth.z - bias;
 
-		if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
-		if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
-		if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
-		if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
+		#ifndef FULLFLOAT
+			if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
+			if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
+			if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
+			if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
+		#else
+			if (texture2D(shadowSampler, uv + poissonDisk[0] * mapSize).x < biasedDepth) visibility -= 0.25;
+			if (texture2D(shadowSampler, uv + poissonDisk[1] * mapSize).x < biasedDepth) visibility -= 0.25;
+			if (texture2D(shadowSampler, uv + poissonDisk[2] * mapSize).x < biasedDepth) visibility -= 0.25;
+			if (texture2D(shadowSampler, uv + poissonDisk[3] * mapSize).x < biasedDepth) visibility -= 0.25;
+		#endif
 
 		return  min(1.0, visibility + darkness);
 	}
 
-	// Thanks to http://devmaster.net/
-	float unpackHalf(vec2 color)
-	{
-		return color.x + (color.y / 255.0);
-	}
+	#ifndef FULLFLOAT
+		// Thanks to http://devmaster.net/
+		float unpackHalf(vec2 color)
+		{
+			return color.x + (color.y / 255.0);
+		}
+	#endif
 
 	float linstep(float low, float high, float v) {
 		return clamp((v - low) / (high - low), 0.0, 1.0);
@@ -139,7 +165,12 @@
 
 		vec4 texel = texture2D(shadowSampler, uv);
 
-		vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
+		#ifndef FULLFLOAT
+			vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
+		#else
+			vec2 moments = texel.xy;
+		#endif
+
 		return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
 	}
 #endif

+ 13 - 3
src/Shaders/shadowMap.fragment.fx

@@ -1,4 +1,5 @@
-vec4 pack(float depth)
+#ifndef FULLFLOAT
+vec4 pack(float depth)
 {
 	const vec4 bit_shift = vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0);
 	const vec4 bit_mask = vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
@@ -17,6 +18,7 @@ vec2 packHalf(float depth)
 
 	return color - (color.yy * bitOffset);
 }
+#endif
 
 varying vec4 vPosition;
 
@@ -52,8 +54,16 @@ void main(void)
 	float moment1 = depth;
 	float moment2 = moment1 * moment1;
 
-	gl_FragColor = vec4(packHalf(moment1), packHalf(moment2));
+	#ifndef FULLFLOAT
+		gl_FragColor = vec4(packHalf(moment1), packHalf(moment2));
+	#else
+		gl_FragColor = vec4(moment1, moment2, 1.0, 1.0);
+	#endif
 #else
-	gl_FragColor = pack(depth);
+	#ifndef FULLFLOAT
+		gl_FragColor = pack(depth);
+	#else
+		gl_FragColor = vec4(depth, 1.0, 1.0, 1.0);
+	#endif
 #endif
 }