Переглянути джерело

PMREMGenerator: Add `size` and `position` options to `fromScene()`. (#30477)

* PMREMGenerator: Add `size` and `position` options to `fromScene()`.

* PMREMGenerator: Restore return type.
Michael Herzog 1 рік тому
батько
коміт
57e59a97c0

+ 6 - 4
docs/api/en/extras/PMREMGenerator.html

@@ -68,19 +68,21 @@
 		<h2>Methods</h2>
 		<h2>Methods</h2>
 
 
 		<h3>
 		<h3>
-			[method:WebGLRenderTarget fromScene]( [param:Scene scene], [param:Number sigma], [param:Number near], [param:Number far] )
+			[method:WebGLRenderTarget fromScene]( [param:Scene scene], [param:Number sigma], [param:Number near], [param:Number far], [param:Object options] )
 		</h3>
 		</h3>
 		<p>
 		<p>
 			[page:Scene scene] - The given scene.<br />
 			[page:Scene scene] - The given scene.<br />
 			[page:Number sigma] - (optional) Specifies a blur radius in radians to be
 			[page:Number sigma] - (optional) Specifies a blur radius in radians to be
 			applied to the scene before PMREM generation. Default is `0`.<br />
 			applied to the scene before PMREM generation. Default is `0`.<br />
 			[page:Number near] - (optional) The near plane value. Default is `0.1`.<br />
 			[page:Number near] - (optional) The near plane value. Default is `0.1`.<br />
-			[page:Number far] - (optional) The far plane value. Default is `100`.<br /><br />
+			[page:Number far] - (optional) The far plane value. Default is `100`.<br />
+			[page:Object options] - (optional) The configuration options. It allows to define
+			the `size` of the PMREM as a number well as the `position` of the internal cube camera as
+			an instance of `Vector3`.<br /><br />
 
 
 			Generates a PMREM from a supplied Scene, which can be faster than using an
 			Generates a PMREM from a supplied Scene, which can be faster than using an
 			image if networking bandwidth is low. Optional near and far planes ensure
 			image if networking bandwidth is low. Optional near and far planes ensure
-			the scene is rendered in its entirety (the cubeCamera is placed at the
-			origin).
+			the scene is rendered in its entirety.
 		</p>
 		</p>
 
 
 		<h3>
 		<h3>

+ 20 - 9
src/extras/PMREMGenerator.js

@@ -60,6 +60,8 @@ const _axisDirections = [
 	/*@__PURE__*/ new Vector3( - 1, 1, 1 ),
 	/*@__PURE__*/ new Vector3( - 1, 1, 1 ),
 	/*@__PURE__*/ new Vector3( 1, 1, 1 ) ];
 	/*@__PURE__*/ new Vector3( 1, 1, 1 ) ];
 
 
+const _origin = /*@__PURE__*/ new Vector3();
+
 /**
 /**
  * This class generates a Prefiltered, Mipmapped Radiance Environment Map
  * This class generates a Prefiltered, Mipmapped Radiance Environment Map
  * (PMREM) from a cubeMap environment texture. This allows different levels of
  * (PMREM) from a cubeMap environment texture. This allows different levels of
@@ -100,16 +102,21 @@ class PMREMGenerator {
 	 * Generates a PMREM from a supplied Scene, which can be faster than using an
 	 * Generates a PMREM from a supplied Scene, which can be faster than using an
 	 * image if networking bandwidth is low. Optional sigma specifies a blur radius
 	 * image if networking bandwidth is low. Optional sigma specifies a blur radius
 	 * in radians to be applied to the scene before PMREM generation. Optional near
 	 * in radians to be applied to the scene before PMREM generation. Optional near
-	 * and far planes ensure the scene is rendered in its entirety (the cubeCamera
-	 * is placed at the origin).
+	 * and far planes ensure the scene is rendered in its entirety.
 	 *
 	 *
 	 * @param {Scene} scene
 	 * @param {Scene} scene
 	 * @param {number} sigma
 	 * @param {number} sigma
 	 * @param {number} near
 	 * @param {number} near
 	 * @param {number} far
 	 * @param {number} far
+	 * @param {?Object} [options={}]
 	 * @return {WebGLRenderTarget}
 	 * @return {WebGLRenderTarget}
 	 */
 	 */
