Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 50 additions & 29 deletions src/extras/PMREMGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];
const MAX_SAMPLES = 20;

// GGX VNDF importance sampling configuration
const GGX_SAMPLES = 2048;
const GGX_SAMPLES = 512;

const _flatCamera = /*@__PURE__*/ new OrthographicCamera();
const _clearColor = /*@__PURE__*/ new Color();
Expand Down Expand Up @@ -77,16 +77,17 @@ class PMREMGenerator {

this._lodMax = 0;
this._cubeSize = 0;
this._lodPlanes = [];
this._sizeLods = [];
this._sigmas = [];
this._lodMeshes = [];

this._backgroundBox = null;

this._blurMaterial = null;
this._ggxMaterial = null;
this._cubemapMaterial = null;
this._equirectMaterial = null;

this._compileMaterial( this._blurMaterial );
this._blurMaterial = null;
this._ggxMaterial = null;

}

Expand Down Expand Up @@ -211,6 +212,13 @@ class PMREMGenerator {
if ( this._cubemapMaterial !== null ) this._cubemapMaterial.dispose();
if ( this._equirectMaterial !== null ) this._equirectMaterial.dispose();

if ( this._backgroundBox !== null ) {

this._backgroundBox.geometry.dispose();
this._backgroundBox.material.dispose();

}

}

