Browse Source

Scene: Add background blur with PMREM. (#24752)

Michael Herzog 2 years ago
parent
commit
c22c1fcf1e

+ 5 - 0
docs/api/en/scenes/Scene.html

@@ -30,6 +30,11 @@
 		Can be set to a [page:Color] which sets the clear color, a [page:Texture] covering the canvas, a cubemap as a [page:CubeTexture] or an equirectangular as a [page:Texture] . Default is null.
 		Can be set to a [page:Color] which sets the clear color, a [page:Texture] covering the canvas, a cubemap as a [page:CubeTexture] or an equirectangular as a [page:Texture] . Default is null.
 		</p>
 		</p>
 
 
+		<h3>[property:Float backgroundBlurriness]</h3>
+		<p>
+			Sets the blurriness of the background. Only influences environment maps assigned to [page:Scene.background]. Valid input is a float between *0* and *1*. Default is *0*.
+		</p>
+
 		<h3>[property:Texture environment]</h3>
 		<h3>[property:Texture environment]</h3>
 		<p>
 		<p>
 		If not null, this texture is set as the environment map for all physical materials in the scene.
 		If not null, this texture is set as the environment map for all physical materials in the scene.

+ 5 - 0
docs/api/zh/scenes/Scene.html

@@ -32,6 +32,11 @@
 		或是 a cubemap as a [page:CubeTexture] or an equirectangular as a [page:Texture]。默认值为null。
 		或是 a cubemap as a [page:CubeTexture] or an equirectangular as a [page:Texture]。默认值为null。
 		</p>
 		</p>
 
 
+		<h3>[property:Float backgroundBlurriness]</h3>
+		<p>
+			Sets the blurriness of the background. Only influences environment maps assigned to [page:Scene.background]. Valid input is a float between *0* and *1*. Default is *0*.
+		</p>
+
 		<h3>[property:Texture environment]</h3>
 		<h3>[property:Texture environment]</h3>
 		<p>
 		<p>
     若该值不为null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。
     若该值不为null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。

BIN
examples/screenshots/webgl_tonemapping.jpg


+ 12 - 1
examples/webgl_tonemapping.html

@@ -42,7 +42,8 @@
 
 
 			const params = {
 			const params = {
 				exposure: 1.0,
 				exposure: 1.0,
-				toneMapping: 'ACESFilmic'
+				toneMapping: 'ACESFilmic',
+				blurriness: 1
 			};
 			};
 
 
 			const toneMappingOptions = {
 			const toneMappingOptions = {
@@ -86,6 +87,7 @@
 				);
 				);
 
 
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
+				scene.backgroundBlurriness = 1;
 
 
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
 				camera.position.set( - 1.8, 0.6, 2.7 );
 				camera.position.set( - 1.8, 0.6, 2.7 );
@@ -136,6 +138,15 @@
 
 
 					} );
 					} );
 
 
+				gui.add( params, 'blurriness', 0, 1 )
+
+					.onChange( function ( value ) {
+
+						scene.backgroundBlurriness = value;
+						render();
+
+					} );
+
 				updateGUI();
 				updateGUI();
 
 
 				gui.open();
 				gui.open();

+ 2 - 0
src/loaders/ObjectLoader.js

@@ -780,6 +780,8 @@ class ObjectLoader extends Loader {
 
 
 				}
 				}
 
 
+				if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness;
+
 				break;
 				break;
 
 
 			case 'PerspectiveCamera':
 			case 'PerspectiveCamera':

+ 1 - 1
src/renderers/WebGLRenderer.js

