Selaa lähdekoodia

Add support for two-sided lighting (thanks to @BeardedGnome for helping out with the prototyping)

Gary Hsu 8 vuotta sitten
vanhempi
commit
93a898e737

+ 11 - 1
src/Materials/babylon.pbrMaterial.ts

@@ -61,9 +61,9 @@
         public RADIANCEOVERALPHA = false;
         public USEPMREMREFLECTION = false;
         public USEPMREMREFRACTION = false;
-        public OPENGLNORMALMAP = false;
         public INVERTNORMALMAPX = false;
         public INVERTNORMALMAPY = false;
+        public TWOSIDEDLIGHTING = false;
         public SHADOWFULLFLOAT = false;
 
         public METALLICWORKFLOW = false;
@@ -487,6 +487,12 @@
         @serialize()
         public invertNormalMapY = false;
 
+        /**
+         * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
+         */
+        @serialize()
+        public twoSidedLighting = false;
+
         private _renderTargets = new SmartArray<RenderTargetTexture>(16);
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _globalAmbientColor = new Color3(0, 0, 0);
@@ -846,6 +852,10 @@
                         this._defines.CAMERACOLORGRADING = true;
                     }
                 }
+
+                if (!this.backFaceCulling && this.twoSidedLighting) {
+                    this._defines.TWOSIDEDLIGHTING = true;
+                }
             }
 
             // Effect

+ 11 - 0
src/Materials/babylon.standardMaterial.ts

@@ -55,6 +55,7 @@
         public REFLECTIONOVERALPHA = false;
         public INVERTNORMALMAPX = false;
         public INVERTNORMALMAPY = false;
+        public TWOSIDEDLIGHTING = false;
         public SHADOWFULLFLOAT = false;
         public CAMERACOLORGRADING = false;
         public CAMERACOLORCURVES = false;
@@ -184,6 +185,12 @@
         public invertNormalMapY = false;
 
         /**
+         * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
+         */
+        @serialize()
+        public twoSidedLighting = false;
+
+        /**
          * Color Grading 2D Lookup Texture.
          * This allows special effects like sepia, black and white to sixties rendering style. 
          */
@@ -462,6 +469,10 @@
                         this._defines.CAMERACOLORGRADING = true;
                     }
                 }
+
+                if (!this.backFaceCulling && this.twoSidedLighting) {
+                    this._defines.TWOSIDEDLIGHTING = true;
+                }
             }
 
             // Effect

+ 2 - 2
src/Shaders/ShadersInclude/bumpFragment.fx

@@ -4,7 +4,7 @@
 	#if defined(TANGENT) && defined(NORMAL)
 		mat3 TBN = vTBN;
 	#else
-		mat3 TBN = cotangent_frame(normalW * vBumpInfos.y, -viewDirectionW, vBumpUV);
+		mat3 TBN = cotangent_frame(normalW * vBumpInfos.y, vPositionW, vBumpUV);
 	#endif
 #endif
 
@@ -19,5 +19,5 @@
 #endif
 
 #ifdef BUMP
-	normalW = perturbNormal(viewDirectionW, TBN, vBumpUV + uvOffset);
+	normalW = perturbNormal(TBN, vBumpUV + uvOffset);
 #endif

+ 4 - 1
src/Shaders/ShadersInclude/bumpFragmentFunctions.fx

@@ -9,6 +9,9 @@
 	// Thanks to http://www.thetenthplanet.de/archives/1180
 	mat3 cotangent_frame(vec3 normal, vec3 p, vec2 uv)
 	{
+		// flip the uv for the backface
+		uv = gl_FrontFacing ? uv : -uv;
+
 		// get edge vectors of the pixel triangle
 		vec3 dp1 = dFdx(p);
 		vec3 dp2 = dFdy(p);
@@ -26,7 +29,7 @@
 		return mat3(tangent * invmax, binormal * invmax, normal);
 	}
 
-	vec3 perturbNormal(vec3 viewDir, mat3 cotangentFrame, vec2 uv)
+	vec3 perturbNormal(mat3 cotangentFrame, vec2 uv)
 	{
 		vec3 map = texture2D(bumpSampler, uv).xyz;
 

+ 4 - 0
src/Shaders/default.fragment.fx

@@ -178,6 +178,10 @@ void main(void) {
 
 #include<bumpFragment>
 
+#ifdef TWOSIDEDLIGHTING
+	normalW = gl_FrontFacing ? normalW : -normalW;
+#endif
+
 #ifdef DIFFUSE
 	baseColor = texture2D(diffuseSampler, vDiffuseUV + uvOffset);
 

+ 10 - 6
src/Shaders/pbr.fragment.fx

@@ -185,13 +185,17 @@ void main(void) {
 	vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
 
 	// Bump
-	#ifdef NORMAL
-		vec3 normalW = normalize(vNormalW);
-	#else
-		vec3 normalW = vec3(1.0, 1.0, 1.0);
-	#endif
+#ifdef NORMAL
+	vec3 normalW = normalize(vNormalW);
+#else
+	vec3 normalW = vec3(1.0, 1.0, 1.0);
+#endif
+
+#include<bumpFragment>
 
-	#include<bumpFragment>
+#ifdef TWOSIDEDLIGHTING
+	normalW = gl_FrontFacing ? normalW : -normalW;
+#endif
 
 	// Albedo
 	vec4 surfaceAlbedo = vec4(1., 1., 1., 1.);