浏览代码

Implemented Scene.environment.

Mr.doob 5 年之前
父节点
当前提交
0b6b2e782b
共有 3 个文件被更改,包括 49 次插入30 次删除
  1. 34 25
      src/renderers/WebGLRenderer.js
  2. 10 5
      src/renderers/webgl/WebGLPrograms.js
  3. 5 0
      src/scenes/Scene.js

+ 34 - 25
src/renderers/WebGLRenderer.js

@@ -25,6 +25,7 @@ import { cloneUniforms } from './shaders/UniformsUtils.js';
 import { Vector2 } from '../math/Vector2.js';
 import { Vector2 } from '../math/Vector2.js';
 import { Vector3 } from '../math/Vector3.js';
 import { Vector3 } from '../math/Vector3.js';
 import { Vector4 } from '../math/Vector4.js';
 import { Vector4 } from '../math/Vector4.js';
+import { Scene } from '../scenes/Scene.js';
 import { WebGLAnimation } from './webgl/WebGLAnimation.js';
 import { WebGLAnimation } from './webgl/WebGLAnimation.js';
 import { WebGLAttributes } from './webgl/WebGLAttributes.js';
 import { WebGLAttributes } from './webgl/WebGLAttributes.js';
 import { WebGLBackground } from './webgl/WebGLBackground.js';
 import { WebGLBackground } from './webgl/WebGLBackground.js';
@@ -719,11 +720,15 @@ function WebGLRenderer( parameters ) {
 
 
 	};
 	};
 
 
-	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
+	var tempScene = new Scene();
+
+	this.renderBufferDirect = function ( camera, scene, geometry, material, object, group ) {
+
+		if ( scene === null ) scene = tempScene; // renderBufferDirect second parameter used to be fog (could be null)
 
 
 		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
 		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
 
 
-		var program = setProgram( camera, fog, material, object );
+		var program = setProgram( camera, scene, material, object );
 
 
 		state.setMaterial( material, frontFaceCW );
 		state.setMaterial( material, frontFaceCW );
 
 
@@ -1053,13 +1058,13 @@ function WebGLRenderer( parameters ) {
 
 
 					for ( var i = 0; i < object.material.length; i ++ ) {
 					for ( var i = 0; i < object.material.length; i ++ ) {
 
 
-						initMaterial( object.material[ i ], scene.fog, object );
+						initMaterial( object.material[ i ], scene, object );
 
 
 					}
 					}
 
 
 				} else {
 				} else {
 
 
-					initMaterial( object.material, scene.fog, object );
+					initMaterial( object.material, scene, object );
 
 
 				}
 				}
 
 