@@ -337,7 +337,7 @@ function WebGLRenderer( parameters = {} ) {
 		materials = new WebGLMaterials( _this, properties );
 		materials = new WebGLMaterials( _this, properties );
 		renderLists = new WebGLRenderLists();
 		renderLists = new WebGLRenderLists();
 		renderStates = new WebGLRenderStates( extensions, capabilities );
 		renderStates = new WebGLRenderStates( extensions, capabilities );
-		background = new WebGLBackground( _this, cubemaps, state, objects, _alpha, _premultipliedAlpha );
+		background = new WebGLBackground( _this, cubemaps, cubeuvmaps, state, objects, _alpha, _premultipliedAlpha );
 		shadowMap = new WebGLShadowMap( _this, objects, capabilities );
 		shadowMap = new WebGLShadowMap( _this, objects, capabilities );
 		uniformsGroups = new WebGLUniformsGroups( _gl, info, capabilities, state );
 		uniformsGroups = new WebGLUniformsGroups( _gl, info, capabilities, state );
 
 

+ 1 - 0
src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js

@@ -1,6 +1,7 @@
 export default /* glsl */`
 export default /* glsl */`
 #ifdef USE_ENVMAP
 #ifdef USE_ENVMAP
 
 
+	uniform float backgroundBlurriness;
 	uniform float envMapIntensity;
 	uniform float envMapIntensity;
 	uniform float flipEnvMap;
 	uniform float flipEnvMap;
 
 

+ 1 - 1
src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js

@@ -40,7 +40,7 @@ export default /* glsl */`
 
 
 	#elif defined( ENVMAP_TYPE_CUBE_UV )
 	#elif defined( ENVMAP_TYPE_CUBE_UV )
 
 
-		vec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );
+		vec4 envColor = textureCubeUV( envMap, reflectVec, backgroundBlurriness );
 
 
 	#else
 	#else
 
 

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

@@ -34,7 +34,8 @@ const UniformsLib = {
 		flipEnvMap: { value: - 1 },
 		flipEnvMap: { value: - 1 },
 		reflectivity: { value: 1.0 }, // basic, lambert, phong
 		reflectivity: { value: 1.0 }, // basic, lambert, phong
 		ior: { value: 1.5 }, // physical
 		ior: { value: 1.5 }, // physical
-		refractionRatio: { value: 0.98 } // basic, lambert, phong
+		refractionRatio: { value: 0.98 }, // basic, lambert, phong
+		backgroundBlurriness: { value: 0 } // background
 
 
 	},
 	},
 
 

+ 4 - 2
src/renderers/webgl/WebGLBackground.js

@@ -7,7 +7,7 @@ import { Mesh } from '../../objects/Mesh.js';
 import { ShaderLib } from '../shaders/ShaderLib.js';
 import { ShaderLib } from '../shaders/ShaderLib.js';
 import { cloneUniforms } from '../shaders/UniformsUtils.js';
 import { cloneUniforms } from '../shaders/UniformsUtils.js';
 
 
-function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipliedAlpha ) {
+function WebGLBackground( renderer, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha ) {
 
 
 	const clearColor = new Color( 0x000000 );
 	const clearColor = new Color( 0x000000 );
 	let clearAlpha = alpha === true ? 0 : 1;
 	let clearAlpha = alpha === true ? 0 : 1;
@@ -26,7 +26,8 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli
 
 
 		if ( background && background.isTexture ) {
 		if ( background && background.isTexture ) {
 
 
-			background = cubemaps.get( background );
+			const usePMREM = scene.backgroundBlurriness > 0; // use PMREM if the user wants to blur the background
+			background = ( usePMREM ? cubeuvmaps : cubemaps ).get( background );
 
 
 		}
 		}
 
 
@@ -103,6 +104,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli
 
 
 			boxMesh.material.uniforms.envMap.value = background;
 			boxMesh.material.uniforms.envMap.value = background;
 			boxMesh.material.uniforms.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? - 1 : 1;
 			boxMesh.material.uniforms.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? - 1 : 1;
+			boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness;
 
 
 			if ( currentBackground !== background ||
 			if ( currentBackground !== background ||
 				currentBackgroundVersion !== background.version ||
 				currentBackgroundVersion !== background.version ||

+ 5 - 0
src/scenes/Scene.js

@@ -14,6 +14,8 @@ class Scene extends Object3D {
 		this.environment = null;
 		this.environment = null;
 		this.fog = null;
 		this.fog = null;
 
 
+		this.backgroundBlurriness = 0;
+
 		this.overrideMaterial = null;
 		this.overrideMaterial = null;
 
 
 		if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
 		if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
@@ -32,6 +34,8 @@ class Scene extends Object3D {
 		if ( source.environment !== null ) this.environment = source.environment.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();
 
 
+		this.backgroundBlurriness = source.backgroundBlurriness;
+
 		if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
 		if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
 
 
 		this.matrixAutoUpdate = source.matrixAutoUpdate;
 		this.matrixAutoUpdate = source.matrixAutoUpdate;
@@ -45,6 +49,7 @@ class Scene extends Object3D {
 		const data = super.toJSON( meta );
 		const data = super.toJSON( meta );
 
 
 		if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
 		if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
+		if ( this.backgroundBlurriness > 0 ) data.backgroundBlurriness = this.backgroundBlurriness;
 
 
 		return data;
 		return data;