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.
 		</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>
 		<p>
 		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。
 		</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>
 		<p>
     若该值不为null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。

BIN
examples/screenshots/webgl_tonemapping.jpg


+ 12 - 1
examples/webgl_tonemapping.html

@@ -42,7 +42,8 @@
 
 			const params = {
 				exposure: 1.0,
-				toneMapping: 'ACESFilmic'
+				toneMapping: 'ACESFilmic',
+				blurriness: 1
 			};
 
 			const toneMappingOptions = {
@@ -86,6 +87,7 @@
 				);
 
 				scene = new THREE.Scene();
+				scene.backgroundBlurriness = 1;
 
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
 				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();
 
 				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;
 
 			case 'PerspectiveCamera':

+ 1 - 1
src/renderers/WebGLRenderer.js

@@ -337,7 +337,7 @@ function WebGLRenderer( parameters = {} ) {
 		materials = new WebGLMaterials( _this, properties );
 		renderLists = new WebGLRenderLists();
 		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 );
 		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 */`
 #ifdef USE_ENVMAP
 
+	uniform float backgroundBlurriness;
 	uniform float envMapIntensity;
 	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 )
 
-		vec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );
+		vec4 envColor = textureCubeUV( envMap, reflectVec, backgroundBlurriness );
 
 	#else
 

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

@@ -34,7 +34,8 @@ const UniformsLib = {
 		flipEnvMap: { value: - 1 },
 		reflectivity: { value: 1.0 }, // basic, lambert, phong
 		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 { 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 );
 	let clearAlpha = alpha === true ? 0 : 1;
@@ -26,7 +26,8 @@ function WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipli
 
 		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.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? - 1 : 1;
+			boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness;
 
 			if ( currentBackground !== background ||
 				currentBackgroundVersion !== background.version ||

+ 5 - 0
src/scenes/Scene.js

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