Skip to content

Commit 84b6feb

Browse files
WebGPURenderer: Array-Based RenderTarget Refactor (#30959)
* ShadowNode: Inherit camera.layers only if shadow.layers is not set * Fix layers check * invert condition * restore after render * move array creation to module scope * WebGPURenderer: Refactor Texture Arrays * fix conflicts * cleanup and fix multiview * revert webgpu pipeline utils * Fix StorageTexture depth * fix fbo setSize * update build * fix xrmanager depth missing arg * bump build * revert build
1 parent d088fc1 commit 84b6feb

24 files changed

+115
-269
lines changed

examples/jsm/helpers/TextureHelperGPU.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class TextureHelper extends Mesh {
5151

5252
colorNode = texture3D( texture ).sample( uvw );
5353

54-
} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
54+
} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
5555

5656
colorNode = textureNode( texture ).sample( uvw.xy ).depth( uvw.z );
5757

@@ -100,7 +100,7 @@ function getImageCount( texture ) {
100100

101101
return 6;
102102

103-
} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
103+
} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
104104

105105
return texture.image.depth;
106106

@@ -122,7 +122,7 @@ function getAlpha( texture ) {
122122

123123
return 1;
124124

125-
} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
125+
} else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
126126

127127
return Math.max( 1 / texture.image.depth, 0.25 );
128128

