super-three 0.172.0 → 0.173.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/build/three.cjs +439 -380
- package/build/three.core.js +413 -41
- package/build/three.core.min.js +2 -2
- package/build/three.module.js +28 -344
- package/build/three.module.min.js +2 -2
- package/build/three.tsl.js +11 -3
- package/build/three.tsl.min.js +2 -2
- package/build/three.webgpu.js +7550 -1798
- package/build/three.webgpu.min.js +2 -2
- package/build/three.webgpu.nodes.js +7551 -1798
- package/build/three.webgpu.nodes.min.js +2 -2
- package/examples/jsm/animation/CCDIKSolver.js +6 -5
- package/examples/jsm/capabilities/WebGPU.js +1 -1
- package/examples/jsm/controls/ArcballControls.js +23 -21
- package/examples/jsm/exporters/GLTFExporter.js +26 -25
- package/examples/jsm/geometries/TextGeometry.js +1 -12
- package/examples/jsm/interactive/InteractiveGroup.js +108 -51
- package/examples/jsm/libs/demuxer_mp4.js +109 -0
- package/examples/jsm/loaders/GCodeLoader.js +3 -1
- package/examples/jsm/loaders/GLTFLoader.js +0 -2
- package/examples/jsm/loaders/TDSLoader.js +0 -1
- package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
- package/examples/jsm/misc/GPUComputationRenderer.js +6 -7
- package/examples/jsm/misc/ProgressiveLightMap.js +4 -3
- package/examples/jsm/misc/ProgressiveLightMapGPU.js +4 -3
- package/examples/jsm/misc/Volume.js +7 -5
- package/examples/jsm/misc/VolumeSlice.js +5 -3
- package/examples/jsm/objects/WaterMesh.js +25 -20
- package/examples/jsm/physics/JoltPhysics.js +7 -7
- package/examples/jsm/physics/RapierPhysics.js +4 -4
- package/examples/jsm/postprocessing/EffectComposer.js +23 -2
- package/examples/jsm/postprocessing/OutputPass.js +2 -0
- package/examples/jsm/postprocessing/Pass.js +6 -1
- package/examples/jsm/shaders/OutputShader.js +5 -1
- package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
- package/examples/jsm/transpiler/TSLEncoder.js +2 -0
- package/package.json +1 -1
- package/src/Three.Core.js +2 -0
- package/src/Three.TSL.js +9 -1
- package/src/cameras/ArrayCamera.js +1 -0
- package/src/constants.js +6 -1
- package/src/core/BufferAttribute.js +4 -0
- package/src/core/EventDispatcher.js +8 -6
- package/src/extras/ImageUtils.js +1 -11
- package/src/loaders/nodes/NodeObjectLoader.js +1 -1
- package/src/materials/nodes/MeshBasicNodeMaterial.js +1 -1
- package/src/materials/nodes/MeshPhysicalNodeMaterial.js +1 -1
- package/src/materials/nodes/NodeMaterial.js +5 -5
- package/src/materials/nodes/NodeMaterials.js +0 -1
- package/src/materials/nodes/PointsNodeMaterial.js +109 -7
- package/src/materials/nodes/SpriteNodeMaterial.js +1 -1
- package/src/materials/nodes/VolumeNodeMaterial.js +3 -3
- package/src/materials/nodes/manager/NodeMaterialObserver.js +8 -0
- package/src/nodes/Nodes.js +4 -0
- package/src/nodes/TSL.js +4 -0
- package/src/nodes/accessors/Arrays.js +30 -8
- package/src/nodes/accessors/BatchNode.js +3 -3
- package/src/nodes/accessors/BufferAttributeNode.js +1 -1
- package/src/nodes/accessors/Camera.js +64 -3
- package/src/nodes/accessors/InstanceNode.js +1 -1
- package/src/nodes/accessors/MaterialNode.js +9 -9
- package/src/nodes/accessors/ModelViewProjectionNode.js +1 -1
- package/src/nodes/accessors/Normal.js +6 -2
- package/src/nodes/accessors/Object3DNode.js +0 -1
- package/src/nodes/accessors/Position.js +6 -6
- package/src/nodes/accessors/ReferenceBaseNode.js +2 -4
- package/src/nodes/accessors/ReferenceNode.js +2 -3
- package/src/nodes/accessors/StorageBufferNode.js +42 -5
- package/src/nodes/accessors/Tangent.js +2 -2
- package/src/nodes/accessors/Texture3DNode.js +1 -1
- package/src/nodes/accessors/TextureNode.js +12 -5
- package/src/nodes/accessors/UniformArrayNode.js +9 -3
- package/src/nodes/accessors/VelocityNode.js +0 -2
- package/src/nodes/code/ScriptableNode.js +3 -3
- package/src/nodes/core/ArrayNode.js +125 -0
- package/src/nodes/core/ConstNode.js +8 -0
- package/src/nodes/core/Node.js +14 -1
- package/src/nodes/core/NodeBuilder.js +229 -19
- package/src/nodes/core/NodeUtils.js +11 -1
- package/src/nodes/core/NodeVar.js +17 -1
- package/src/nodes/core/OutputStructNode.js +19 -9
- package/src/nodes/core/StackNode.js +20 -1
- package/src/nodes/core/StructNode.js +121 -0
- package/src/nodes/core/StructType.js +13 -0
- package/src/nodes/core/StructTypeNode.js +82 -21
- package/src/nodes/core/TempNode.js +1 -1
- package/src/nodes/core/VarNode.js +94 -7
- package/src/nodes/core/VaryingNode.js +19 -3
- package/src/nodes/display/BlendModes.js +88 -1
- package/src/nodes/display/BumpMapNode.js +6 -6
- package/src/nodes/display/NormalMapNode.js +6 -6
- package/src/nodes/display/PassNode.js +3 -1
- package/src/nodes/display/ScreenNode.js +9 -0
- package/src/nodes/fog/Fog.js +17 -0
- package/src/nodes/gpgpu/AtomicFunctionNode.js +20 -4
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +8 -0
- package/src/nodes/gpgpu/WorkgroupInfoNode.js +1 -1
- package/src/nodes/lighting/ShadowNode.js +1 -1
- package/src/nodes/math/ConditionalNode.js +8 -1
- package/src/nodes/math/MathNode.js +14 -1
- package/src/nodes/math/OperatorNode.js +96 -18
- package/src/nodes/pmrem/PMREMUtils.js +1 -1
- package/src/nodes/shapes/Shapes.js +33 -0
- package/src/nodes/tsl/TSLBase.js +1 -0
- package/src/nodes/tsl/TSLCore.js +22 -2
- package/src/nodes/utils/ArrayElementNode.js +1 -1
- package/src/nodes/utils/LoopNode.js +8 -1
- package/src/nodes/utils/MemberNode.js +68 -0
- package/src/nodes/utils/StorageArrayElementNode.js +14 -0
- package/src/nodes/utils/Timer.js +21 -0
- package/src/objects/BatchedMesh.js +1 -1
- package/src/objects/Line.js +6 -6
- package/src/renderers/WebGLRenderer.js +7 -0
- package/src/renderers/common/Animation.js +23 -1
- package/src/renderers/common/Backend.js +58 -15
- package/src/renderers/common/Background.js +14 -0
- package/src/renderers/common/Binding.js +1 -1
- package/src/renderers/common/BufferUtils.js +1 -1
- package/src/renderers/common/BundleGroup.js +1 -1
- package/src/renderers/common/ChainMap.js +9 -7
- package/src/renderers/common/ClippingContext.js +1 -1
- package/src/renderers/common/Color4.js +7 -3
- package/src/renderers/common/Geometries.js +2 -23
- package/src/renderers/common/Info.js +1 -45
- package/src/renderers/common/Lighting.js +8 -6
- package/src/renderers/common/Pipelines.js +3 -3
- package/src/renderers/common/PostProcessing.js +24 -8
- package/src/renderers/common/QuadMesh.js +1 -1
- package/src/renderers/common/RenderBundles.js +9 -3
- package/src/renderers/common/RenderContext.js +37 -3
- package/src/renderers/common/RenderContexts.js +30 -17
- package/src/renderers/common/RenderList.js +2 -2
- package/src/renderers/common/RenderLists.js +9 -3
- package/src/renderers/common/RenderObject.js +76 -17
- package/src/renderers/common/RenderObjects.js +9 -7
- package/src/renderers/common/Renderer.js +86 -67
- package/src/renderers/common/SampledTexture.js +0 -1
- package/src/renderers/common/StorageBufferAttribute.js +1 -1
- package/src/renderers/common/StorageInstancedBufferAttribute.js +1 -1
- package/src/renderers/common/StorageTexture.js +1 -1
- package/src/renderers/common/Textures.js +14 -7
- package/src/renderers/common/TimestampQueryPool.js +39 -0
- package/src/renderers/common/Uniform.js +37 -1
- package/src/renderers/common/UniformsGroup.js +2 -0
- package/src/renderers/common/XRManager.js +1193 -0
- package/src/renderers/common/XRRenderTarget.js +74 -0
- package/src/renderers/common/extras/PMREMGenerator.js +53 -8
- package/src/renderers/common/nodes/NodeBuilderState.js +4 -4
- package/src/renderers/common/nodes/NodeLibrary.js +5 -5
- package/src/renderers/common/nodes/NodeSampledTexture.js +0 -1
- package/src/renderers/common/nodes/NodeUniform.js +54 -2
- package/src/renderers/common/nodes/Nodes.js +25 -18
- package/src/renderers/webgl/WebGLBackground.js +4 -0
- package/src/renderers/webgl-fallback/WebGLBackend.js +295 -110
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +347 -17
- package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +57 -0
- package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +28 -0
- package/src/renderers/webgl-fallback/utils/WebGLExtensions.js +45 -0
- package/src/renderers/webgl-fallback/utils/WebGLState.js +323 -11
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +167 -21
- package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +359 -0
- package/src/renderers/webgl-fallback/utils/WebGLUtils.js +43 -0
- package/src/renderers/webgpu/WebGPUBackend.js +132 -149
- package/src/renderers/webgpu/WebGPURenderer.Nodes.js +6 -4
- package/src/renderers/webgpu/WebGPURenderer.js +5 -4
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +615 -41
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +85 -6
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +85 -0
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +102 -3
- package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +98 -1
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +257 -9
- package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +274 -0
- package/src/renderers/webgpu/utils/WebGPUUtils.js +86 -4
- package/src/renderers/webxr/WebXRManager.js +13 -2
- package/src/textures/VideoFrameTexture.js +35 -0
- package/examples/jsm/geometries/InstancedPointsGeometry.js +0 -176
- package/examples/jsm/objects/InstancedPoints.js +0 -19
- package/src/materials/nodes/InstancedPointsNodeMaterial.js +0 -209
- package/src/nodes/accessors/InstancedPointsMaterialNode.js +0 -37
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { warnOnce } from '../../../utils.js';
|
|
2
|
+
import TimestampQueryPool from '../../common/TimestampQueryPool.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Manages a pool of WebGPU timestamp queries for performance measurement.
|
|
6
|
+
* Extends the base TimestampQueryPool to provide WebGPU-specific implementation.
|
|
7
|
+
* @extends TimestampQueryPool
|
|
8
|
+
*/
|
|
9
|
+
class WebGPUTimestampQueryPool extends TimestampQueryPool {
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new WebGPU timestamp query pool.
|
|
13
|
+
* @param {GPUDevice} device - The WebGPU device to create queries on.
|
|
14
|
+
* @param {string} type - The type identifier for this query pool.
|
|
15
|
+
* @param {number} [maxQueries=2048] - Maximum number of queries this pool can hold.
|
|
16
|
+
*/
|
|
17
|
+
constructor( device, type, maxQueries = 2048 ) {
|
|
18
|
+
|
|
19
|
+
super( maxQueries );
|
|
20
|
+
this.device = device;
|
|
21
|
+
this.type = type;
|
|
22
|
+
|
|
23
|
+
this.querySet = this.device.createQuerySet( {
|
|
24
|
+
type: 'timestamp',
|
|
25
|
+
count: this.maxQueries,
|
|
26
|
+
label: `queryset_global_timestamp_${type}`
|
|
27
|
+
} );
|
|
28
|
+
|
|
29
|
+
const bufferSize = this.maxQueries * 8;
|
|
30
|
+
this.resolveBuffer = this.device.createBuffer( {
|
|
31
|
+
label: `buffer_timestamp_resolve_${type}`,
|
|
32
|
+
size: bufferSize,
|
|
33
|
+
usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
|
|
34
|
+
} );
|
|
35
|
+
|
|
36
|
+
this.resultBuffer = this.device.createBuffer( {
|
|
37
|
+
label: `buffer_timestamp_result_${type}`,
|
|
38
|
+
size: bufferSize,
|
|
39
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
40
|
+
} );
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Allocates a pair of queries for a given render context.
|
|
46
|
+
* @param {Object} renderContext - The render context to allocate queries for.
|
|
47
|
+
* @returns {?number} The base offset for the allocated queries, or null if allocation failed.
|
|
48
|
+
*/
|
|
49
|
+
allocateQueriesForContext( renderContext ) {
|
|
50
|
+
|
|
51
|
+
if ( ! this.trackTimestamp || this.isDisposed ) return null;
|
|
52
|
+
|
|
53
|
+
if ( this.currentQueryIndex + 2 > this.maxQueries ) {
|
|
54
|
+
|
|
55
|
+
warnOnce( `WebGPUTimestampQueryPool [${ this.type }]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${ this.type.toUpperCase() } ).` );
|
|
56
|
+
return null;
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const baseOffset = this.currentQueryIndex;
|
|
61
|
+
this.currentQueryIndex += 2;
|
|
62
|
+
|
|
63
|
+
this.queryOffsets.set( renderContext.id, baseOffset );
|
|
64
|
+
return baseOffset;
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Asynchronously resolves all pending queries and returns the total duration.
|
|
70
|
+
* If there's already a pending resolve operation, returns that promise instead.
|
|
71
|
+
* @returns {Promise<number>} The total duration in milliseconds, or the last valid value if resolution fails.
|
|
72
|
+
*/
|
|
73
|
+
async resolveQueriesAsync() {
|
|
74
|
+
|
|
75
|
+
if ( ! this.trackTimestamp || this.currentQueryIndex === 0 || this.isDisposed ) {
|
|
76
|
+
|
|
77
|
+
return this.lastValue;
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if ( this.pendingResolve ) {
|
|
82
|
+
|
|
83
|
+
return this.pendingResolve;
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.pendingResolve = this._resolveQueries();
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
|
|
91
|
+
const result = await this.pendingResolve;
|
|
92
|
+
return result;
|
|
93
|
+
|
|
94
|
+
} finally {
|
|
95
|
+
|
|
96
|
+
this.pendingResolve = null;
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Internal method to resolve queries and calculate total duration.
|
|
104
|
+
* @private
|
|
105
|
+
* @returns {Promise<number>} The total duration in milliseconds.
|
|
106
|
+
*/
|
|
107
|
+
async _resolveQueries() {
|
|
108
|
+
|
|
109
|
+
if ( this.isDisposed ) {
|
|
110
|
+
|
|
111
|
+
return this.lastValue;
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
|
|
117
|
+
if ( this.resultBuffer.mapState !== 'unmapped' ) {
|
|
118
|
+
|
|
119
|
+
return this.lastValue;
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const currentOffsets = new Map( this.queryOffsets );
|
|
124
|
+
const queryCount = this.currentQueryIndex;
|
|
125
|
+
const bytesUsed = queryCount * 8;
|
|
126
|
+
|
|
127
|
+
// Reset state before GPU work
|
|
128
|
+
this.currentQueryIndex = 0;
|
|
129
|
+
this.queryOffsets.clear();
|
|
130
|
+
|
|
131
|
+
const commandEncoder = this.device.createCommandEncoder();
|
|
132
|
+
|
|
133
|
+
commandEncoder.resolveQuerySet(
|
|
134
|
+
this.querySet,
|
|
135
|
+
0,
|
|
136
|
+
queryCount,
|
|
137
|
+
this.resolveBuffer,
|
|
138
|
+
0
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
commandEncoder.copyBufferToBuffer(
|
|
142
|
+
this.resolveBuffer,
|
|
143
|
+
0,
|
|
144
|
+
this.resultBuffer,
|
|
145
|
+
0,
|
|
146
|
+
bytesUsed
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const commandBuffer = commandEncoder.finish();
|
|
150
|
+
this.device.queue.submit( [ commandBuffer ] );
|
|
151
|
+
|
|
152
|
+
if ( this.resultBuffer.mapState !== 'unmapped' ) {
|
|
153
|
+
|
|
154
|
+
return this.lastValue;
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Create and track the mapping operation
|
|
159
|
+
await this.resultBuffer.mapAsync( GPUMapMode.READ, 0, bytesUsed );
|
|
160
|
+
|
|
161
|
+
if ( this.isDisposed ) {
|
|
162
|
+
|
|
163
|
+
if ( this.resultBuffer.mapState === 'mapped' ) {
|
|
164
|
+
|
|
165
|
+
this.resultBuffer.unmap();
|
|
166
|
+
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return this.lastValue;
|
|
170
|
+
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const times = new BigUint64Array( this.resultBuffer.getMappedRange( 0, bytesUsed ) );
|
|
174
|
+
let totalDuration = 0;
|
|
175
|
+
|
|
176
|
+
for ( const [ , baseOffset ] of currentOffsets ) {
|
|
177
|
+
|
|
178
|
+
const startTime = times[ baseOffset ];
|
|
179
|
+
const endTime = times[ baseOffset + 1 ];
|
|
180
|
+
const duration = Number( endTime - startTime ) / 1e6;
|
|
181
|
+
totalDuration += duration;
|
|
182
|
+
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
this.resultBuffer.unmap();
|
|
186
|
+
this.lastValue = totalDuration;
|
|
187
|
+
|
|
188
|
+
return totalDuration;
|
|
189
|
+
|
|
190
|
+
} catch ( error ) {
|
|
191
|
+
|
|
192
|
+
console.error( 'Error resolving queries:', error );
|
|
193
|
+
if ( this.resultBuffer.mapState === 'mapped' ) {
|
|
194
|
+
|
|
195
|
+
this.resultBuffer.unmap();
|
|
196
|
+
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return this.lastValue;
|
|
200
|
+
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async dispose() {
|
|
206
|
+
|
|
207
|
+
if ( this.isDisposed ) {
|
|
208
|
+
|
|
209
|
+
return;
|
|
210
|
+
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
this.isDisposed = true;
|
|
214
|
+
|
|
215
|
+
// Wait for pending resolve operation
|
|
216
|
+
if ( this.pendingResolve ) {
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
|
|
220
|
+
await this.pendingResolve;
|
|
221
|
+
|
|
222
|
+
} catch ( error ) {
|
|
223
|
+
|
|
224
|
+
console.error( 'Error waiting for pending resolve:', error );
|
|
225
|
+
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Ensure buffer is unmapped before destroying
|
|
231
|
+
if ( this.resultBuffer && this.resultBuffer.mapState === 'mapped' ) {
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
|
|
235
|
+
this.resultBuffer.unmap();
|
|
236
|
+
|
|
237
|
+
} catch ( error ) {
|
|
238
|
+
|
|
239
|
+
console.error( 'Error unmapping buffer:', error );
|
|
240
|
+
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Destroy resources
|
|
246
|
+
if ( this.querySet ) {
|
|
247
|
+
|
|
248
|
+
this.querySet.destroy();
|
|
249
|
+
this.querySet = null;
|
|
250
|
+
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if ( this.resolveBuffer ) {
|
|
254
|
+
|
|
255
|
+
this.resolveBuffer.destroy();
|
|
256
|
+
this.resolveBuffer = null;
|
|
257
|
+
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if ( this.resultBuffer ) {
|
|
261
|
+
|
|
262
|
+
this.resultBuffer.destroy();
|
|
263
|
+
this.resultBuffer = null;
|
|
264
|
+
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
this.queryOffsets.clear();
|
|
268
|
+
this.pendingResolve = null;
|
|
269
|
+
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export default WebGPUTimestampQueryPool;
|
|
@@ -1,13 +1,35 @@
|
|
|
1
|
+
import { HalfFloatType, UnsignedByteType } from '../../../constants.js';
|
|
1
2
|
import { GPUPrimitiveTopology, GPUTextureFormat } from './WebGPUConstants.js';
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* A WebGPU backend utility module with common helpers.
|
|
6
|
+
*
|
|
7
|
+
* @private
|
|
8
|
+
*/
|
|
3
9
|
class WebGPUUtils {
|
|
4
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Constructs a new utility object.
|
|
13
|
+
*
|
|
14
|
+
* @param {WebGPUBackend} backend - The WebGPU backend.
|
|
15
|
+
*/
|
|
5
16
|
constructor( backend ) {
|
|
6
17
|
|
|
18
|
+
/**
|
|
19
|
+
* A reference to the WebGPU backend.
|
|
20
|
+
*
|
|
21
|
+
* @type {WebGPUBackend}
|
|
22
|
+
*/
|
|
7
23
|
this.backend = backend;
|
|
8
24
|
|
|
9
25
|
}
|
|
10
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Returns the depth/stencil GPU format for the given render context.
|
|
29
|
+
*
|
|
30
|
+
* @param {RenderContext} renderContext - The render context.
|
|
31
|
+
* @return {String} The depth/stencil GPU texture format.
|
|
32
|
+
*/
|
|
11
33
|
getCurrentDepthStencilFormat( renderContext ) {
|
|
12
34
|
|
|
13
35
|
let format;
|
|
@@ -30,12 +52,24 @@ class WebGPUUtils {
|
|
|
30
52
|
|
|
31
53
|
}
|
|
32
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Returns the GPU format for the given texture.
|
|
57
|
+
*
|
|
58
|
+
* @param {Texture} texture - The texture.
|
|
59
|
+
* @return {String} The GPU texture format.
|
|
60
|
+
*/
|
|
33
61
|
getTextureFormatGPU( texture ) {
|
|
34
62
|
|
|
35
63
|
return this.backend.get( texture ).format;
|
|
36
64
|
|
|
37
65
|
}
|
|
38
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Returns an object that defines the multi-sampling state of the given texture.
|
|
69
|
+
*
|
|
70
|
+
* @param {Texture} texture - The texture.
|
|
71
|
+
* @return {Object} The multi-sampling state.
|
|
72
|
+
*/
|
|
39
73
|
getTextureSampleData( texture ) {
|
|
40
74
|
|
|
41
75
|
let samples;
|
|
@@ -66,6 +100,12 @@ class WebGPUUtils {
|
|
|
66
100
|
|
|
67
101
|
}
|
|
68
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Returns the default color attachment's GPU format of the current render context.
|
|
105
|
+
*
|
|
106
|
+
* @param {RenderContext} renderContext - The render context.
|
|
107
|
+
* @return {String} The GPU texture format of the default color attachment.
|
|
108
|
+
*/
|
|
69
109
|
getCurrentColorFormat( renderContext ) {
|
|
70
110
|
|
|
71
111
|
let format;
|
|
@@ -84,6 +124,12 @@ class WebGPUUtils {
|
|
|
84
124
|
|
|
85
125
|
}
|
|
86
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Returns the output color space of the current render context.
|
|
129
|
+
*
|
|
130
|
+
* @param {RenderContext} renderContext - The render context.
|
|
131
|
+
* @return {String} The output color space.
|
|
132
|
+
*/
|
|
87
133
|
getCurrentColorSpace( renderContext ) {
|
|
88
134
|
|
|
89
135
|
if ( renderContext.textures !== null ) {
|
|
@@ -96,6 +142,13 @@ class WebGPUUtils {
|
|
|
96
142
|
|
|
97
143
|
}
|
|
98
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Returns GPU primitive topology for the given object and material.
|
|
147
|
+
*
|
|
148
|
+
* @param {Object3D} object - The 3D object.
|
|
149
|
+
* @param {Material} material - The material.
|
|
150
|
+
* @return {String} The GPU primitive topology.
|
|
151
|
+
*/
|
|
99
152
|
getPrimitiveTopology( object, material ) {
|
|
100
153
|
|
|
101
154
|
if ( object.isPoints ) return GPUPrimitiveTopology.PointList;
|
|
@@ -105,6 +158,14 @@ class WebGPUUtils {
|
|
|
105
158
|
|
|
106
159
|
}
|
|
107
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Returns a modified sample count from the given sample count value.
|
|
163
|
+
*
|
|
164
|
+
* That is required since WebGPU does not support arbitrary sample counts.
|
|
165
|
+
*
|
|
166
|
+
* @param {Number} sampleCount - The input sample count.
|
|
167
|
+
* @return {Number} The (potentially updated) output sample count.
|
|
168
|
+
*/
|
|
108
169
|
getSampleCount( sampleCount ) {
|
|
109
170
|
|
|
110
171
|
let count = 1;
|
|
@@ -126,6 +187,12 @@ class WebGPUUtils {
|
|
|
126
187
|
|
|
127
188
|
}
|
|
128
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Returns the sample count of the given render context.
|
|
192
|
+
*
|
|
193
|
+
* @param {RenderContext} renderContext - The render context.
|
|
194
|
+
* @return {Number} The sample count.
|
|
195
|
+
*/
|
|
129
196
|
getSampleCountRenderContext( renderContext ) {
|
|
130
197
|
|
|
131
198
|
if ( renderContext.textures !== null ) {
|
|
@@ -138,18 +205,33 @@ class WebGPUUtils {
|
|
|
138
205
|
|
|
139
206
|
}
|
|
140
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Returns the preferred canvas format.
|
|
210
|
+
*
|
|
211
|
+
* There is a separate method for this so it's possible to
|
|
212
|
+
* honor edge cases for specific devices.
|
|
213
|
+
*
|
|
214
|
+
* @return {String} The GPU texture format of the canvas.
|
|
215
|
+
*/
|
|
141
216
|
getPreferredCanvasFormat() {
|
|
142
217
|
|
|
143
|
-
|
|
144
|
-
// https://github.com/mrdoob/three.js/pull/29221/files#r1731833949
|
|
218
|
+
const outputType = this.backend.parameters.outputType;
|
|
145
219
|
|
|
146
|
-
if (
|
|
220
|
+
if ( outputType === undefined ) {
|
|
221
|
+
|
|
222
|
+
return navigator.gpu.getPreferredCanvasFormat();
|
|
223
|
+
|
|
224
|
+
} else if ( outputType === UnsignedByteType ) {
|
|
147
225
|
|
|
148
226
|
return GPUTextureFormat.BGRA8Unorm;
|
|
149
227
|
|
|
228
|
+
} else if ( outputType === HalfFloatType ) {
|
|
229
|
+
|
|
230
|
+
return GPUTextureFormat.RGBA16Float;
|
|
231
|
+
|
|
150
232
|
} else {
|
|
151
233
|
|
|
152
|
-
|
|
234
|
+
throw new Error( 'Unsupported outputType' );
|
|
153
235
|
|
|
154
236
|
}
|
|
155
237
|
|
|
@@ -248,6 +248,12 @@ class WebXRManager extends EventDispatcher {
|
|
|
248
248
|
|
|
249
249
|
};
|
|
250
250
|
|
|
251
|
+
this.getRenderTarget = function () {
|
|
252
|
+
|
|
253
|
+
return newRenderTarget;
|
|
254
|
+
|
|
255
|
+
};
|
|
256
|
+
|
|
251
257
|
this.getFrame = function () {
|
|
252
258
|
|
|
253
259
|
return xrFrame;
|
|
@@ -286,7 +292,9 @@ class WebXRManager extends EventDispatcher {
|
|
|
286
292
|
currentPixelRatio = renderer.getPixelRatio();
|
|
287
293
|
renderer.getSize( currentSize );
|
|
288
294
|
|
|
289
|
-
|
|
295
|
+
// Check that the browser implements the necessary APIs to use an
|
|
296
|
+
// XRProjectionLayer rather than an XRWebGLLayer
|
|
297
|
+
const useLayers = typeof XRWebGLBinding !== 'undefined' && 'createProjectionLayer' in XRWebGLBinding.prototype;
|
|
290
298
|
|
|
291
299
|
if ( ! useLayers ) {
|
|
292
300
|
|
|
@@ -845,8 +853,11 @@ class WebXRManager extends EventDispatcher {
|
|
|
845
853
|
//
|
|
846
854
|
|
|
847
855
|
const enabledFeatures = session.enabledFeatures;
|
|
856
|
+
const gpuDepthSensingEnabled = enabledFeatures &&
|
|
857
|
+
enabledFeatures.includes( 'depth-sensing' ) &&
|
|
858
|
+
session.depthUsage == 'gpu-optimized';
|
|
848
859
|
|
|
849
|
-
if (
|
|
860
|
+
if ( gpuDepthSensingEnabled && glBinding ) {
|
|
850
861
|
|
|
851
862
|
const depthData = glBinding.getDepthInformation( views[ 0 ] );
|
|
852
863
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { VideoTexture } from './VideoTexture.js';
|
|
2
|
+
|
|
3
|
+
class VideoFrameTexture extends VideoTexture {
|
|
4
|
+
|
|
5
|
+
constructor( mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
|
|
6
|
+
|
|
7
|
+
super( {}, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
|
|
8
|
+
|
|
9
|
+
this.isVideoFrameTexture = true;
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
update() {
|
|
14
|
+
|
|
15
|
+
// overwrites `VideoTexture.update()` with an empty method since
|
|
16
|
+
// this type of texture is updated via `setFrame()`.
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
clone() {
|
|
21
|
+
|
|
22
|
+
return new this.constructor().copy( this ); // restoring Texture.clone()
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setFrame( frame ) {
|
|
27
|
+
|
|
28
|
+
this.image = frame;
|
|
29
|
+
this.needsUpdate = true;
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { VideoFrameTexture };
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Box3,
|
|
3
|
-
Float32BufferAttribute,
|
|
4
|
-
InstancedBufferGeometry,
|
|
5
|
-
InstancedBufferAttribute,
|
|
6
|
-
Sphere,
|
|
7
|
-
Vector3
|
|
8
|
-
} from 'three';
|
|
9
|
-
|
|
10
|
-
const _vector = new Vector3();
|
|
11
|
-
|
|
12
|
-
class InstancedPointsGeometry extends InstancedBufferGeometry {
|
|
13
|
-
|
|
14
|
-
constructor() {
|
|
15
|
-
|
|
16
|
-
super();
|
|
17
|
-
|
|
18
|
-
this.isInstancedPointsGeometry = true;
|
|
19
|
-
|
|
20
|
-
this.type = 'InstancedPointsGeometry';
|
|
21
|
-
|
|
22
|
-
const positions = [ - 1, 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ];
|
|
23
|
-
const uvs = [ 0, 1, 1, 1, 0, 0, 1, 0 ];
|
|
24
|
-
const index = [ 0, 2, 1, 2, 3, 1 ];
|
|
25
|
-
|
|
26
|
-
this.setIndex( index );
|
|
27
|
-
this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
|
|
28
|
-
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
applyMatrix4( matrix ) {
|
|
33
|
-
|
|
34
|
-
const pos = this.attributes.instancePosition;
|
|
35
|
-
|
|
36
|
-
if ( pos !== undefined ) {
|
|
37
|
-
|
|
38
|
-
pos.applyMatrix4( matrix );
|
|
39
|
-
|
|
40
|
-
pos.needsUpdate = true;
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if ( this.boundingBox !== null ) {
|
|
45
|
-
|
|
46
|
-
this.computeBoundingBox();
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if ( this.boundingSphere !== null ) {
|
|
51
|
-
|
|
52
|
-
this.computeBoundingSphere();
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return this;
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
setPositions( array ) {
|
|
61
|
-
|
|
62
|
-
let points;
|
|
63
|
-
|
|
64
|
-
if ( array instanceof Float32Array ) {
|
|
65
|
-
|
|
66
|
-
points = array;
|
|
67
|
-
|
|
68
|
-
} else if ( Array.isArray( array ) ) {
|
|
69
|
-
|
|
70
|
-
points = new Float32Array( array );
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
this.setAttribute( 'instancePosition', new InstancedBufferAttribute( points, 3 ) ); // xyz
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
this.computeBoundingBox();
|
|
79
|
-
this.computeBoundingSphere();
|
|
80
|
-
|
|
81
|
-
this.instanceCount = points.length / 3;
|
|
82
|
-
|
|
83
|
-
return this;
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
setColors( array ) {
|
|
88
|
-
|
|
89
|
-
let colors;
|
|
90
|
-
|
|
91
|
-
if ( array instanceof Float32Array ) {
|
|
92
|
-
|
|
93
|
-
colors = array;
|
|
94
|
-
|
|
95
|
-
} else if ( Array.isArray( array ) ) {
|
|
96
|
-
|
|
97
|
-
colors = new Float32Array( array );
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
this.setAttribute( 'instanceColor', new InstancedBufferAttribute( colors, 3 ) ); // rgb
|
|
102
|
-
|
|
103
|
-
return this;
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
computeBoundingBox() {
|
|
108
|
-
|
|
109
|
-
if ( this.boundingBox === null ) {
|
|
110
|
-
|
|
111
|
-
this.boundingBox = new Box3();
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const pos = this.attributes.instancePosition;
|
|
116
|
-
|
|
117
|
-
if ( pos !== undefined ) {
|
|
118
|
-
|
|
119
|
-
this.boundingBox.setFromBufferAttribute( pos );
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
computeBoundingSphere() {
|
|
126
|
-
|
|
127
|
-
if ( this.boundingSphere === null ) {
|
|
128
|
-
|
|
129
|
-
this.boundingSphere = new Sphere();
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if ( this.boundingBox === null ) {
|
|
134
|
-
|
|
135
|
-
this.computeBoundingBox();
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const pos = this.attributes.instancePosition;
|
|
140
|
-
|
|
141
|
-
if ( pos !== undefined ) {
|
|
142
|
-
|
|
143
|
-
const center = this.boundingSphere.center;
|
|
144
|
-
|
|
145
|
-
this.boundingBox.getCenter( center );
|
|
146
|
-
|
|
147
|
-
let maxRadiusSq = 0;
|
|
148
|
-
|
|
149
|
-
for ( let i = 0, il = pos.count; i < il; i ++ ) {
|
|
150
|
-
|
|
151
|
-
_vector.fromBufferAttribute( pos, i );
|
|
152
|
-
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
|
|
157
|
-
|
|
158
|
-
if ( isNaN( this.boundingSphere.radius ) ) {
|
|
159
|
-
|
|
160
|
-
console.error( 'THREE.InstancedPointsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
toJSON() {
|
|
169
|
-
|
|
170
|
-
// todo
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export default InstancedPointsGeometry;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Mesh, InstancedPointsNodeMaterial } from 'three/webgpu';
|
|
2
|
-
|
|
3
|
-
import InstancedPointsGeometry from '../geometries/InstancedPointsGeometry.js';
|
|
4
|
-
|
|
5
|
-
class InstancedPoints extends Mesh {
|
|
6
|
-
|
|
7
|
-
constructor( geometry = new InstancedPointsGeometry(), material = new InstancedPointsNodeMaterial() ) {
|
|
8
|
-
|
|
9
|
-
super( geometry, material );
|
|
10
|
-
|
|
11
|
-
this.isInstancedPoints = true;
|
|
12
|
-
|
|
13
|
-
this.type = 'InstancedPoints';
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default InstancedPoints;
|