Skip to content

Commit

Permalink
PMREMGenerator: Add size and position options to fromScene().
Browse files Browse the repository at this point in the history
  • Loading branch information
Mugen87 committed Feb 7, 2025
1 parent f35ec72 commit 2f84345
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 35 deletions.
10 changes: 6 additions & 4 deletions docs/api/en/extras/PMREMGenerator.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,21 @@ <h3>[name]( [param:WebGLRenderer renderer] )</h3>
<h2>Methods</h2>

<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>
<p>
[page:Scene scene] - The given scene.<br />
[page:Number sigma] - (optional) Specifies a blur radius in radians to be
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 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
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>

<h3>
Expand Down
29 changes: 20 additions & 9 deletions src/extras/PMREMGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const _axisDirections = [
/*@__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
* (PMREM) from a cubeMap environment texture. This allows different levels of
Expand Down Expand Up @@ -100,16 +102,21 @@ class PMREMGenerator {
* 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
* 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 {number} sigma
* @param {number} near
* @param {number} far
* @param {?Object} [options={}]
* @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();
_oldActiveCubeFace = this._renderer.getActiveCubeFace();
Expand All @@ -118,12 +125,12 @@ class PMREMGenerator {

this._renderer.xr.enabled = false;

this._setSize( 256 );
this._setSize( size );

const cubeUVRenderTarget = this._allocateTargets();
cubeUVRenderTarget.depthBuffer = true;

this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );
this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position );

if ( sigma > 0 ) {

Expand Down Expand Up @@ -320,7 +327,7 @@ class PMREMGenerator {

}

_sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) {
_sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position ) {

const fov = 90;
const aspect = 1;
Expand Down Expand Up @@ -372,17 +379,21 @@ class PMREMGenerator {
if ( col === 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 ) {

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 {

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 ] );

}

Expand Down
59 changes: 37 additions & 22 deletions src/renderers/common/extras/PMREMGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ const _axisDirections = [
/*@__PURE__*/ new Vector3( 1, 1, 1 )
];

const _origin = /*@__PURE__*/ new Vector3();

// maps blur materials to their uniforms dictionary

const _uniformsMap = new WeakMap();
Expand All @@ -93,8 +95,8 @@ const _outputDirection = /*@__PURE__*/ vec3( _direction.x, _direction.y, _direct
* higher roughness levels. In this way we maintain resolution to smoothly
* 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 {
Expand Down Expand Up @@ -128,30 +130,35 @@ class PMREMGenerator {
* 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
* 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 {number} [sigma=0] - The blur radius in radians.
* @param {number} [near=0.1] - The near plane distance.
* @param {number} [far=100] - The far plane distance.
* @param {?RenderTarget} [renderTarget=null] - The render target to use.
* @return {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>|RenderTarget} A Promise that resolve with the PMREM when the generation has been finished.
* When the renderer has been initialized already, a render target is returned.
* @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 ) {

console.warn( 'THREE.PMREMGenerator: .fromScene() called before the backend is initialized. Try using .fromSceneAsync() instead.' );

const cubeUVRenderTarget = renderTarget || this._allocateTargets();

this.fromSceneAsync( scene, sigma, near, far, cubeUVRenderTarget );

return cubeUVRenderTarget;
return this.fromSceneAsync( scene, sigma, near, far, options );

}

Expand All @@ -162,7 +169,7 @@ class PMREMGenerator {
const cubeUVRenderTarget = renderTarget || this._allocateTargets();
cubeUVRenderTarget.depthBuffer = true;

this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );
this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position );

if ( sigma > 0 ) {

Expand All @@ -189,15 +196,18 @@ class PMREMGenerator {
* @param {number} [sigma=0] - The blur radius in radians.
* @param {number} [near=0.1] - The near 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
*/
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();

return this.fromScene( scene, sigma, near, far, renderTarget );
return this.fromScene( scene, sigma, near, far, options );

}

Expand Down Expand Up @@ -458,7 +468,7 @@ class PMREMGenerator {

}

_sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) {
_sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position ) {

const cubeCamera = _cubeCamera;
cubeCamera.near = near;
Expand Down Expand Up @@ -528,17 +538,22 @@ class PMREMGenerator {
if ( col === 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 ) {

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 {

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 ] );


}

Expand Down

0 comments on commit 2f84345

Please sign in to comment.