@@ -1456,7 +1461,7 @@ function WebGLRenderer( parameters ) {
 
 
 		if ( object.isImmediateRenderObject ) {
 		if ( object.isImmediateRenderObject ) {
 
 
-			var program = setProgram( camera, scene.fog, material, object );
+			var program = setProgram( camera, scene, material, object );
 
 
 			state.setMaterial( material );
 			state.setMaterial( material );
 
 
@@ -1468,7 +1473,7 @@ function WebGLRenderer( parameters ) {
 
 
 		} else {
 		} else {
 
 
-			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
+			_this.renderBufferDirect( camera, scene, geometry, material, object, group );
 
 
 		}
 		}
 
 
@@ -1477,7 +1482,7 @@ function WebGLRenderer( parameters ) {
 
 
 	}
 	}
 
 
-	function initMaterial( material, fog, object ) {
+	function initMaterial( material, scene, object ) {
 
 
 		var materialProperties = properties.get( material );
 		var materialProperties = properties.get( material );
 
 
@@ -1487,7 +1492,7 @@ function WebGLRenderer( parameters ) {
 		var lightsStateVersion = lights.state.version;
 		var lightsStateVersion = lights.state.version;
 
 
 		var parameters = programCache.getParameters(
 		var parameters = programCache.getParameters(
-			material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object );
+			material, lights.state, shadowsArray, scene, _clipping.numPlanes, _clipping.numIntersection, object );
 
 
 		var programCacheKey = programCache.getProgramCacheKey( material, parameters );
 		var programCacheKey = programCache.getProgramCacheKey( material, parameters );
 
 
@@ -1605,7 +1610,7 @@ function WebGLRenderer( parameters ) {
 
 
 		}
 		}
 
 
-		materialProperties.fog = fog;
+		materialProperties.fog = scene.fog;
 
 
 		// store the light setup it was created for
 		// store the light setup it was created for
 
 
@@ -1642,10 +1647,13 @@ function WebGLRenderer( parameters ) {
 
 
 	}
 	}
 
 
-	function setProgram( camera, fog, material, object ) {
+	function setProgram( camera, scene, material, object ) {
 
 
 		textures.resetTextureUnits();
 		textures.resetTextureUnits();
 
 
+		var fog = scene.fog;
+		var environment = material.isMeshStandardMaterial ? scene.environment : null;
+
 		var materialProperties = properties.get( material );
 		var materialProperties = properties.get( material );
 		var lights = currentRenderState.state.lights;
 		var lights = currentRenderState.state.lights;
 
 
@@ -1698,7 +1706,7 @@ function WebGLRenderer( parameters ) {
 
 
 		if ( material.version !== materialProperties.__version ) {
 		if ( material.version !== materialProperties.__version ) {
 
 
-			initMaterial( material, fog, object );
+			initMaterial( material, scene, object );
 			materialProperties.__version = material.version;
 			materialProperties.__version = material.version;
 
 
 		}
 		}
@@ -1923,22 +1931,21 @@ function WebGLRenderer( parameters ) {
 
 
 			} else if ( material.isMeshStandardMaterial ) {
 			} else if ( material.isMeshStandardMaterial ) {
 
 
-				refreshUniformsCommon( m_uniforms, material );
+				refreshUniformsCommon( m_uniforms, material, environment );
 
 
 				if ( material.isMeshPhysicalMaterial ) {
 				if ( material.isMeshPhysicalMaterial ) {
 
 
-					refreshUniformsPhysical( m_uniforms, material );
+					refreshUniformsPhysical( m_uniforms, material, environment );
 
 
 				} else {
 				} else {
 
 
-					refreshUniformsStandard( m_uniforms, material );
+					refreshUniformsStandard( m_uniforms, material, environment );
 
 
 				}
 				}
 
 
 			} else if ( material.isMeshMatcapMaterial ) {
 			} else if ( material.isMeshMatcapMaterial ) {
 
 
 				refreshUniformsCommon( m_uniforms, material );
 				refreshUniformsCommon( m_uniforms, material );
-
 				refreshUniformsMatcap( m_uniforms, material );
 				refreshUniformsMatcap( m_uniforms, material );
 
 
 			} else if ( material.isMeshDepthMaterial ) {
 			} else if ( material.isMeshDepthMaterial ) {
@@ -2031,7 +2038,7 @@ function WebGLRenderer( parameters ) {
 
 
 	// Uniforms (refresh uniforms objects)
 	// Uniforms (refresh uniforms objects)
 
 
-	function refreshUniformsCommon( uniforms, material ) {
+	function refreshUniformsCommon( uniforms, material, environment ) {
 
 
 		uniforms.opacity.value = material.opacity;
 		uniforms.opacity.value = material.opacity;
 
 
@@ -2065,20 +2072,22 @@ function WebGLRenderer( parameters ) {
 
 
 		}
 		}
 
 
-		if ( material.envMap ) {
+		var envMap = material.envMap || environment;
+
+		if ( envMap ) {
 
 
-			uniforms.envMap.value = material.envMap;
+			uniforms.envMap.value = envMap;
 
 
 			// don't flip CubeTexture envMaps, flip everything else:
 			// don't flip CubeTexture envMaps, flip everything else:
 			//  WebGLRenderTargetCube will be flipped for backwards compatibility
 			//  WebGLRenderTargetCube will be flipped for backwards compatibility
 			//  WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
 			//  WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
 			// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
 			// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
-			uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;
+			uniforms.flipEnvMap.value = envMap.isCubeTexture ? - 1 : 1;
 
 
 			uniforms.reflectivity.value = material.reflectivity;
 			uniforms.reflectivity.value = material.reflectivity;
 			uniforms.refractionRatio.value = material.refractionRatio;
 			uniforms.refractionRatio.value = material.refractionRatio;
 
 
-			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
+			uniforms.maxMipLevel.value = properties.get( envMap ).__maxMipLevel;
 
 
 		}
 		}
 
 
@@ -2419,7 +2428,7 @@ function WebGLRenderer( parameters ) {
 
 
 	}
 	}
 
 
-	function refreshUniformsStandard( uniforms, material ) {
+	function refreshUniformsStandard( uniforms, material, environment ) {
 
 
 		uniforms.roughness.value = material.roughness;
 		uniforms.roughness.value = material.roughness;
 		uniforms.metalness.value = material.metalness;
 		uniforms.metalness.value = material.metalness;
@@ -2466,7 +2475,7 @@ function WebGLRenderer( parameters ) {
 
 
 		}
 		}
 
 
-		if ( material.envMap ) {
+		if ( material.envMap || environment ) {
 
 
 			//uniforms.envMap.value = material.envMap; // part of uniforms common
 			//uniforms.envMap.value = material.envMap; // part of uniforms common
 			uniforms.envMapIntensity.value = material.envMapIntensity;
 			uniforms.envMapIntensity.value = material.envMapIntensity;
@@ -2475,9 +2484,9 @@ function WebGLRenderer( parameters ) {
 
 
 	}
 	}
 
 
-	function refreshUniformsPhysical( uniforms, material ) {
+	function refreshUniformsPhysical( uniforms, material, environment ) {
 
 
-		refreshUniformsStandard( uniforms, material );
+		refreshUniformsStandard( uniforms, material, environment );
 
 
 		uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common
 		uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common
 
 
@@ -2609,7 +2618,7 @@ function WebGLRenderer( parameters ) {
 
 
 	function materialNeedsLights( material ) {
 	function materialNeedsLights( material ) {
 
 
-		return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial ||
+		return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial ||
 			material.isMeshStandardMaterial || material.isShadowMaterial ||
 			material.isMeshStandardMaterial || material.isShadowMaterial ||
 			( material.isShaderMaterial && material.lights === true );
 			( material.isShaderMaterial && material.lights === true );
 
 

+ 10 - 5
src/renderers/webgl/WebGLPrograms.js

@@ -110,7 +110,12 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 
 
 	}
 	}
 
 
-	this.getParameters = function ( material, lights, shadows, fog, nClipPlanes, nClipIntersection, object ) {
+	this.getParameters = function ( material, lights, shadows, scene, nClipPlanes, nClipIntersection, object ) {
+
+		var fog = scene.fog;
+		var environment = material.isMeshStandardMaterial ? scene.environment : null;
+
+		var envMap = material.envMap || environment;
 
 
 		var shaderID = shaderIDs[ material.type ];
 		var shaderID = shaderIDs[ material.type ];
 
 
@@ -151,10 +156,10 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 			mapEncoding: getTextureEncodingFromMap( material.map ),
 			mapEncoding: getTextureEncodingFromMap( material.map ),
 			matcap: !! material.matcap,
 			matcap: !! material.matcap,
 			matcapEncoding: getTextureEncodingFromMap( material.matcap ),
 			matcapEncoding: getTextureEncodingFromMap( material.matcap ),
-			envMap: !! material.envMap,
-			envMapMode: material.envMap && material.envMap.mapping,
-			envMapEncoding: getTextureEncodingFromMap( material.envMap ),
-			envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),
+			envMap: !! envMap,
+			envMapMode: envMap && envMap.mapping,
+			envMapEncoding: getTextureEncodingFromMap( envMap ),
+			envMapCubeUV: ( !! envMap ) && ( ( envMap.mapping === CubeUVReflectionMapping ) || ( envMap.mapping === CubeUVRefractionMapping ) ),
 			lightMap: !! material.lightMap,
 			lightMap: !! material.lightMap,
 			lightMapEncoding: getTextureEncodingFromMap( material.lightMap ),
 			lightMapEncoding: getTextureEncodingFromMap( material.lightMap ),
 			aoMap: !! material.aoMap,
 			aoMap: !! material.aoMap,

+ 5 - 0
src/scenes/Scene.js

@@ -11,7 +11,9 @@ function Scene() {
 	this.type = 'Scene';
 	this.type = 'Scene';
 
 
 	this.background = null;
 	this.background = null;
+	this.environment = null;
 	this.fog = null;
 	this.fog = null;
+
 	this.overrideMaterial = null;
 	this.overrideMaterial = null;
 
 
 	this.autoUpdate = true; // checked by the renderer
 	this.autoUpdate = true; // checked by the renderer
@@ -35,7 +37,9 @@ Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
 		Object3D.prototype.copy.call( this, source, recursive );
 		Object3D.prototype.copy.call( this, source, recursive );
 
 
 		if ( source.background !== null ) this.background = source.background.clone();
 		if ( source.background !== null ) this.background = source.background.clone();
+		if ( source.environment !== null ) this.environment = source.environment.clone();
 		if ( source.fog !== null ) this.fog = source.fog.clone();
 		if ( source.fog !== null ) this.fog = source.fog.clone();
+
 		if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
 		if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
 
 
 		this.autoUpdate = source.autoUpdate;
 		this.autoUpdate = source.autoUpdate;
@@ -50,6 +54,7 @@ Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
 		var data = Object3D.prototype.toJSON.call( this, meta );
 		var data = Object3D.prototype.toJSON.call( this, meta );
 
 
 		if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
 		if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
+		if ( this.environment !== null ) data.object.environment = this.environment.toJSON( meta );
 		if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
 		if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
 
 
 		return data;
 		return data;