@@ -192,7 +192,7 @@ function createSliceGeometry( texture, width, height, depth ) {
192192
const v = texture.flipY ? uv.getY( j ) : 1 - uv.getY( j );
193193
const w = sliceCount === 1
194194
? 1
195-
: texture.isDataArrayTexture || texture.isCompressedArrayTexture
195+
: texture.isArrayTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture
196196
? i
197197
: i / ( sliceCount - 1 );
198198

examples/jsm/tsl/shadows/TileShadowNode.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
ShadowBaseNode,
55
Plane,
66
Line3,
7-
DepthArrayTexture,
7+
DepthTexture,
88
LessCompare,
99
Vector2,
1010
RedFormat,
@@ -159,10 +159,10 @@ class TileShadowNode extends ShadowBaseNode {
159159
// Clear existing lights/nodes if re-initializing
160160
this.disposeLightsAndNodes();
161161

162-
const depthTexture = new DepthArrayTexture( shadowWidth, shadowHeight, tileCount );
162+
const depthTexture = new DepthTexture( shadowWidth, shadowHeight, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, tileCount );
163163
depthTexture.compareFunction = LessCompare;
164164
depthTexture.name = 'ShadowDepthArrayTexture';
165-
const shadowMap = builder.createRenderTargetArray( shadowWidth, shadowHeight, tileCount, { format: RedFormat } );
165+
const shadowMap = builder.createRenderTarget( shadowWidth, shadowHeight, { format: RedFormat, depth: tileCount } );
166166
shadowMap.depthTexture = depthTexture;
167167
shadowMap.texture.name = 'ShadowTexture';
168168
this.shadowMap = shadowMap;

examples/webgpu_rendertarget_2d-array_3d.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,9 @@
211211
materialQuad.depthTest = false;
212212
materialQuad.outputNode = vec4( texture( mapArray ).depth( uZCoord ).rgb, 1 );
213213

214-
const fboArray = new THREE.RenderTargetArray( size.width, size.height, size.depth, {
214+
const fboArray = new THREE.RenderTarget( size.width, size.height, {
215215
depthBuffer: false,
216+
depth: size.depth
216217
} );
217218
fboArray.texture.name = 'RenderTargetArray';
218219

examples/webgpu_shadowmap_array.html

+2-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
async function init() {
4646

4747
// Renderer setup
48-
renderer = new THREE.WebGPURenderer( { antialias: true, forceWebGL: false } );
48+
renderer = new THREE.WebGPURenderer( { antialias: true } );
4949
renderer.setPixelRatio( window.devicePixelRatio );
5050
renderer.setSize( window.innerWidth, window.innerHeight );
5151
renderer.setAnimationLoop( animate );
@@ -87,8 +87,7 @@
8787
// Set up the tile shadow mapping
8888
const tsm = new TileShadowNode( dirLight, {
8989
tilesX: 2,
90-
tilesY: 2,
91-
debug: true
90+
tilesY: 2
9291
} );
9392

9493

src/Three.Core.js

-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export { CompressedCubeTexture } from './textures/CompressedCubeTexture.js';
3434
export { CubeTexture } from './textures/CubeTexture.js';
3535
export { CanvasTexture } from './textures/CanvasTexture.js';
3636
export { DepthTexture } from './textures/DepthTexture.js';
37-
export { DepthArrayTexture } from './textures/DepthArrayTexture.js';
3837
export { Texture } from './textures/Texture.js';
3938
export * from './geometries/Geometries.js';
4039
export * from './materials/Materials.js';
@@ -89,7 +88,6 @@ export { AnimationClip } from './animation/AnimationClip.js';
8988
export { AnimationAction } from './animation/AnimationAction.js';
9089
export { RenderTarget } from './core/RenderTarget.js';
9190
export { RenderTarget3D } from './core/RenderTarget3D.js';
92-
export { RenderTargetArray } from './core/RenderTargetArray.js';
9391
export { Uniform } from './core/Uniform.js';
9492
export { UniformsGroup } from './core/UniformsGroup.js';
9593
export { InstancedBufferGeometry } from './core/InstancedBufferGeometry.js';

src/core/RenderTarget.js

+24-16
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class RenderTarget extends EventDispatcher {
3535
* @property {?Texture} [depthTexture=null] - Reference to a depth texture.
3636
* @property {number} [samples=0] - The MSAA samples count.
3737
* @property {number} [count=1] - Defines the number of color attachments . Must be at least `1`.
38+
* @property {number} [depth=1] - The texture depth.
3839
* @property {boolean} [multiview=false] - Whether this target is used for multiview rendering.
3940
*/
4041

@@ -49,6 +50,21 @@ class RenderTarget extends EventDispatcher {
4950

5051
super();
5152

53+
options = Object.assign( {
54+
generateMipmaps: false,
55+
internalFormat: null,
56+
minFilter: LinearFilter,
57+
depthBuffer: true,
58+
stencilBuffer: false,
59+
resolveDepthBuffer: true,
60+
resolveStencilBuffer: true,
61+
depthTexture: null,
62+
samples: 0,
63+
count: 1,
64+
depth: 1,
65+
multiview: false
66+
}, options );
67+
5268
/**
5369
* This flag can be used for type testing.
5470
*
@@ -80,7 +96,7 @@ class RenderTarget extends EventDispatcher {
8096
* @type {number}
8197
* @default 1
8298
*/
83-
this.depth = options.depth ? options.depth : 1;
99+
this.depth = options.depth;
84100

85101
/**
86102
* A rectangular area inside the render target's viewport. Fragments that are
@@ -108,21 +124,7 @@ class RenderTarget extends EventDispatcher {
108124
*/
109125
this.viewport = new Vector4( 0, 0, width, height );
110126

111-
const image = { width: width, height: height, depth: this.depth };
112-
113-
options = Object.assign( {
114-
generateMipmaps: false,
115-
internalFormat: null,
116-
minFilter: LinearFilter,
117-
depthBuffer: true,
118-
stencilBuffer: false,
119-
resolveDepthBuffer: true,
120-
resolveStencilBuffer: true,
121-
depthTexture: null,
122-
samples: 0,
123-
count: 1,
124-
multiview: false
125-
}, options );
127+
const image = { width: width, height: height, depth: options.depth };
126128

127129
const texture = new Texture( image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace );
128130

@@ -263,6 +265,12 @@ class RenderTarget extends EventDispatcher {
263265
this.textures[ i ].image.height = height;
264266
this.textures[ i ].image.depth = depth;
265267

268+
if ( this.textures[ i ].image.depth > 1 ) {
269+
270+
this.textures[ i ].isArrayTexture = true;
271+
272+
}
273+
266274
}
267275

268276
this.dispose();

src/core/RenderTargetArray.js

-40
This file was deleted.

src/nodes/accessors/StorageTextureNode.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class StorageTextureNode extends TextureNode {
9898
const properties = builder.getNodeProperties( this );
9999
properties.storeNode = this.storeNode;
100100

101+
return properties;
102+
101103
}
102104

103105
/**
@@ -181,18 +183,27 @@ class StorageTextureNode extends TextureNode {
181183

182184
const properties = builder.getNodeProperties( this );
183185

184-
const { uvNode, storeNode } = properties;
186+
const { uvNode, storeNode, depthNode } = properties;
185187

186188
const textureProperty = super.generate( builder, 'property' );
187189
const uvSnippet = uvNode.build( builder, 'uvec2' );
188190
const storeSnippet = storeNode.build( builder, 'vec4' );
191+
const depthSnippet = depthNode ? depthNode.build( builder, 'int' ) : null;
189192

190-
const snippet = builder.generateTextureStore( builder, textureProperty, uvSnippet, storeSnippet );
193+
const snippet = builder.generateTextureStore( builder, textureProperty, uvSnippet, depthSnippet, storeSnippet );
191194

192195
builder.addLineFlowCode( snippet, this );
193196

194197
}
195198

199+
clone() {
200+
201+
const newNode = super.clone();
202+
newNode.storeNode = this.storeNode;
203+
return newNode;
204+
205+
}
206+
196207
}
197208

198209
export default StorageTextureNode;

src/nodes/core/NodeBuilder.js

-17
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import BindGroup from '../../renderers/common/BindGroup.js';
2626

2727
import { REVISION, IntType, UnsignedIntType, LinearFilter, LinearMipmapNearestFilter, NearestMipmapLinearFilter, LinearMipmapLinearFilter } from '../../constants.js';
2828
import { RenderTarget } from '../../core/RenderTarget.js';
29-
import { RenderTargetArray } from '../../core/RenderTargetArray.js';
3029
import { Color } from '../../math/Color.js';
3130
import { Vector2 } from '../../math/Vector2.js';
3231
import { Vector3 } from '../../math/Vector3.js';
@@ -458,22 +457,6 @@ class NodeBuilder {
458457

459458
}
460459

461-
/**
462-
* Factory method for creating an instance of {@link RenderTargetArray} with the given
463-
* dimensions and options.
464-
*
465-
* @param {number} width - The width of the render target.
466-
* @param {number} height - The height of the render target.
467-
* @param {number} depth - The depth of the render target.
468-
* @param {Object} options - The options of the render target.
469-
* @return {RenderTargetArray} The render target.
470-
*/
471-
createRenderTargetArray( width, height, depth, options ) {
472-
473-
return new RenderTargetArray( width, height, depth, options );
474-
475-
}
476-
477460
/**
478461
* Factory method for creating an instance of {@link CubeRenderTarget} with the given
479462
* dimensions and options.

src/nodes/lighting/ShadowFilterNode.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const BasicShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord
2424

2525
let basic = texture( depthTexture, shadowCoord.xy ).label( 't_basic' );
2626

27-
if ( depthTexture.isDepthArrayTexture ) {
27+
if ( depthTexture.isArrayTexture ) {
2828

2929
basic = basic.depth( depthLayer );
3030

@@ -50,7 +50,7 @@ export const PCFShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord,
5050

5151
let depth = texture( depthTexture, uv );
5252

53-
if ( depthTexture.isDepthArrayTexture ) {
53+
if ( depthTexture.isArrayTexture ) {
5454

5555
depth = depth.depth( depthLayer );
5656

@@ -111,7 +111,7 @@ export const PCFSoftShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoo
111111

112112
let depth = texture( depthTexture, uv );
113113

114-
if ( depthTexture.isDepthArrayTexture ) {
114+
if ( depthTexture.isArrayTexture ) {
115115

116116
depth = depth.depth( depthLayer );
117117

@@ -189,7 +189,7 @@ export const VSMShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord,
189189

190190
let distribution = texture( depthTexture ).sample( shadowCoord.xy );
191191

192-
if ( depthTexture.isDepthArrayTexture || depthTexture.isDataArrayTexture ) {
192+
if ( depthTexture.isArrayTexture ) {
193193

194194
distribution = distribution.depth( depthLayer );
195195

src/nodes/lighting/ShadowNode.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ const VSMPassVertical = /*@__PURE__*/ Fn( ( { samples, radius, size, shadowPass,
110110

111111
let depth = shadowPass.sample( add( screenCoordinate.xy, vec2( 0, uvOffset ).mul( radius ) ).div( size ) );
112112

113-
if ( shadowPass.value.isDepthArrayTexture || shadowPass.value.isDataArrayTexture ) {
113+
if ( shadowPass.value.isArrayTexture ) {
114114

115115
depth = depth.depth( depthLayer );
116116

@@ -156,7 +156,7 @@ const VSMPassHorizontal = /*@__PURE__*/ Fn( ( { samples, radius, size, shadowPas
156156

157157
let distribution = shadowPass.sample( add( screenCoordinate.xy, vec2( uvOffset, 0 ).mul( radius ) ).div( size ) );
158158

159-
if ( shadowPass.value.isDepthArrayTexture || shadowPass.value.isDataArrayTexture ) {
159+
if ( shadowPass.value.isArrayTexture ) {
160160

161161
distribution = distribution.depth( depthLayer );
162162

@@ -421,11 +421,11 @@ class ShadowNode extends ShadowBaseNode {
421421

422422
depthTexture.compareFunction = null; // VSM does not use textureSampleCompare()/texture2DCompare()
423423

424-
if ( shadowMap.isRenderTargetArray ) {
424+
if ( shadowMap.depth > 1 ) {
425425

426426
if ( ! shadowMap._vsmShadowMapVertical ) {
427427

428-
shadowMap._vsmShadowMapVertical = builder.createRenderTargetArray( shadow.mapSize.width, shadow.mapSize.height, shadowMap.depth, { format: RGFormat, type: HalfFloatType, depthBuffer: false } );
428+
shadowMap._vsmShadowMapVertical = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height, { format: RGFormat, type: HalfFloatType, depth: shadowMap.depth, depthBuffer: false } );
429429
shadowMap._vsmShadowMapVertical.texture.name = 'VSMVertical';
430430

431431
}
@@ -434,7 +434,7 @@ class ShadowNode extends ShadowBaseNode {
434434

435435
if ( ! shadowMap._vsmShadowMapHorizontal ) {
436436

437-
shadowMap._vsmShadowMapHorizontal = builder.createRenderTargetArray( shadow.mapSize.width, shadow.mapSize.height, shadowMap.depth, { format: RGFormat, type: HalfFloatType, depthBuffer: false } );
437+
shadowMap._vsmShadowMapHorizontal = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height, { format: RGFormat, type: HalfFloatType, depth: shadowMap.depth, depthBuffer: false } );
438438
shadowMap._vsmShadowMapHorizontal.texture.name = 'VSMHorizontal';
439439

440440
}
@@ -451,15 +451,15 @@ class ShadowNode extends ShadowBaseNode {
451451

452452
let shadowPassVertical = texture( depthTexture );
453453

454-
if ( depthTexture.isDepthArrayTexture ) {
454+
if ( depthTexture.isArrayTexture ) {
455455

456456
shadowPassVertical = shadowPassVertical.depth( this.depthLayer );
457457

458458
}
459459

460460
let shadowPassHorizontal = texture( this.vsmShadowMapVertical.texture );
461461

462-
if ( depthTexture.isDepthArrayTexture ) {
462+
if ( depthTexture.isArrayTexture ) {
463463

464464
shadowPassHorizontal = shadowPassHorizontal.depth( this.depthLayer );
465465

@@ -503,7 +503,7 @@ class ShadowNode extends ShadowBaseNode {
503503

504504
let shadowColor = texture( shadowMap.texture, shadowCoord );
505505

506-
if ( depthTexture.isDepthArrayTexture ) {
506+
if ( depthTexture.isArrayTexture ) {
507507

508508
shadowColor = shadowColor.depth( this.depthLayer );
509509

0 commit comments

Comments
 (0)