-	fromScene( scene, sigma = 0, near = 0.1, far = 100 ) {
+	fromScene( scene, sigma = 0, near = 0.1, far = 100, options = {} ) {
+
+		const {
+			size = 256,
+			position = _origin,
+		} = options;
 
 
 		_oldTarget = this._renderer.getRenderTarget();
 		_oldTarget = this._renderer.getRenderTarget();
 		_oldActiveCubeFace = this._renderer.getActiveCubeFace();
 		_oldActiveCubeFace = this._renderer.getActiveCubeFace();
@@ -118,12 +125,12 @@ class PMREMGenerator {
 
 
 		this._renderer.xr.enabled = false;
 		this._renderer.xr.enabled = false;
 
 
-		this._setSize( 256 );
+		this._setSize( size );
 
 
 		const cubeUVRenderTarget = this._allocateTargets();
 		const cubeUVRenderTarget = this._allocateTargets();
 		cubeUVRenderTarget.depthBuffer = true;
 		cubeUVRenderTarget.depthBuffer = true;
 
 
-		this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );
+		this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position );
 
 
 		if ( sigma > 0 ) {
 		if ( sigma > 0 ) {
 
 
@@ -320,7 +327,7 @@ class PMREMGenerator {
 
 
 	}
 	}
 
 
-	_sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) {
+	_sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position ) {
 
 
 		const fov = 90;
 		const fov = 90;
 		const aspect = 1;
 		const aspect = 1;
@@ -372,17 +379,21 @@ class PMREMGenerator {
 			if ( col === 0 ) {
 			if ( col === 0 ) {
 
 
 				cubeCamera.up.set( 0, upSign[ i ], 0 );
 				cubeCamera.up.set( 0, upSign[ i ], 0 );
-				cubeCamera.lookAt( forwardSign[ i ], 0, 0 );
+				cubeCamera.position.set( position.x, position.y, position.z );
+				cubeCamera.lookAt( position.x + forwardSign[ i ], position.y, position.z );
 
 
 			} else if ( col === 1 ) {
 			} else if ( col === 1 ) {
 
 
 				cubeCamera.up.set( 0, 0, upSign[ i ] );
 				cubeCamera.up.set( 0, 0, upSign[ i ] );
-				cubeCamera.lookAt( 0, forwardSign[ i ], 0 );
+				cubeCamera.position.set( position.x, position.y, position.z );
+				cubeCamera.lookAt( position.x, position.y + forwardSign[ i ], position.z );
+
 
 
 			} else {
 			} else {
 
 
 				cubeCamera.up.set( 0, upSign[ i ], 0 );
 				cubeCamera.up.set( 0, upSign[ i ], 0 );
-				cubeCamera.lookAt( 0, 0, forwardSign[ i ] );
+				cubeCamera.position.set( position.x, position.y, position.z );
+				cubeCamera.lookAt( position.x, position.y, position.z + forwardSign[ i ] );
 
 
 			}
 			}
 
 

+ 37 - 17
src/renderers/common/extras/PMREMGenerator.js

@@ -69,6 +69,8 @@ const _axisDirections = [
 	/*@__PURE__*/ new Vector3( 1, 1, 1 )
 	/*@__PURE__*/ new Vector3( 1, 1, 1 )
 ];
 ];
 
 
+const _origin = /*@__PURE__*/ new Vector3();
+
 // maps blur materials to their uniforms dictionary
 // maps blur materials to their uniforms dictionary
 
 
 const _uniformsMap = new WeakMap();
 const _uniformsMap = new WeakMap();
@@ -93,8 +95,8 @@ const _outputDirection = /*@__PURE__*/ vec3( _direction.x, _direction.y, _direct
  * higher roughness levels. In this way we maintain resolution to smoothly
  * higher roughness levels. In this way we maintain resolution to smoothly
  * interpolate diffuse lighting while limiting sampling computation.
  * interpolate diffuse lighting while limiting sampling computation.
  *
  *
- * Paper: Fast, Accurate Image-Based Lighting
- * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view
+ * Paper: Fast, Accurate Image-Based Lighting:
+ * {@link https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view}
 */
 */
 
 
 class PMREMGenerator {
 class PMREMGenerator {
@@ -128,20 +130,28 @@ class PMREMGenerator {
 	 * Generates a PMREM from a supplied Scene, which can be faster than using an
 	 * Generates a PMREM from a supplied Scene, which can be faster than using an
 	 * image if networking bandwidth is low. Optional sigma specifies a blur radius
 	 * image if networking bandwidth is low. Optional sigma specifies a blur radius
 	 * in radians to be applied to the scene before PMREM generation. Optional near
 	 * in radians to be applied to the scene before PMREM generation. Optional near
-	 * and far planes ensure the scene is rendered in its entirety (the cubeCamera
-	 * is placed at the origin).
+	 * and far planes ensure the scene is rendered in its entirety.
 	 *
 	 *
 	 * @param {Scene} scene - The scene to be captured.
 	 * @param {Scene} scene - The scene to be captured.
 	 * @param {number} [sigma=0] - The blur radius in radians.
 	 * @param {number} [sigma=0] - The blur radius in radians.
 	 * @param {number} [near=0.1] - The near plane distance.
 	 * @param {number} [near=0.1] - The near plane distance.
 	 * @param {number} [far=100] - The far plane distance.
 	 * @param {number} [far=100] - The far plane distance.
-	 * @param {?RenderTarget} [renderTarget=null] - The render target to use.
+	 * @param {Object} [options={}] - The configuration options.
+	 * @param {number} [options.size=256] - The texture size of the PMREM.
+	 * @param {Vector3} [options.renderTarget=origin] - The position of the internal cube camera that renders the scene.
+	 * @param {?RenderTarget} [options.renderTarget=null] - The render target to use.
 	 * @return {RenderTarget} The resulting PMREM.
 	 * @return {RenderTarget} The resulting PMREM.
 	 * @see fromSceneAsync
 	 * @see fromSceneAsync
 	 */
 	 */
-	fromScene( scene, sigma = 0, near = 0.1, far = 100, renderTarget = null ) {
+	fromScene( scene, sigma = 0, near = 0.1, far = 100, options = {} ) {
+
+		const {
+			size = 256,
+			position = _origin,
+			renderTarget = null,
+		} = options;
 
 
-		this._setSize( 256 );
+		this._setSize( size );
 
 
 		if ( this._hasInitialized === false ) {
 		if ( this._hasInitialized === false ) {
 
 
@@ -149,7 +159,9 @@ class PMREMGenerator {
 
 
 			const cubeUVRenderTarget = renderTarget || this._allocateTargets();
 			const cubeUVRenderTarget = renderTarget || this._allocateTargets();
 
 
-			this.fromSceneAsync( scene, sigma, near, far, cubeUVRenderTarget );
+			options.renderTarget = cubeUVRenderTarget;
+
+			this.fromSceneAsync( scene, sigma, near, far, options );
 
 
 			return cubeUVRenderTarget;
 			return cubeUVRenderTarget;
 
 
@@ -162,7 +174,7 @@ class PMREMGenerator {
 		const cubeUVRenderTarget = renderTarget || this._allocateTargets();
 		const cubeUVRenderTarget = renderTarget || this._allocateTargets();
 		cubeUVRenderTarget.depthBuffer = true;
 		cubeUVRenderTarget.depthBuffer = true;
 
 
-		this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );
+		this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position );
 
 
 		if ( sigma > 0 ) {
 		if ( sigma > 0 ) {
 
 
@@ -189,15 +201,18 @@ class PMREMGenerator {
 	 * @param {number} [sigma=0] - The blur radius in radians.
 	 * @param {number} [sigma=0] - The blur radius in radians.
 	 * @param {number} [near=0.1] - The near plane distance.
 	 * @param {number} [near=0.1] - The near plane distance.
 	 * @param {number} [far=100] - The far plane distance.
 	 * @param {number} [far=100] - The far plane distance.
-	 * @param {?RenderTarget} [renderTarget=null] - The render target to use.
-	 * @return {Promise<RenderTarget>} The resulting PMREM.
+	 * @param {Object} [options={}] - The configuration options.
+	 * @param {number} [options.size=256] - The texture size of the PMREM.
+	 * @param {Vector3} [options.renderTarget=origin] - The position of the internal cube camera that renders the scene.
+	 * @param {?RenderTarget} [options.renderTarget=null] - The render target to use.
+	 * @return {Promise<RenderTarget>} A Promise that resolve with the PMREM when the generation has been finished.
 	 * @see fromScene
 	 * @see fromScene
 	 */
 	 */
-	async fromSceneAsync( scene, sigma = 0, near = 0.1, far = 100, renderTarget = null ) {
+	async fromSceneAsync( scene, sigma = 0, near = 0.1, far = 100, options = {} ) {
 
 
 		if ( this._hasInitialized === false ) await this._renderer.init();
 		if ( this._hasInitialized === false ) await this._renderer.init();
 
 
-		return this.fromScene( scene, sigma, near, far, renderTarget );
+		return this.fromScene( scene, sigma, near, far, options );
 
 
 	}
 	}
 
 
@@ -458,7 +473,7 @@ class PMREMGenerator {
 
 
 	}
 	}
 
 
-	_sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) {
+	_sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position ) {
 
 
 		const cubeCamera = _cubeCamera;
 		const cubeCamera = _cubeCamera;
 		cubeCamera.near = near;
 		cubeCamera.near = near;
@@ -528,17 +543,22 @@ class PMREMGenerator {
 			if ( col === 0 ) {
 			if ( col === 0 ) {
 
 
 				cubeCamera.up.set( 0, upSign[ i ], 0 );
 				cubeCamera.up.set( 0, upSign[ i ], 0 );
-				cubeCamera.lookAt( forwardSign[ i ], 0, 0 );
+				cubeCamera.position.set( position.x, position.y, position.z );
+				cubeCamera.lookAt( position.x + forwardSign[ i ], position.y, position.z );
 
 
 			} else if ( col === 1 ) {
 			} else if ( col === 1 ) {
 
 
 				cubeCamera.up.set( 0, 0, upSign[ i ] );
 				cubeCamera.up.set( 0, 0, upSign[ i ] );
-				cubeCamera.lookAt( 0, forwardSign[ i ], 0 );
+				cubeCamera.position.set( position.x, position.y, position.z );
+				cubeCamera.lookAt( position.x, position.y + forwardSign[ i ], position.z );
+
 
 
 			} else {
 			} else {
 
 
 				cubeCamera.up.set( 0, upSign[ i ], 0 );
 				cubeCamera.up.set( 0, upSign[ i ], 0 );
-				cubeCamera.lookAt( 0, 0, forwardSign[ i ] );
+				cubeCamera.position.set( position.x, position.y, position.z );
+				cubeCamera.lookAt( position.x, position.y, position.z + forwardSign[ i ] );
+
 
 
 			}
 			}
 
 

粤ICP备19079148号