Skip to content

Commit 12b08b2

Browse files
authored
WebGPURenderer: PMREM (mrdoob#27829)
* WebGPURenderer: PMREM (WIP) * add temporary example * Added fromCubemap() * added pmrem and examples * cleanup * fix circular dependency * Revert "fix circular dependency" This reverts commit 83d6882. * update pmrem examples * NodeBuilder: Rename .getRenderTarget() -> .createRenderTarget() * fix circular dependency (2) * revision * revision * update `webgpu_cubemap_mix` example * update `webgpu_cubemap_adjustments` example * update `webgpu_equirectangular` example * update screenshots
1 parent ef80ac7 commit 12b08b2

31 files changed

+1626
-142
lines changed

examples/files.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,9 @@
372372
"webgpu_tsl_editor",
373373
"webgpu_tsl_transpiler",
374374
"webgpu_video_panorama",
375+
"webgpu_pmrem_cubemap",
376+
"webgpu_pmrem_equirectangular",
377+
"webgpu_pmrem_scene",
375378
"webgpu_postprocessing_afterimage",
376379
"webgpu_postprocessing_anamorphic",
377380
"webgpu_mirror",

examples/jsm/nodes/Nodes.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ export { default as RemapNode, remap, remapClamp } from './utils/RemapNode.js';
6464
export { default as RotateUVNode, rotateUV } from './utils/RotateUVNode.js';
6565
export { default as RotateNode, rotate } from './utils/RotateNode.js';
6666
export { default as SetNode } from './utils/SetNode.js';
67-
export { default as SpecularMIPLevelNode, specularMIPLevel } from './utils/SpecularMIPLevelNode.js';
6867
export { default as SplitNode } from './utils/SplitNode.js';
6968
export { default as SpriteSheetUVNode, spritesheetUV } from './utils/SpriteSheetUVNode.js';
7069
export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js';
@@ -160,6 +159,10 @@ export { default as EnvironmentNode } from './lighting/EnvironmentNode.js';
160159
export { default as AONode } from './lighting/AONode.js';
161160
export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js';
162161

162+
// pmrem
163+
export { default as PMREMNode, pmremTexture } from './pmrem/PMREMNode.js';
164+
export * as PMREMUtils from './pmrem/PMREMUtils.js';
165+
163166
// procedural
164167
export { default as CheckerNode, checker } from './procedural/CheckerNode.js';
165168

examples/jsm/nodes/accessors/TextureNode.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,6 @@ class TextureNode extends UniformNode {
126126

127127
}
128128

129-
if ( levelNode !== null && builder.context.getTextureLevelAlgorithm !== undefined ) {
130-
131-
levelNode = builder.context.getTextureLevelAlgorithm( this, levelNode );
132-
133-
}
134-
135129
//
136130

137131
properties.uvNode = uvNode;

examples/jsm/nodes/core/NodeBuilder.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import { getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js';
2323
import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js';
2424
import ChainMap from '../../renderers/common/ChainMap.js';
2525

26+
import PMREMGenerator from '../../renderers/common/extras/PMREMGenerator.js';
27+
2628
const uniformsGroupCache = new ChainMap();
2729

2830
const typeFromLength = new Map( [
@@ -113,18 +115,26 @@ class NodeBuilder {
113115

114116
}
115117

116-
getRenderTarget( width, height, options ) {
118+
createRenderTarget( width, height, options ) {
117119

118120
return new RenderTarget( width, height, options );
119121

120122
}
121123

122-
getCubeRenderTarget( size, options ) {
124+
createCubeRenderTarget( size, options ) {
123125

124126
return new CubeRenderTarget( size, options );
125127

126128
}
127129

130+
createPMREMGenerator() {
131+
132+
// TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support
133+
134+
return new PMREMGenerator( this.renderer );
135+
136+
}
137+
128138
includes( node ) {
129139

130140
return this.nodes.includes( node );
@@ -1168,6 +1178,8 @@ class NodeBuilder {
11681178

11691179
createNodeMaterial( type = 'NodeMaterial' ) {
11701180

1181+
// TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support
1182+
11711183
return createNodeMaterialFromType( type );
11721184

11731185
}

examples/jsm/nodes/lighting/AnalyticLightNode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class AnalyticLightNode extends LightingNode {
6363
}
6464

6565
const shadow = this.light.shadow;
66-
const rtt = builder.getRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
66+
const rtt = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
6767

6868
const depthTexture = new DepthTexture();
6969
depthTexture.minFilter = NearestFilter;

examples/jsm/nodes/lighting/EnvironmentNode.js

Lines changed: 10 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import LightingNode from './LightingNode.js';
22
import { cache } from '../core/CacheNode.js';
33
import { context } from '../core/ContextNode.js';
4-
import { maxMipLevel } from '../utils/MaxMipLevelNode.js';
54
import { roughness, clearcoatRoughness } from '../core/PropertyNode.js';
6-
import { equirectUV } from '../utils/EquirectUVNode.js';
7-
import { specularMIPLevel } from '../utils/SpecularMIPLevelNode.js';
85
import { cameraViewMatrix } from '../accessors/CameraNode.js';
96
import { transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld } from '../accessors/NormalNode.js';
107
import { positionViewDirection } from '../accessors/PositionNode.js';
118
import { addNodeClass } from '../core/Node.js';
12-
import { vec2 } from '../shadernode/ShaderNode.js';
13-
import { cubeTexture } from '../accessors/CubeTextureNode.js';
9+
import { float } from '../shadernode/ShaderNode.js';
1410
import { reference } from '../accessors/ReferenceNode.js';
11+
import { pmremTexture } from '../pmrem/PMREMNode.js';
1512

1613
const envNodeCache = new WeakMap();
1714

@@ -29,19 +26,13 @@ class EnvironmentNode extends LightingNode {
2926

3027
let envNode = this.envNode;
3128

32-
if ( envNode.isTextureNode && envNode.value.isCubeTexture !== true ) {
29+
if ( envNode.isTextureNode ) {
3330

3431
let cacheEnvNode = envNodeCache.get( envNode.value );
3532

3633
if ( cacheEnvNode === undefined ) {
3734

38-
const texture = envNode.value;
39-
const renderer = builder.renderer;
40-
41-
// @TODO: Add dispose logic here
42-
const cubeRTT = builder.getCubeRenderTarget( 512 ).fromEquirectangularTexture( renderer, texture );
43-
44-
cacheEnvNode = cubeTexture( cubeRTT.texture );
35+
cacheEnvNode = pmremTexture( envNode.value );
4536

4637
envNodeCache.set( envNode.value, cacheEnvNode );
4738

@@ -86,12 +77,9 @@ class EnvironmentNode extends LightingNode {
8677
const createRadianceContext = ( roughnessNode, normalViewNode ) => {
8778

8879
let reflectVec = null;
89-
let textureUVNode = null;
9080

9181
return {
92-
getUV: ( textureNode ) => {
93-
94-
let node = null;
82+
getUV: () => {
9583

9684
if ( reflectVec === null ) {
9785

@@ -101,75 +89,29 @@ const createRadianceContext = ( roughnessNode, normalViewNode ) => {
10189

10290
}
10391

104-
if ( textureNode.isCubeTextureNode ) {
105-
106-
node = reflectVec;
107-
108-
} else if ( textureNode.isTextureNode ) {
109-
110-
if ( textureUVNode === null ) {
111-
112-
// @TODO: Needed PMREM
113-
114-
textureUVNode = equirectUV( reflectVec );
115-
116-
}
117-
118-
node = textureUVNode;
119-
120-
}
121-
122-
return node;
92+
return reflectVec;
12393

12494
},
12595
getTextureLevel: () => {
12696

12797
return roughnessNode;
12898

129-
},
130-
getTextureLevelAlgorithm: ( textureNode, levelNode ) => {
131-
132-
return specularMIPLevel( textureNode, levelNode );
133-
13499
}
135100
};
136101

137102
};
138103

139104
const createIrradianceContext = ( normalWorldNode ) => {
140105

141-
let textureUVNode = null;
142-
143106
return {
144-
getUV: ( textureNode ) => {
145-
146-
let node = null;
147-
148-
if ( textureNode.isCubeTextureNode ) {
149-
150-
node = normalWorldNode;
151-
152-
} else if ( textureNode.isTextureNode ) {
153-
154-
if ( textureUVNode === null ) {
107+
getUV: () => {
155108

156-
// @TODO: Needed PMREM
157-
158-
textureUVNode = equirectUV( normalWorldNode );
159-
textureUVNode = vec2( textureUVNode.x, textureUVNode.y.oneMinus() );
160-
161-
}
162-
163-
node = textureUVNode;
164-
165-
}
166-
167-
return node;
109+
return normalWorldNode;
168110

169111
},
170-
getTextureLevel: ( textureNode ) => {
112+
getTextureLevel: () => {
171113

172-
return maxMipLevel( textureNode );
114+
return float( 1.0 );
173115

174116
}
175117
};

0 commit comments

Comments
 (0)