Skip to content

Commit b5d53e5

Browse files
authored
WebGPURenderer: Reuse Meshes in PMREMGenerator and pmremVersion logic (mrdoob#27988)
* PMREMGenerator: Reuse Meshes * TextureNode: Introduce `referenceNode` * PMREMNode: Added pmremVersion logic * update screenshot * fix webgl backend * cleanup example * fix webgl pmrem node * PMREMGenerator: Reuse PerspectiveCamera
1 parent e0d2ddf commit b5d53e5

File tree

4 files changed

+75
-40
lines changed

4 files changed

+75
-40
lines changed

examples/jsm/nodes/pmrem/PMREMNode.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { texture } from '../accessors/TextureNode.js';
44
import { textureCubeUV } from './PMREMUtils.js';
55
import { uniform } from '../core/UniformNode.js';
66
import { NodeUpdateType } from '../core/constants.js';
7-
import { nodeProxy } from '../shadernode/ShaderNode.js';
7+
import { nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
8+
import { WebGLCoordinateSystem } from 'three';
89

910
let _generator = null;
1011

@@ -26,7 +27,9 @@ function _getPMREMFromTexture( texture ) {
2627

2728
let cacheTexture = _cache.get( texture );
2829

29-
if ( cacheTexture === undefined ) {
30+
const pmremVersion = cacheTexture !== undefined ? cacheTexture.pmremVersion : - 1;
31+
32+
if ( pmremVersion !== texture.pmremVersion ) {
3033

3134
if ( texture.isCubeTexture ) {
3235

@@ -36,7 +39,7 @@ function _getPMREMFromTexture( texture ) {
3639

3740
}
3841

39-
cacheTexture = _generator.fromCubemap( texture );
42+
cacheTexture = _generator.fromCubemap( texture, cacheTexture );
4043

4144
} else {
4245

@@ -46,10 +49,12 @@ function _getPMREMFromTexture( texture ) {
4649

4750
}
4851

49-
cacheTexture = _generator.fromEquirectangular( texture );
52+
cacheTexture = _generator.fromEquirectangular( texture, cacheTexture );
5053

5154
}
5255

56+
cacheTexture.pmremVersion = texture.pmremVersion;
57+
5358
_cache.set( texture, cacheTexture );
5459

5560
}
@@ -104,13 +109,14 @@ class PMREMNode extends TempNode {
104109

105110
}
106111

107-
updateBefore( frame ) {
112+
updateBefore() {
108113

109114
let pmrem = this._pmrem;
110115

111-
if ( pmrem === null ) {
116+
const pmremVersion = pmrem ? pmrem.pmremVersion : - 1;
117+
const texture = this._value;
112118

113-
const texture = this._value;
119+
if ( pmremVersion !== texture.pmremVersion ) {
114120

115121
if ( texture.isPMREMTexture === true ) {
116122

@@ -154,6 +160,16 @@ class PMREMNode extends TempNode {
154160

155161
//
156162

163+
const texture = this.value;
164+
165+
if ( builder.renderer.coordinateSystem === WebGLCoordinateSystem && texture.isPMREMTexture !== true && texture.isRenderTargetTexture === true ) {
166+
167+
uvNode = vec3( uvNode.x.negate(), uvNode.yz );
168+
169+
}
170+
171+
//
172+
157173
let levelNode = this.levelNode;
158174

159175
if ( levelNode === null && builder.context.getTextureLevel ) {

examples/jsm/renderers/common/extras/PMREMGenerator.js

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];
4444
const MAX_SAMPLES = 20;
4545

4646
const _flatCamera = /*@__PURE__*/ new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
47+
const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera( 90, 1 );
4748
const _clearColor = /*@__PURE__*/ new Color();
4849
let _oldTarget = null;
4950
let _oldActiveCubeFace = 0;
@@ -106,10 +107,12 @@ class PMREMGenerator {
106107
this._lodPlanes = [];
107108
this._sizeLods = [];
108109
this._sigmas = [];
110+
this._lodMeshes = [];
109111

110112
this._blurMaterial = null;
111113
this._cubemapMaterial = null;
112114
this._equirectMaterial = null;
115+
this._backgroundBox = null;
113116

114117
}
115118

@@ -210,6 +213,12 @@ class PMREMGenerator {
210213

211214
if ( this._cubemapMaterial !== null ) this._cubemapMaterial.dispose();
212215
if ( this._equirectMaterial !== null ) this._equirectMaterial.dispose();
216+
if ( this._backgroundBox !== null ) {
217+
218+
this._backgroundBox.geometry.dispose();
219+
this._backgroundBox.material.dispose();
220+
221+
}
213222

214223
}
215224

@@ -297,7 +306,7 @@ class PMREMGenerator {
297306
this._pingPongRenderTarget = _createRenderTarget( width, height, params );
298307

299308
const { _lodMax } = this;
300-
( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes( _lodMax ) );
309+
( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas, lodMeshes: this._lodMeshes } = _createPlanes( _lodMax ) );
301310

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

@@ -309,16 +318,18 @@ class PMREMGenerator {
309318

310319
_compileMaterial( material ) {
311320

312-
const tmpMesh = new Mesh( this._lodPlanes[ 0 ], material );
321+
const tmpMesh = this._lodMeshes[ 0 ];
322+
tmpMesh.material = material;
323+
313324
this._renderer.compile( tmpMesh, _flatCamera );
314325

315326
}
316327

317328
_sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) {
318329

319-
const fov = 90;
320-
const aspect = 1;
321-
const cubeCamera = new PerspectiveCamera( fov, aspect, near, far );
330+
const cubeCamera = _cubeCamera;
331+
cubeCamera.near = near;
332+
cubeCamera.far = far;
322333

323334
// px, py, pz, nx, ny, nz
324335
const upSign = [ - 1, 1, - 1, - 1, - 1, - 1 ];
@@ -333,14 +344,20 @@ class PMREMGenerator {
333344
renderer.toneMapping = NoToneMapping;
334345
renderer.autoClear = false;
335346

336-
const backgroundMaterial = new MeshBasicMaterial( {
337-
name: 'PMREM.Background',
338-
side: BackSide,
339-
depthWrite: false,
340-
depthTest: false
341-
} );
347+
let backgroundBox = this._backgroundBox;
342348

343-
const backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial );
349+
if ( backgroundBox === null ) {
350+
351+
const backgroundMaterial = new MeshBasicMaterial( {
352+
name: 'PMREM.Background',
353+
side: BackSide,
354+
depthWrite: false,
355+
depthTest: false
356+
} );
357+
358+
backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial );
359+
360+
}
344361

345362
let useSolidColor = false;
346363
const background = scene.background;
@@ -349,15 +366,15 @@ class PMREMGenerator {
349366

350367
if ( background.isColor ) {
351368

352-
backgroundMaterial.color.copy( background );
369+
backgroundBox.material.color.copy( background );
353370
scene.background = null;
354371
useSolidColor = true;
355372

356373
}
357374

358375
} else {
359376

360-
backgroundMaterial.color.copy( _clearColor );
377+
backgroundBox.material.color.copy( _clearColor );
361378
useSolidColor = true;
362379

363380
}
@@ -401,9 +418,6 @@ class PMREMGenerator {
401418

402419
}
403420

404-
backgroundBox.geometry.dispose();
405-
backgroundBox.material.dispose();
406-
407421
renderer.toneMapping = toneMapping;
408422
renderer.autoClear = originalAutoClear;
409423
scene.background = background;
@@ -435,10 +449,11 @@ class PMREMGenerator {
435449
}
436450

437451
const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial;
438-
const mesh = new Mesh( this._lodPlanes[ 0 ], material );
439-
440452
material.fragmentNode.value = texture;
441453

454+
const mesh = this._lodMeshes[ 0 ];
455+
mesh.material = material;
456+
442457
const size = this._cubeSize;
443458

444459
_setViewport( cubeUVRenderTarget, 0, 0, 3 * size, 2 * size );
@@ -506,15 +521,16 @@ class PMREMGenerator {
506521

507522
if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) {
508523

509-
console.error(
510-
'blur direction must be either latitudinal or longitudinal!' );
524+
console.error( 'blur direction must be either latitudinal or longitudinal!' );
511525

512526
}
513527

514528
// Number of standard deviations at which to cut off the discrete approximation.
515529
const STANDARD_DEVIATIONS = 3;
516530

517-
const blurMesh = new Mesh( this._lodPlanes[ lodOut ], blurMaterial );
531+
const blurMesh = this._lodMeshes[ lodOut ];
532+
blurMesh.material = blurMaterial;
533+
518534
const blurUniforms = blurMaterial.uniforms;
519535

520536
const pixels = this._sizeLods[ lodIn ] - 1;
@@ -557,6 +573,8 @@ class PMREMGenerator {
557573

558574
}
559575

576+
targetIn.texture.frame = ( targetIn.texture.frame || 0 ) + 1;
577+
560578
blurUniforms.envMap.value = targetIn.texture;
561579
blurUniforms.samples.value = samples;
562580
blurUniforms.weights.array = weights;
@@ -589,6 +607,7 @@ function _createPlanes( lodMax ) {
589607
const lodPlanes = [];
590608
const sizeLods = [];
591609
const sigmas = [];
610+
const lodMeshes = [];
592611

593612
let lod = lodMax;
594613

@@ -653,6 +672,7 @@ function _createPlanes( lodMax ) {
653672
planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );
654673
planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );
655674
lodPlanes.push( planes );
675+
lodMeshes.push( new Mesh( planes, null ) );
656676

657677
if ( lod > LOD_MIN ) {
658678

@@ -662,7 +682,7 @@ function _createPlanes( lodMax ) {
662682

663683
}
664684

665-
return { lodPlanes, sizeLods, sigmas };
685+
return { lodPlanes, sizeLods, sigmas, lodMeshes };
666686

667687
}
668688

-14 Bytes
Loading

examples/webgpu_cubemap_dynamic.html

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,6 @@
6060

6161
}
6262

63-
renderer = new WebGPURenderer( { antialias: true } );
64-
renderer.setPixelRatio( window.devicePixelRatio );
65-
renderer.setSize( window.innerWidth, window.innerHeight );
66-
renderer.setAnimationLoop( animation );
67-
renderer.toneMapping = THREE.ACESFilmicToneMapping;
68-
document.body.appendChild( renderer.domElement );
69-
70-
window.addEventListener( 'resize', onWindowResized );
71-
7263
stats = new Stats();
7364
document.body.appendChild( stats.dom );
7465

@@ -134,6 +125,15 @@
134125

135126
//
136127

128+
renderer = new WebGPURenderer( { antialias: true, forceWebGL: false } );
129+
renderer.setPixelRatio( window.devicePixelRatio );
130+
renderer.setSize( window.innerWidth, window.innerHeight );
131+
renderer.setAnimationLoop( animation );
132+
renderer.toneMapping = THREE.ACESFilmicToneMapping;
133+
document.body.appendChild( renderer.domElement );
134+
135+
window.addEventListener( 'resize', onWindowResized );
136+
137137
controls = new OrbitControls( camera, renderer.domElement );
138138
controls.autoRotate = true;
139139

@@ -159,7 +159,6 @@
159159

160160
const time = msTime / 1000;
161161

162-
if ( ! cube ) return;
163162
cube.position.x = Math.cos( time ) * 30;
164163
cube.position.y = Math.sin( time ) * 30;
165164
cube.position.z = Math.sin( time ) * 30;

0 commit comments

Comments
 (0)