浏览代码

Merge pull request #1343 from BitOfGold/lightmapsexcluded

Combining baked and dynamic shadows nicely (lightmap)
David Catuhe 9 年之前
父节点
当前提交
4d447a19c6

+ 37 - 0
src/Lights/babylon.light.ts

@@ -21,6 +21,40 @@
     }
 
     export class Light extends Node {
+
+        //lightmapMode Consts
+        private static _LIGHTMAP_DEFAULT = 0;
+        private static _LIGHTMAP_SPECULAR = 1;
+        private static _LIGHTMAP_SHADOWSONLY = 2;
+
+        /**
+         * If every light affecting the material is in this lightmapMode,
+         * material.lightmapTexture adds or multiplies
+         * (depends on material.useLightmapAsShadowmap)
+         * after every other light calculations.
+         */
+        public static get LIGHTMAP_DEFAULT(): number {
+            return Light._LIGHTMAP_DEFAULT;
+        }
+
+        /**
+         * material.lightmapTexture as only diffuse lighting from this light
+         * adds pnly specular lighting from this light
+         * adds dynamic shadows
+         */
+        public static get LIGHTMAP_SPECULAR(): number {
+            return Light._LIGHTMAP_SPECULAR;
+        }
+
+        /**
+         * material.lightmapTexture as only lighting
+         * no light calculation from this light
+         * only adds dynamic shadows from this light
+         */
+        public static get LIGHTMAP_SHADOWSONLY(): number {
+            return Light._LIGHTMAP_SHADOWSONLY;
+        }
+
         @serializeAsColor3()
         public diffuse = new Color3(1.0, 1.0, 1.0);
 
@@ -42,6 +76,9 @@
         @serialize()
         public excludeWithLayerMask = 0;
 
+        @serialize()
+        public lightmapMode = 0;
+
         // PBR Properties.
         @serialize()
         public radius = 0.00001;

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

@@ -5,6 +5,7 @@
             var needNormals = false;
             var needRebuild = false;
             var needShadows = false;
+            var lightmapMode = false;
 
             for (var index = 0; index < scene.lights.length; index++) {
                 var light = scene.lights[index];
@@ -103,6 +104,20 @@
                     }
                 }
 
+                if (light.lightmapMode != Light.LIGHTMAP_DEFAULT ) {
+                    lightmapMode = true;
+                    if (defines["LIGHTMAPEXCLUDED" + lightIndex] === undefined) {
+                        needRebuild = true;
+                    }
+                    if (defines["LIGHTMAPNOSPECULAR" + lightIndex] === undefined) {
+                        needRebuild = true;
+                    }
+                    defines["LIGHTMAPEXCLUDED" + lightIndex] = true;
+                    if (light.lightmapMode == Light.LIGHTMAP_SHADOWSONLY) {
+                        defines["LIGHTMAPNOSPECULAR" + lightIndex] = true;
+                    }
+                }
+
                 lightIndex++;
                 if (lightIndex === maxSimultaneousLights)
                     break;
@@ -117,6 +132,13 @@
                 defines["SHADOWFULLFLOAT"] = true;
             }
 
+            if (defines["LIGHTMAPEXCLUDED"] === undefined) {
+                needRebuild = true;
+            }
+            if (lightmapMode) {
+                defines["LIGHTMAPEXCLUDED"] = true;
+            }
+
             if (needRebuild) {
                 defines.rebuild();
             }

+ 28 - 15
src/Shaders/ShadersInclude/lightFragment.fx

@@ -1,16 +1,20 @@
 #ifdef LIGHT{X}
-	#ifndef SPECULARTERM
-		vec3 vLightSpecular{X} = vec3(0.);
-	#endif
-	#ifdef SPOTLIGHT{X}
-		info = computeSpotLighting(viewDirectionW, normalW, vLightData{X}, vLightDirection{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightDiffuse{X}.a, glossiness);
-	#endif
-	#ifdef HEMILIGHT{X}
-		info = computeHemisphericLighting(viewDirectionW, normalW, vLightData{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightGround{X}, glossiness);
-	#endif
-	#if defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})
-		info = computeLighting(viewDirectionW, normalW, vLightData{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightDiffuse{X}.a, glossiness);
-	#endif
+    #if defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X})
+        //No light calculation
+    #else
+        #ifndef SPECULARTERM
+            vec3 vLightSpecular{X} = vec3(0.);
+        #endif
+        #ifdef SPOTLIGHT{X}
+            info = computeSpotLighting(viewDirectionW, normalW, vLightData{X}, vLightDirection{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightDiffuse{X}.a, glossiness);
+        #endif
+        #ifdef HEMILIGHT{X}
+            info = computeHemisphericLighting(viewDirectionW, normalW, vLightData{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightGround{X}, glossiness);
+        #endif
+        #if defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})
+            info = computeLighting(viewDirectionW, normalW, vLightData{X}, vLightDiffuse{X}.rgb, vLightSpecular{X}, vLightDiffuse{X}.a, glossiness);
+        #endif
+    #endif
 	#ifdef SHADOW{X}
 		#ifdef SHADOWVSM{X}
 			shadow = computeShadowWithVSM(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.z, shadowsInfo{X}.x);
@@ -32,8 +36,17 @@
 	#else
 		shadow = 1.;
 	#endif
-		diffuseBase += info.diffuse * shadow;
-	#ifdef SPECULARTERM
-		specularBase += info.specular * shadow;
+    #if defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X})
+	    diffuseBase += lightmapColor * shadow;
+	    #ifdef SPECULARTERM
+            #ifndef LIGHTMAPNOSPECULAR{X}
+                specularBase += info.specular * shadow * lightmapColor;
+            #endif
+        #endif
+    #else
+	    diffuseBase += info.diffuse * shadow;
+	    #ifdef SPECULARTERM
+		    specularBase += info.specular * shadow;
+	    #endif
 	#endif
 #endif

+ 12 - 7
src/Shaders/default.fragment.fx

@@ -232,6 +232,10 @@ void main(void) {
 #endif
 	float shadow = 1.;
 
+#ifdef LIGHTMAP
+	vec3 lightmapColor = texture2D(lightmapSampler, vLightmapUV).rgb * vLightmapInfos.y;
+#endif
+
 #include<lightFragment>[0..maxSimultaneousLights]
 
 	// Refraction
@@ -387,14 +391,15 @@ void main(void) {
 	vec4 color = vec4(finalDiffuse * baseAmbientColor + finalSpecular + reflectionColor + refractionColor, alpha);
 #endif
 
+//Old lightmap calculation method
 #ifdef LIGHTMAP
-	vec3 lightmapColor = texture2D(lightmapSampler, vLightmapUV).rgb * vLightmapInfos.y;
-
-#ifdef USELIGHTMAPASSHADOWMAP
-	color.rgb *= lightmapColor;
-#else
-	color.rgb += lightmapColor;
-#endif
+    #ifndef LIGHTMAPEXCLUDED
+        #ifdef USELIGHTMAPASSHADOWMAP
+            color.rgb *= lightmapColor;
+        #else
+            color.rgb += lightmapColor;
+        #endif
+    #endif
 #endif
 
 #include<logDepthFragment>