Просмотр исходного кода

MeshLambertMaterial: Add support for scene.environment IBL. (#32791)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
mrdoob 2 месяцев назад
Родитель
Сommit
77097b78d2

+ 9 - 0
src/materials/MeshLambertMaterial.js

@@ -267,6 +267,14 @@ class MeshLambertMaterial extends Material {
 		 */
 		this.reflectivity = 1;
 
+		/**
+		 * Scales the effect of the environment map by multiplying its color.
+		 *
+		 * @type {number}
+		 * @default 1
+		 */
+		this.envMapIntensity = 1.0;
+
 		/**
 		 * The index of refraction (IOR) of air (approximately 1) divided by the
 		 * index of refraction of the material. It is used with environment mapping
@@ -373,6 +381,7 @@ class MeshLambertMaterial extends Material {
 		this.envMapRotation.copy( source.envMapRotation );
 		this.combine = source.combine;
 		this.reflectivity = source.reflectivity;
+		this.envMapIntensity = source.envMapIntensity;
 		this.refractionRatio = source.refractionRatio;
 
 		this.wireframe = source.wireframe;

+ 8 - 5
src/renderers/WebGLRenderer.js

@@ -2132,9 +2132,11 @@ class WebGLRenderer {
 
 			// always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change
 
-			materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
+			materialProperties.environment = ( material.isMeshStandardMaterial || material.isMeshLambertMaterial ) ? scene.environment : null;
 			materialProperties.fog = scene.fog;
-			materialProperties.envMap = environments.get( material.envMap || materialProperties.environment, material.isMeshStandardMaterial );
+
+			const usePMREM = material.isMeshStandardMaterial || ( material.isMeshLambertMaterial && ! material.envMap );
+			materialProperties.envMap = environments.get( material.envMap || materialProperties.environment, usePMREM );
 			materialProperties.envMapRotation = ( materialProperties.environment !== null && material.envMap === null ) ? scene.environmentRotation : material.envMapRotation;
 
 			if ( programs === undefined ) {
@@ -2265,9 +2267,10 @@ class WebGLRenderer {
 			textures.resetTextureUnits();
 
 			const fog = scene.fog;
-			const environment = material.isMeshStandardMaterial ? scene.environment : null;
+			const environment = ( material.isMeshStandardMaterial || material.isMeshLambertMaterial ) ? scene.environment : null;
 			const colorSpace = ( _currentRenderTarget === null ) ? _this.outputColorSpace : ( _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace );
-			const envMap = environments.get( material.envMap || environment, material.isMeshStandardMaterial );
+			const usePMREM = material.isMeshStandardMaterial || ( material.isMeshLambertMaterial && ! material.envMap );
+			const envMap = environments.get( material.envMap || environment, usePMREM );
 			const vertexAlphas = material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4;
 			const vertexTangents = !! geometry.attributes.tangent && ( !! material.normalMap || material.anisotropy > 0 );
 			const morphTargets = !! geometry.morphAttributes.position;
@@ -2592,7 +2595,7 @@ class WebGLRenderer {
 
 			}
 
-			if ( material.isMeshStandardMaterial && material.envMap === null && scene.environment !== null ) {
+			if ( ( material.isMeshStandardMaterial || material.isMeshLambertMaterial ) && material.envMap === null && scene.environment !== null ) {
 
 				m_uniforms.envMapIntensity.value = scene.environmentIntensity;
 

+ 7 - 11
src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js

@@ -38,23 +38,19 @@ export default /* glsl */`
 
 		vec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
 
-	#else
-
-		vec4 envColor = vec4( 0.0 );
+		#ifdef ENVMAP_BLENDING_MULTIPLY
 
-	#endif
+			outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );
 
-	#ifdef ENVMAP_BLENDING_MULTIPLY
+		#elif defined( ENVMAP_BLENDING_MIX )
 
-		outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );
+			outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );
 
-	#elif defined( ENVMAP_BLENDING_MIX )
+		#elif defined( ENVMAP_BLENDING_ADD )
 
-		outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );
+			outgoingLight += envColor.xyz * specularStrength * reflectivity;
 
-	#elif defined( ENVMAP_BLENDING_ADD )
-
-		outgoingLight += envColor.xyz * specularStrength * reflectivity;
+		#endif
 
 	#endif
 

+ 6 - 0
src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js

@@ -1,6 +1,12 @@
 export default /* glsl */`
 #if defined( RE_IndirectDiffuse )
 
+	#ifdef LAMBERT
+
+		irradiance += iblIrradiance;
+
+	#endif
+
 	RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
 
 #endif

+ 6 - 2
src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js

@@ -10,9 +10,13 @@ export default /* glsl */`
 
 	#endif
 
-	#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )
+	#if defined( USE_ENVMAP ) && defined( ENVMAP_TYPE_CUBE_UV )
 
-		iblIrradiance += getIBLIrradiance( geometryNormal );
+		#if defined( STANDARD ) || defined( LAMBERT )
+
+			iblIrradiance += getIBLIrradiance( geometryNormal );
+
+		#endif
 
 	#endif
 

+ 2 - 1
src/renderers/shaders/ShaderLib.js

@@ -39,7 +39,8 @@ const ShaderLib = {
 			UniformsLib.fog,
 			UniformsLib.lights,
 			{
-				emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) }
+				emissive: { value: /*@__PURE__*/ new Color( 0x000000 ) },
+				envMapIntensity: { value: 1 }
 			}
 		] ),
 

+ 2 - 0
src/renderers/shaders/ShaderLib/meshlambert.glsl.js

@@ -68,8 +68,10 @@ uniform float opacity;
 #include <aomap_pars_fragment>
 #include <lightmap_pars_fragment>
 #include <emissivemap_pars_fragment>
+#include <cube_uv_reflection_fragment>
 #include <envmap_common_pars_fragment>
 #include <envmap_pars_fragment>
+#include <envmap_physical_pars_fragment>
 #include <fog_pars_fragment>
 #include <bsdfs>
 #include <lights_pars_begin>

+ 6 - 0
src/renderers/webgl/WebGLMaterials.js

@@ -47,6 +47,12 @@ function WebGLMaterials( renderer, properties ) {
 
 			refreshUniformsCommon( uniforms, material );
 
+			if ( material.envMap ) {
+
+				uniforms.envMapIntensity.value = material.envMapIntensity;
+
+			}
+
 		} else if ( material.isMeshToonMaterial ) {
 
 			refreshUniformsCommon( uniforms, material );

+ 3 - 2
src/renderers/webgl/WebGLPrograms.js

@@ -51,9 +51,10 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
 
 		const fog = scene.fog;
 		const geometry = object.geometry;
-		const environment = material.isMeshStandardMaterial ? scene.environment : null;
+		const environment = ( material.isMeshStandardMaterial || material.isMeshLambertMaterial ) ? scene.environment : null;
 
-		const envMap = environments.get( material.envMap || environment, material.isMeshStandardMaterial );
+		const usePMREM = material.isMeshStandardMaterial || ( material.isMeshLambertMaterial && ! material.envMap );
+		const envMap = environments.get( material.envMap || environment, usePMREM );
 		const envMapCubeUVHeight = ( !! envMap ) && ( envMap.mapping === CubeUVReflectionMapping ) ? envMap.image.height : null;
 
 		const shaderID = shaderIDs[ material.type ];

粤ICP备19079148号