// private interface
Expand All @@ -229,9 +237,9 @@ class PMREMGenerator {

if ( this._pingPongRenderTarget !== null ) this._pingPongRenderTarget.dispose();

for ( let i = 0; i < this._lodPlanes.length; i ++ ) {
for ( let i = 0; i < this._lodMeshes.length; i ++ ) {

this._lodPlanes[ i ].dispose();
this._lodMeshes[ i ].geometry.dispose();

}

Expand Down Expand Up @@ -303,7 +311,7 @@ class PMREMGenerator {
this._pingPongRenderTarget = _createRenderTarget( width, height, params );

const { _lodMax } = this;
( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes( _lodMax ) );
( { lodMeshes: this._lodMeshes, sizeLods: this._sizeLods, sigmas: this._sigmas } = _createPlanes( _lodMax ) );

this._blurMaterial = _getBlurShader( _lodMax, width, height );

Expand All @@ -315,8 +323,8 @@ class PMREMGenerator {

_compileMaterial( material ) {

const tmpMesh = new Mesh( this._lodPlanes[ 0 ], material );
this._renderer.compile( tmpMesh, _flatCamera );
const mesh = new Mesh( new BufferGeometry(), material );
this._renderer.compile( mesh, _flatCamera );

}

Expand Down Expand Up @@ -347,16 +355,25 @@ class PMREMGenerator {

}

const backgroundMaterial = new MeshBasicMaterial( {
name: 'PMREM.Background',
side: BackSide,
depthWrite: false,
depthTest: false,
} );
if ( this._backgroundBox === null ) {

const backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial );
this._backgroundBox = new Mesh(
new BoxGeometry(),
new MeshBasicMaterial( {
name: 'PMREM.Background',
side: BackSide,
depthWrite: false,
depthTest: false,
} )
);

}

const backgroundBox = this._backgroundBox;
const backgroundMaterial = backgroundBox.material;

let useSolidColor = false;

const background = scene.background;

if ( background ) {
Expand Down Expand Up @@ -417,9 +434,6 @@ class PMREMGenerator {

}

backgroundBox.geometry.dispose();
backgroundBox.material.dispose();

renderer.toneMapping = toneMapping;
renderer.autoClear = originalAutoClear;
scene.background = background;
Expand Down Expand Up @@ -453,7 +467,9 @@ class PMREMGenerator {
}

const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial;
const mesh = new Mesh( this._lodPlanes[ 0 ], material );

const mesh = this._lodMeshes[ 0 ];
mesh.material = material;

const uniforms = material.uniforms;

Expand All @@ -473,7 +489,8 @@ class PMREMGenerator {
const renderer = this._renderer;
const autoClear = renderer.autoClear;
renderer.autoClear = false;
const n = this._lodPlanes.length;

const n = this._lodMeshes.length;

// Use GGX VNDF importance sampling
for ( let i = 1; i < n; i ++ ) {
Expand Down Expand Up @@ -511,12 +528,14 @@ class PMREMGenerator {
}

const ggxMaterial = this._ggxMaterial;
const ggxMesh = new Mesh( this._lodPlanes[ lodOut ], ggxMaterial );
const ggxMesh = this._lodMeshes[ lodOut ];
ggxMesh.material = ggxMaterial;

const ggxUniforms = ggxMaterial.uniforms;

// Calculate incremental roughness between LOD levels
const targetRoughness = lodOut / ( this._lodPlanes.length - 1 );
const sourceRoughness = lodIn / ( this._lodPlanes.length - 1 );
const targetRoughness = lodOut / ( this._lodMeshes.length - 1 );
const sourceRoughness = lodIn / ( this._lodMeshes.length - 1 );
const incrementalRoughness = Math.sqrt( targetRoughness * targetRoughness - sourceRoughness * sourceRoughness );

// Apply blur strength mapping for better quality across the roughness range
Expand Down Expand Up @@ -604,7 +623,9 @@ class PMREMGenerator {
// Number of standard deviations at which to cut off the discrete approximation.
const STANDARD_DEVIATIONS = 3;

const blurMesh = new Mesh( this._lodPlanes[ lodOut ], blurMaterial );
const blurMesh = this._lodMeshes[ lodOut ];
blurMesh.material = blurMaterial;

const blurUniforms = blurMaterial.uniforms;

const pixels = this._sizeLods[ lodIn ] - 1;
Expand Down Expand Up @@ -678,9 +699,9 @@ class PMREMGenerator {

function _createPlanes( lodMax ) {

const lodPlanes = [];
const sizeLods = [];
const sigmas = [];
const lodMeshes = [];

let lod = lodMax;

Expand Down Expand Up @@ -742,7 +763,7 @@ function _createPlanes( lodMax ) {
planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) );
planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );
planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );
lodPlanes.push( planes );
lodMeshes.push( new Mesh( planes, null ) );

if ( lod > LOD_MIN ) {

Expand All @@ -752,7 +773,7 @@ function _createPlanes( lodMax ) {

}

return { lodPlanes, sizeLods, sigmas };
return { lodMeshes, sizeLods, sigmas };

}

Expand Down
54 changes: 28 additions & 26 deletions src/renderers/common/extras/PMREMGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];
const MAX_SAMPLES = 20;

// GGX VNDF importance sampling configuration
const GGX_SAMPLES = 2048;
const GGX_SAMPLES = 512;

const _flatCamera = /*@__PURE__*/ new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera( 90, 1 );
Expand Down Expand Up @@ -98,13 +98,13 @@ class PMREMGenerator {

this._lodMax = 0;
this._cubeSize = 0;
this._lodPlanes = [];
this._sizeLods = [];
this._sigmas = [];
this._lodMeshes = [];

this._blurMaterial = null;
this._ggxMaterial = null;

this._cubemapMaterial = null;
this._equirectMaterial = null;
this._backgroundBox = null;
Expand Down Expand Up @@ -398,9 +398,9 @@ class PMREMGenerator {

if ( this._pingPongRenderTarget !== null ) this._pingPongRenderTarget.dispose();

for ( let i = 0; i < this._lodPlanes.length; i ++ ) {
for ( let i = 0; i < this._lodMeshes.length; i ++ ) {

this._lodPlanes[ i ].dispose();
this._lodMeshes[ i ].geometry.dispose();

}

Expand Down Expand Up @@ -456,7 +456,7 @@ class PMREMGenerator {
this._pingPongRenderTarget = _createRenderTarget( renderTarget.width, renderTarget.height );

const { _lodMax } = this;
( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas, lodMeshes: this._lodMeshes } = _createPlanes( _lodMax ) );
( { lodMeshes: this._lodMeshes, sizeLods: this._sizeLods, sigmas: this._sigmas } = _createPlanes( _lodMax ) );

this._blurMaterial = _getBlurShader( _lodMax, renderTarget.width, renderTarget.height );

Expand All @@ -466,8 +466,8 @@ class PMREMGenerator {

async _compileMaterial( material ) {

const tmpMesh = new Mesh( this._lodPlanes[ 0 ], material );
await this._renderer.compile( tmpMesh, _flatCamera );
const mesh = new Mesh( new BufferGeometry(), material );
await this._renderer.compile( mesh, _flatCamera );

}

Expand All @@ -489,37 +489,40 @@ class PMREMGenerator {

renderer.autoClear = false;

let backgroundBox = this._backgroundBox;

if ( backgroundBox === null ) {

const backgroundMaterial = new MeshBasicMaterial( {
name: 'PMREM.Background',
side: BackSide,
depthWrite: false,
depthTest: false
} );
if ( this._backgroundBox === null ) {

backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial );
this._backgroundBox = new Mesh(
new BoxGeometry(),
new MeshBasicMaterial( {
name: 'PMREM.Background',
side: BackSide,
depthWrite: false,
depthTest: false,
} )
);

}

const backgroundBox = this._backgroundBox;
const backgroundMaterial = backgroundBox.material;

let useSolidColor = false;

const background = scene.background;

if ( background ) {

if ( background.isColor ) {

backgroundBox.material.color.copy( background );
backgroundMaterial.color.copy( background );
scene.background = null;
useSolidColor = true;

}

} else {

backgroundBox.material.color.copy( _clearColor );
backgroundMaterial.color.copy( _clearColor );
useSolidColor = true;

}
Expand Down Expand Up @@ -617,7 +620,8 @@ class PMREMGenerator {
const renderer = this._renderer;
const autoClear = renderer.autoClear;
renderer.autoClear = false;
const n = this._lodPlanes.length;

const n = this._lodMeshes.length;

// Use GGX VNDF importance sampling
for ( let i = 1; i < n; i ++ ) {
Expand Down Expand Up @@ -660,8 +664,8 @@ class PMREMGenerator {
const ggxUniforms = _uniformsMap.get( ggxMaterial );

// Calculate incremental roughness between LOD levels
const targetRoughness = lodOut / ( this._lodPlanes.length - 1 );
const sourceRoughness = lodIn / ( this._lodPlanes.length - 1 );
const targetRoughness = lodOut / ( this._lodMeshes.length - 1 );
const sourceRoughness = lodIn / ( this._lodMeshes.length - 1 );
const incrementalRoughness = Math.sqrt( targetRoughness * targetRoughness - sourceRoughness * sourceRoughness );

// Apply blur strength mapping for better quality across the roughness range
Expand Down Expand Up @@ -826,7 +830,6 @@ class PMREMGenerator {

function _createPlanes( lodMax ) {

const lodPlanes = [];
const sizeLods = [];
const sigmas = [];
const lodMeshes = [];
Expand Down Expand Up @@ -893,7 +896,6 @@ function _createPlanes( lodMax ) {
planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) );
planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );
planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );
lodPlanes.push( planes );
lodMeshes.push( new Mesh( planes, null ) );

if ( lod > LOD_MIN ) {
Expand All @@ -904,7 +906,7 @@ function _createPlanes( lodMax ) {

}

return { lodPlanes, sizeLods, sigmas, lodMeshes };
return { lodMeshes, sizeLods, sigmas };

}

Expand Down