@hello-terrain/three 0.0.0-alpha.4 → 0.0.0-alpha.5
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/README.md +179 -23
- package/dist/index.cjs +644 -126
- package/dist/index.d.cts +335 -136
- package/dist/index.d.mts +335 -136
- package/dist/index.d.ts +335 -136
- package/dist/index.mjs +631 -127
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { BufferGeometry } from 'three';
|
|
2
2
|
import * as three_webgpu from 'three/webgpu';
|
|
3
|
-
import { InstancedMesh, NodeMaterial,
|
|
3
|
+
import { InstancedMesh, NodeMaterial, Node, WebGPURenderer, StorageBufferAttribute, StorageBufferNode, UniformNode, Vector3, Vector3Like, ConstNode } from 'three/webgpu';
|
|
4
4
|
import * as three_src_nodes_TSL_js from 'three/src/nodes/TSL.js';
|
|
5
5
|
import { ShaderCallNodeInternal } from 'three/src/nodes/TSL.js';
|
|
6
|
-
import Node from 'three/src/nodes/core/Node.js';
|
|
7
6
|
import * as _hello_terrain_work from '@hello-terrain/work';
|
|
8
7
|
import { TaskRef } from '@hello-terrain/work';
|
|
8
|
+
import Node$1 from 'three/src/nodes/core/Node.js';
|
|
9
|
+
import * as three_tsl from 'three/tsl';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Custom geometry for terrain tiles with properly handled skirts.
|
|
@@ -108,67 +109,47 @@ declare class TerrainMesh extends InstancedMesh {
|
|
|
108
109
|
set maxNodes(maxNodes: number);
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
*
|
|
114
|
-
* @param value - The node or value in the range [0, 1].
|
|
115
|
-
* @returns A node mapping the input value to the range [-1, 1].
|
|
116
|
-
*/
|
|
117
|
-
declare const textureSpaceToVectorSpace: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
118
|
-
/**
|
|
119
|
-
* Maps a value or node from vector space [-1, 1] to texture space [0, 1].
|
|
120
|
-
*
|
|
121
|
-
* @param value - The node or value in the range [-1, 1].
|
|
122
|
-
* @returns A node mapping the input value to the range [0, 1].
|
|
123
|
-
*/
|
|
124
|
-
declare const vectorSpaceToTextureSpace: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
125
|
-
/**
|
|
126
|
-
* Blends two normal maps using the Reoriented Normal Mapping technique.
|
|
127
|
-
* This is the same algorithm used by Unreal Engine's BlendAngleCorrectedNormals node.
|
|
128
|
-
*
|
|
129
|
-
* Both inputs should be in vector space [-1, 1].
|
|
130
|
-
*
|
|
131
|
-
* @see https://blog.selfshadow.com/publications/blending-in-detail/
|
|
132
|
-
*/
|
|
133
|
-
declare const blendAngleCorrectedNormals: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node]>;
|
|
134
|
-
/**
|
|
135
|
-
* Reconstructs the Z component of a normal from the X and Y components.
|
|
136
|
-
*
|
|
137
|
-
* @param normalXY - A vec2 containing the X and Y components of the normal
|
|
138
|
-
* @returns A vec3 with the reconstructed normal (X, Y, derived Z)
|
|
139
|
-
*/
|
|
140
|
-
declare const deriveNormalZ: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
112
|
+
type ComputeStageCallback = (nodeIndex: Node, globalVertexIndex: Node, uv: Node, localCoordinates: Node, texelSize: Node) => void;
|
|
113
|
+
type ComputePipeline = ComputeStageCallback[];
|
|
141
114
|
|
|
115
|
+
/** Default compile task — uses normalFieldStageTask as the leaf. */
|
|
116
|
+
declare const compileComputeTask: _hello_terrain_work.Task<{
|
|
117
|
+
execute: (renderer: WebGPURenderer, instanceCount: number) => void;
|
|
118
|
+
}, string, unknown>;
|
|
119
|
+
/** Default execute task — dispatches the compiled kernel. */
|
|
120
|
+
declare const executeComputeTask: _hello_terrain_work.Task<any, string, {
|
|
121
|
+
renderer: WebGPURenderer;
|
|
122
|
+
}>;
|
|
142
123
|
/**
|
|
143
|
-
*
|
|
144
|
-
* When a number is provided, it's automatically converted to an int node.
|
|
145
|
-
* When a Node is provided, it should resolve to an integer value.
|
|
146
|
-
*/
|
|
147
|
-
type IntNodeInput = number | ConstNode<number> | Node$1;
|
|
148
|
-
/**
|
|
149
|
-
* Returns a node that is true for skirt vertices in the vertex stage.
|
|
124
|
+
* Factory for user-extensible pipelines.
|
|
150
125
|
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* resolution is derived from `segments`.
|
|
126
|
+
* Users who add custom compute stages create their own stage tasks using
|
|
127
|
+
* the accumulation pattern (`get()` predecessor, spread, append), then pass
|
|
128
|
+
* their leaf stage to this helper to get compile + execute tasks.
|
|
155
129
|
*
|
|
156
|
-
* @
|
|
157
|
-
*
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* const erosionStageTask = task((get, work) => {
|
|
133
|
+
* const upstream = get(elevationFieldStageTask);
|
|
134
|
+
* return work((): ComputePipeline => [
|
|
135
|
+
* ...upstream,
|
|
136
|
+
* (nodeIndex, globalVertexIndex, uv) => {
|
|
137
|
+
* // custom erosion logic
|
|
138
|
+
* },
|
|
139
|
+
* ]);
|
|
140
|
+
* });
|
|
167
141
|
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
142
|
+
* const { compile, execute } = createComputePipelineTasks(erosionStageTask);
|
|
143
|
+
* ```
|
|
170
144
|
*/
|
|
171
|
-
declare
|
|
145
|
+
declare function createComputePipelineTasks(leafStageTask: TaskRef<ComputePipeline>): {
|
|
146
|
+
compile: _hello_terrain_work.Task<{
|
|
147
|
+
execute: (renderer: WebGPURenderer, instanceCount: number) => void;
|
|
148
|
+
}, string, unknown>;
|
|
149
|
+
execute: _hello_terrain_work.Task<any, string, {
|
|
150
|
+
renderer: WebGPURenderer;
|
|
151
|
+
}>;
|
|
152
|
+
};
|
|
172
153
|
|
|
173
154
|
declare const Dir: {
|
|
174
155
|
readonly LEFT: 0;
|
|
@@ -182,7 +163,9 @@ type TileId = {
|
|
|
182
163
|
/** 0 for flat terrain; 0..5 for cube-sphere faces */
|
|
183
164
|
space: number;
|
|
184
165
|
level: number;
|
|
166
|
+
/** tile coordinate at this level (signed to support infinite surfaces) */
|
|
185
167
|
x: number;
|
|
168
|
+
/** tile coordinate at this level (signed to support infinite surfaces) */
|
|
186
169
|
y: number;
|
|
187
170
|
};
|
|
188
171
|
type TileBounds = {
|
|
@@ -195,6 +178,8 @@ type TileBounds = {
|
|
|
195
178
|
};
|
|
196
179
|
type Surface = {
|
|
197
180
|
spaceCount: number;
|
|
181
|
+
/** maximum number of roots returned by `rootTiles` */
|
|
182
|
+
maxRootCount: number;
|
|
198
183
|
/**
|
|
199
184
|
* Compute the same-level neighbor TileId in the requested direction.
|
|
200
185
|
* Returns false if the neighbor is outside the valid topology.
|
|
@@ -211,6 +196,15 @@ type Surface = {
|
|
|
211
196
|
y: number;
|
|
212
197
|
z: number;
|
|
213
198
|
}, out: TileBounds): void;
|
|
199
|
+
/**
|
|
200
|
+
* Fill root tiles for the current frame and return the count.
|
|
201
|
+
* Implementations should write level-0 tiles into `out[0..count)`.
|
|
202
|
+
*/
|
|
203
|
+
rootTiles(cameraOrigin: {
|
|
204
|
+
x: number;
|
|
205
|
+
y: number;
|
|
206
|
+
z: number;
|
|
207
|
+
}, out: TileId[]): number;
|
|
214
208
|
};
|
|
215
209
|
type LeafSet = {
|
|
216
210
|
/** maximum number of leaves that fit in the buffers */
|
|
@@ -219,8 +213,8 @@ type LeafSet = {
|
|
|
219
213
|
count: number;
|
|
220
214
|
space: Uint8Array;
|
|
221
215
|
level: Uint8Array;
|
|
222
|
-
x:
|
|
223
|
-
y:
|
|
216
|
+
x: Int32Array;
|
|
217
|
+
y: Int32Array;
|
|
224
218
|
};
|
|
225
219
|
declare function allocLeafSet(capacity: number): LeafSet;
|
|
226
220
|
declare function resetLeafSet(leaves: LeafSet): void;
|
|
@@ -278,8 +272,8 @@ type NodeStore = {
|
|
|
278
272
|
gen: Uint16Array;
|
|
279
273
|
space: Uint8Array;
|
|
280
274
|
level: Uint8Array;
|
|
281
|
-
x:
|
|
282
|
-
y:
|
|
275
|
+
x: Int32Array;
|
|
276
|
+
y: Int32Array;
|
|
283
277
|
/** sentinel U32_EMPTY means no children; otherwise children are [firstChild..firstChild+3] */
|
|
284
278
|
firstChild: Uint32Array;
|
|
285
279
|
flags: Uint8Array;
|
|
@@ -319,6 +313,9 @@ type QuadtreeState = {
|
|
|
319
313
|
leafIndex: SpatialIndex;
|
|
320
314
|
/** traversal scratch */
|
|
321
315
|
stack: Uint32Array;
|
|
316
|
+
/** root nodes for this frame */
|
|
317
|
+
rootNodeIds: Uint32Array;
|
|
318
|
+
rootCount: number;
|
|
322
319
|
/** split scheduling scratch (dedupe without allocations) */
|
|
323
320
|
splitQueue: Uint32Array;
|
|
324
321
|
splitStamp: Uint16Array;
|
|
@@ -327,11 +324,12 @@ type QuadtreeState = {
|
|
|
327
324
|
scratchTile: TileId;
|
|
328
325
|
scratchNeighbor: TileId;
|
|
329
326
|
scratchBounds: TileBounds;
|
|
327
|
+
scratchRootTiles: TileId[];
|
|
330
328
|
/** surface space count is fixed for a given state */
|
|
331
329
|
spaceCount: number;
|
|
332
330
|
};
|
|
333
331
|
declare function createState(cfg: QuadtreeConfig, surface: Surface): QuadtreeState;
|
|
334
|
-
declare function beginUpdate(state: QuadtreeState, surface: Surface): void;
|
|
332
|
+
declare function beginUpdate(state: QuadtreeState, surface: Surface, params: UpdateParams): void;
|
|
335
333
|
|
|
336
334
|
/**
|
|
337
335
|
* Update the quadtree for the given surface + camera parameters.
|
|
@@ -364,6 +362,20 @@ type FlatSurfaceConfig = {
|
|
|
364
362
|
};
|
|
365
363
|
declare function createFlatSurface(cfg: FlatSurfaceConfig): Surface;
|
|
366
364
|
|
|
365
|
+
type InfiniteFlatSurfaceConfig = {
|
|
366
|
+
rootSize: number;
|
|
367
|
+
origin: {
|
|
368
|
+
x: number;
|
|
369
|
+
y: number;
|
|
370
|
+
z: number;
|
|
371
|
+
};
|
|
372
|
+
/** optional conservative vertical extent, included in bounds radius */
|
|
373
|
+
maxHeight?: number;
|
|
374
|
+
/** half-width of root grid in root tiles (1 => 3x3 roots) */
|
|
375
|
+
rootGridRadius?: number;
|
|
376
|
+
};
|
|
377
|
+
declare function createInfiniteFlatSurface(cfg: InfiniteFlatSurfaceConfig): Surface;
|
|
378
|
+
|
|
367
379
|
type CubeSphereSurfaceConfig = {
|
|
368
380
|
radius: number;
|
|
369
381
|
maxHeight?: number;
|
|
@@ -376,41 +388,12 @@ type CubeSphereSurfaceConfig = {
|
|
|
376
388
|
*/
|
|
377
389
|
declare function createCubeSphereSurface(_cfg: CubeSphereSurfaceConfig): Surface;
|
|
378
390
|
|
|
379
|
-
interface LeafStorageState {
|
|
380
|
-
data: Int32Array<ArrayBuffer>;
|
|
381
|
-
attribute: StorageBufferAttribute;
|
|
382
|
-
node: StorageBufferNode;
|
|
383
|
-
}
|
|
384
|
-
declare const quadtreeConfigTask: _hello_terrain_work.Task<{
|
|
385
|
-
state: QuadtreeState;
|
|
386
|
-
surface: Surface;
|
|
387
|
-
}, string, unknown>;
|
|
388
|
-
declare const quadtreeUpdateTask: _hello_terrain_work.Task<LeafSet, string, unknown>;
|
|
389
|
-
/**
|
|
390
|
-
* Creates the GPU storage buffer objects. Recreated when maxNodes changes.
|
|
391
|
-
*
|
|
392
|
-
* terrainVertextPositionNodeTask depends on this (not leafGpuBufferTask) so
|
|
393
|
-
* the shader is only rebuilt when the buffer is resized, not on every
|
|
394
|
-
* quadtree update.
|
|
395
|
-
*/
|
|
396
|
-
declare const leafStorageTask: _hello_terrain_work.Task<{
|
|
397
|
-
data: Int32Array<ArrayBuffer>;
|
|
398
|
-
attribute: StorageBufferAttribute;
|
|
399
|
-
node: StorageBufferNode;
|
|
400
|
-
}, string, unknown>;
|
|
401
|
-
declare const leafGpuBufferTask: _hello_terrain_work.Task<{
|
|
402
|
-
count: number;
|
|
403
|
-
data: Int32Array<ArrayBuffer>;
|
|
404
|
-
attribute: StorageBufferAttribute;
|
|
405
|
-
node: StorageBufferNode;
|
|
406
|
-
}, string, unknown>;
|
|
407
|
-
|
|
408
391
|
interface TerrainUniformsParams {
|
|
409
392
|
rootSize: number;
|
|
410
393
|
rootOrigin: Vector3Like;
|
|
411
394
|
innerTileSegments: number;
|
|
412
395
|
skirtScale: number;
|
|
413
|
-
|
|
396
|
+
elevationScale: number;
|
|
414
397
|
instanceId: string;
|
|
415
398
|
}
|
|
416
399
|
interface TerrainUniformsContext {
|
|
@@ -418,56 +401,109 @@ interface TerrainUniformsContext {
|
|
|
418
401
|
uRootSize: UniformNode<number>;
|
|
419
402
|
uInnerTileSegments: UniformNode<number>;
|
|
420
403
|
uSkirtScale: UniformNode<number>;
|
|
421
|
-
|
|
404
|
+
uElevationScale: UniformNode<number>;
|
|
405
|
+
}
|
|
406
|
+
interface LeafStorageState {
|
|
407
|
+
data: Int32Array<ArrayBuffer>;
|
|
408
|
+
attribute: StorageBufferAttribute;
|
|
409
|
+
node: StorageBufferNode;
|
|
422
410
|
}
|
|
423
|
-
/**
|
|
424
|
-
* Factory function for instance-specific uniforms for a TerrainMesh.
|
|
425
|
-
* Each TerrainMesh gets its own set of uniforms to avoid global state conflicts.
|
|
426
|
-
*/
|
|
427
|
-
declare function createTerrainUniforms(params: TerrainUniformsParams): TerrainUniformsContext;
|
|
428
|
-
|
|
429
|
-
declare function createTileWorldPosition(leafStorage: LeafStorageState, terrainUniforms: TerrainUniformsContext): three_src_nodes_TSL_js.ShaderCallNodeInternal;
|
|
430
|
-
|
|
431
|
-
/** Generates a unique instance ID per graph (cached once). */
|
|
432
|
-
declare const instanceIdTask: _hello_terrain_work.Task<`${string}-${string}-${string}-${string}-${string}`, string, unknown>;
|
|
433
411
|
|
|
434
|
-
declare function
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
surface: Surface;
|
|
441
|
-
}, string, unknown>;
|
|
442
|
-
readonly quadtreeUpdate: _hello_terrain_work.Task<LeafSet, string, unknown>;
|
|
443
|
-
readonly leafStorage: _hello_terrain_work.Task<{
|
|
444
|
-
data: Int32Array<ArrayBuffer>;
|
|
445
|
-
attribute: three_webgpu.StorageBufferAttribute;
|
|
446
|
-
node: three_webgpu.StorageBufferNode;
|
|
447
|
-
}, string, unknown>;
|
|
448
|
-
readonly leafGpuBuffer: _hello_terrain_work.Task<{
|
|
449
|
-
count: number;
|
|
450
|
-
data: Int32Array<ArrayBuffer>;
|
|
451
|
-
attribute: three_webgpu.StorageBufferAttribute;
|
|
452
|
-
node: three_webgpu.StorageBufferNode;
|
|
453
|
-
}, string, unknown>;
|
|
454
|
-
readonly createUniforms: _hello_terrain_work.Task<TerrainUniformsContext, string, unknown>;
|
|
455
|
-
readonly updateUniforms: _hello_terrain_work.Task<TerrainUniformsContext, string, unknown>;
|
|
456
|
-
readonly positionNode: _hello_terrain_work.Task<three_src_nodes_TSL_js.ShaderCallNodeInternal, string, unknown>;
|
|
412
|
+
declare function createTileCompute(leafStorage: LeafStorageState, uniforms: TerrainUniformsContext): {
|
|
413
|
+
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
414
|
+
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
415
|
+
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
416
|
+
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node, number | Node]>;
|
|
417
|
+
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node, number | Node]>;
|
|
457
418
|
};
|
|
458
419
|
|
|
420
|
+
interface QuadtreeConfigState {
|
|
421
|
+
state: QuadtreeState;
|
|
422
|
+
surface: Surface;
|
|
423
|
+
}
|
|
424
|
+
interface LeafGpuBufferState extends LeafStorageState {
|
|
425
|
+
count: number;
|
|
426
|
+
}
|
|
427
|
+
interface ElevationFieldContext {
|
|
428
|
+
data: Float32Array<ArrayBuffer>;
|
|
429
|
+
attribute: StorageBufferAttribute;
|
|
430
|
+
node: StorageBufferNode;
|
|
431
|
+
}
|
|
432
|
+
interface NormalFieldContext {
|
|
433
|
+
data: Uint32Array<ArrayBuffer>;
|
|
434
|
+
attribute: StorageBufferAttribute;
|
|
435
|
+
node: StorageBufferNode;
|
|
436
|
+
}
|
|
459
437
|
/** Task refs for the standard terrain pipeline. */
|
|
460
438
|
interface TerrainTasks {
|
|
461
439
|
instanceId: TaskRef<string>;
|
|
462
|
-
quadtreeConfig: TaskRef<
|
|
463
|
-
quadtreeUpdate: TaskRef<
|
|
440
|
+
quadtreeConfig: TaskRef<QuadtreeConfigState>;
|
|
441
|
+
quadtreeUpdate: TaskRef<LeafSet>;
|
|
442
|
+
surface: TaskRef<Surface>;
|
|
464
443
|
leafStorage: TaskRef<LeafStorageState>;
|
|
465
|
-
leafGpuBuffer: TaskRef<
|
|
444
|
+
leafGpuBuffer: TaskRef<LeafGpuBufferState>;
|
|
466
445
|
createUniforms: TaskRef<TerrainUniformsContext>;
|
|
467
446
|
updateUniforms: TaskRef<TerrainUniformsContext>;
|
|
468
447
|
positionNode: TaskRef<ShaderCallNodeInternal>;
|
|
448
|
+
createElevationFieldContext: TaskRef<ElevationFieldContext>;
|
|
449
|
+
createTileNodes: TaskRef<ReturnType<typeof createTileCompute>>;
|
|
450
|
+
createNormalFieldContext: TaskRef<NormalFieldContext>;
|
|
451
|
+
elevationFieldStage: TaskRef<ComputePipeline>;
|
|
452
|
+
normalFieldStage: TaskRef<ComputePipeline>;
|
|
453
|
+
compileCompute: TaskRef<{
|
|
454
|
+
execute: (renderer: WebGPURenderer, instanceCount: number) => void;
|
|
455
|
+
}>;
|
|
456
|
+
executeCompute: TaskRef<void | (() => void)>;
|
|
469
457
|
}
|
|
470
458
|
|
|
459
|
+
declare const createElevationFieldContextTask: _hello_terrain_work.Task<{
|
|
460
|
+
data: Float32Array<ArrayBuffer>;
|
|
461
|
+
attribute: StorageBufferAttribute;
|
|
462
|
+
node: three_webgpu.StorageBufferNode;
|
|
463
|
+
}, string, unknown>;
|
|
464
|
+
declare const tileNodesTask: _hello_terrain_work.Task<{
|
|
465
|
+
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
466
|
+
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
467
|
+
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
468
|
+
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
469
|
+
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
470
|
+
}, string, unknown>;
|
|
471
|
+
/**
|
|
472
|
+
* Root compute stage — generates elevation data and writes to the
|
|
473
|
+
* elevation field storage buffer. Returns a single-element `ComputePipeline`.
|
|
474
|
+
*/
|
|
475
|
+
declare const elevationFieldStageTask: _hello_terrain_work.Task<ComputePipeline, string, unknown>;
|
|
476
|
+
|
|
477
|
+
/** Generates a unique instance ID per graph (cached once). */
|
|
478
|
+
declare const instanceIdTask: _hello_terrain_work.Task<`${string}-${string}-${string}-${string}-${string}`, string, unknown>;
|
|
479
|
+
|
|
480
|
+
declare const createNormalFieldContextTask: _hello_terrain_work.Task<{
|
|
481
|
+
data: Uint32Array<ArrayBuffer>;
|
|
482
|
+
attribute: StorageBufferAttribute;
|
|
483
|
+
node: three_webgpu.StorageBufferNode;
|
|
484
|
+
}, string, unknown>;
|
|
485
|
+
/**
|
|
486
|
+
* Normal field compute stage — reads height neighbors from the elevation field
|
|
487
|
+
* buffer, computes surface normals via central differences, packs XZ
|
|
488
|
+
* components into a u32 via `packHalf2x16`, and writes to the normal field
|
|
489
|
+
* storage buffer.
|
|
490
|
+
*
|
|
491
|
+
* Accumulates the upstream elevation pipeline via `get(elevationFieldStageTask)`.
|
|
492
|
+
*/
|
|
493
|
+
declare const normalFieldStageTask: _hello_terrain_work.Task<ComputePipeline, string, unknown>;
|
|
494
|
+
|
|
495
|
+
interface ElevationParams {
|
|
496
|
+
worldPosition: Node$1;
|
|
497
|
+
rootSize: Node$1;
|
|
498
|
+
rootUV: Node$1;
|
|
499
|
+
tileUV: Node$1;
|
|
500
|
+
tileLevel: Node$1;
|
|
501
|
+
tileSize: Node$1;
|
|
502
|
+
tileOriginVec2: Node$1;
|
|
503
|
+
nodeIndex: Node$1;
|
|
504
|
+
}
|
|
505
|
+
type ElevationCallback = (params: ElevationParams) => Node$1;
|
|
506
|
+
|
|
471
507
|
/** Root tile size in world units. */
|
|
472
508
|
declare const rootSize: _hello_terrain_work.ParamRef<number>;
|
|
473
509
|
/** World-space origin of the terrain. */
|
|
@@ -476,29 +512,71 @@ declare const origin: _hello_terrain_work.ParamRef<{
|
|
|
476
512
|
y: number;
|
|
477
513
|
z: number;
|
|
478
514
|
}>;
|
|
479
|
-
/**
|
|
515
|
+
/**
|
|
516
|
+
* Number of segments per inner tile edge.
|
|
517
|
+
* 13 is the max tiles we can support for 256 workgroups (13 + 3 === 16.. 16x16)
|
|
518
|
+
*/
|
|
480
519
|
declare const innerTileSegments: _hello_terrain_work.ParamRef<number>;
|
|
481
520
|
/** Skirt scale factor. */
|
|
482
521
|
declare const skirtScale: _hello_terrain_work.ParamRef<number>;
|
|
483
|
-
/**
|
|
484
|
-
declare const
|
|
522
|
+
/** Elevation vertical scale. */
|
|
523
|
+
declare const elevationScale: _hello_terrain_work.ParamRef<number>;
|
|
485
524
|
/** Maximum quadtree nodes. */
|
|
486
525
|
declare const maxNodes: _hello_terrain_work.ParamRef<number>;
|
|
487
526
|
/** Maximum quadtree subdivision level. */
|
|
488
527
|
declare const maxLevel: _hello_terrain_work.ParamRef<number>;
|
|
489
528
|
/** Quadtree update configuration (camera, mode, etc.). */
|
|
490
529
|
declare const quadtreeUpdate: _hello_terrain_work.ParamRef<UpdateParams>;
|
|
530
|
+
/** Optional custom terrain surface; defaults to bounded flat surface when null. */
|
|
531
|
+
declare const surface: _hello_terrain_work.ParamRef<Surface | null>;
|
|
532
|
+
/** Terrain elevation control function (per vertex, in gpu compute) */
|
|
533
|
+
declare const elevationFn: _hello_terrain_work.ParamRef<ElevationCallback>;
|
|
491
534
|
|
|
492
535
|
/**
|
|
493
536
|
* Builds the TSL position node for the terrain shader.
|
|
494
537
|
*
|
|
495
|
-
* Depends on leafStorageTask (buffer objects)
|
|
496
|
-
* (uniform nodes)
|
|
538
|
+
* Depends on leafStorageTask (buffer objects), createUniformsTask
|
|
539
|
+
* (uniform nodes), createElevationFieldContextTask (elevation field storage),
|
|
540
|
+
* and createNormalFieldContextTask (normal field storage).
|
|
541
|
+
*
|
|
542
|
+
* The position node also reads normals from the normal field buffer
|
|
543
|
+
* per-vertex (using vertexIndex) and assigns them to the vNormal
|
|
544
|
+
* varying for use in the fragment shader.
|
|
545
|
+
*
|
|
546
|
+
* These only change when their GPU resources are recreated
|
|
497
547
|
* (e.g. buffer resize), so this task stays cached during normal quadtree
|
|
498
548
|
* updates — no unnecessary shader rebuilds.
|
|
499
549
|
*/
|
|
500
550
|
declare const positionNodeTask: _hello_terrain_work.Task<three_src_nodes_TSL_js.ShaderCallNodeInternal, string, unknown>;
|
|
501
551
|
|
|
552
|
+
/**
|
|
553
|
+
* Derives the terrain surface from `rootSize` and `origin`.
|
|
554
|
+
* Automatically recomputes when either param changes, keeping the
|
|
555
|
+
* quadtree refinement in sync with the GPU-side tile positioning.
|
|
556
|
+
*/
|
|
557
|
+
declare const surfaceTask: _hello_terrain_work.Task<Surface, string, unknown>;
|
|
558
|
+
declare const quadtreeConfigTask: _hello_terrain_work.Task<{
|
|
559
|
+
state: QuadtreeState;
|
|
560
|
+
surface: Surface;
|
|
561
|
+
}, string, unknown>;
|
|
562
|
+
declare const quadtreeUpdateTask: _hello_terrain_work.Task<LeafSet, string, unknown>;
|
|
563
|
+
/**
|
|
564
|
+
* Creates the GPU storage buffer objects. Recreated when maxNodes changes.
|
|
565
|
+
*
|
|
566
|
+
* positionNodeTask depends on this (not leafGpuBufferTask) so
|
|
567
|
+
* the shader is only rebuilt when the buffer is resized, not on every
|
|
568
|
+
* quadtree update.
|
|
569
|
+
*/
|
|
570
|
+
declare const leafStorageTask: _hello_terrain_work.Task<LeafStorageState, string, unknown>;
|
|
571
|
+
declare const leafGpuBufferTask: _hello_terrain_work.Task<{
|
|
572
|
+
count: number;
|
|
573
|
+
data: Int32Array<ArrayBuffer>;
|
|
574
|
+
attribute: three_webgpu.StorageBufferAttribute;
|
|
575
|
+
node: three_webgpu.StorageBufferNode;
|
|
576
|
+
}, string, unknown>;
|
|
577
|
+
|
|
578
|
+
declare function createTerrainUniforms(params: TerrainUniformsParams): TerrainUniformsContext;
|
|
579
|
+
|
|
502
580
|
/**
|
|
503
581
|
* Creates the terrain uniform nodes once. Downstream tasks capture
|
|
504
582
|
* references to these nodes in shader graphs, so the same instances
|
|
@@ -511,5 +589,126 @@ declare const createUniformsTask: _hello_terrain_work.Task<TerrainUniformsContex
|
|
|
511
589
|
*/
|
|
512
590
|
declare const updateUniformsTask: _hello_terrain_work.Task<TerrainUniformsContext, string, unknown>;
|
|
513
591
|
|
|
514
|
-
|
|
515
|
-
|
|
592
|
+
declare function terrainGraph(): _hello_terrain_work.Graph<string, {
|
|
593
|
+
renderer: WebGPURenderer;
|
|
594
|
+
}>;
|
|
595
|
+
/** All terrain task refs for direct access. */
|
|
596
|
+
declare const terrainTasks: {
|
|
597
|
+
readonly instanceId: _hello_terrain_work.Task<`${string}-${string}-${string}-${string}-${string}`, string, unknown>;
|
|
598
|
+
readonly quadtreeConfig: _hello_terrain_work.Task<{
|
|
599
|
+
state: QuadtreeState;
|
|
600
|
+
surface: Surface;
|
|
601
|
+
}, string, unknown>;
|
|
602
|
+
readonly quadtreeUpdate: _hello_terrain_work.Task<LeafSet, string, unknown>;
|
|
603
|
+
readonly leafStorage: _hello_terrain_work.Task<LeafStorageState, string, unknown>;
|
|
604
|
+
readonly surface: _hello_terrain_work.Task<Surface, string, unknown>;
|
|
605
|
+
readonly leafGpuBuffer: _hello_terrain_work.Task<{
|
|
606
|
+
count: number;
|
|
607
|
+
data: Int32Array<ArrayBuffer>;
|
|
608
|
+
attribute: three_webgpu.StorageBufferAttribute;
|
|
609
|
+
node: three_webgpu.StorageBufferNode;
|
|
610
|
+
}, string, unknown>;
|
|
611
|
+
readonly createUniforms: _hello_terrain_work.Task<TerrainUniformsContext, string, unknown>;
|
|
612
|
+
readonly updateUniforms: _hello_terrain_work.Task<TerrainUniformsContext, string, unknown>;
|
|
613
|
+
readonly positionNode: _hello_terrain_work.Task<three_src_nodes_TSL_js.ShaderCallNodeInternal, string, unknown>;
|
|
614
|
+
readonly createElevationFieldContext: _hello_terrain_work.Task<{
|
|
615
|
+
data: Float32Array<ArrayBuffer>;
|
|
616
|
+
attribute: three_webgpu.StorageBufferAttribute;
|
|
617
|
+
node: three_webgpu.StorageBufferNode;
|
|
618
|
+
}, string, unknown>;
|
|
619
|
+
readonly createTileNodes: _hello_terrain_work.Task<{
|
|
620
|
+
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
621
|
+
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
622
|
+
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
623
|
+
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
624
|
+
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
625
|
+
}, string, unknown>;
|
|
626
|
+
readonly createNormalFieldContext: _hello_terrain_work.Task<{
|
|
627
|
+
data: Uint32Array<ArrayBuffer>;
|
|
628
|
+
attribute: three_webgpu.StorageBufferAttribute;
|
|
629
|
+
node: three_webgpu.StorageBufferNode;
|
|
630
|
+
}, string, unknown>;
|
|
631
|
+
readonly elevationFieldStage: _hello_terrain_work.Task<ComputePipeline, string, unknown>;
|
|
632
|
+
readonly normalFieldStage: _hello_terrain_work.Task<ComputePipeline, string, unknown>;
|
|
633
|
+
readonly compileCompute: _hello_terrain_work.Task<{
|
|
634
|
+
execute: (renderer: WebGPURenderer, instanceCount: number) => void;
|
|
635
|
+
}, string, unknown>;
|
|
636
|
+
readonly executeCompute: _hello_terrain_work.Task<any, string, {
|
|
637
|
+
renderer: WebGPURenderer;
|
|
638
|
+
}>;
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Maps a value or node from texture space [0, 1] to vector space [-1, 1].
|
|
643
|
+
*
|
|
644
|
+
* @param value - The node or value in the range [0, 1].
|
|
645
|
+
* @returns A node mapping the input value to the range [-1, 1].
|
|
646
|
+
*/
|
|
647
|
+
declare const textureSpaceToVectorSpace: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node$1]>;
|
|
648
|
+
/**
|
|
649
|
+
* Maps a value or node from vector space [-1, 1] to texture space [0, 1].
|
|
650
|
+
*
|
|
651
|
+
* @param value - The node or value in the range [-1, 1].
|
|
652
|
+
* @returns A node mapping the input value to the range [0, 1].
|
|
653
|
+
*/
|
|
654
|
+
declare const vectorSpaceToTextureSpace: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node$1]>;
|
|
655
|
+
/**
|
|
656
|
+
* Blends two normal maps using the Reoriented Normal Mapping technique.
|
|
657
|
+
* This is the same algorithm used by Unreal Engine's BlendAngleCorrectedNormals node.
|
|
658
|
+
*
|
|
659
|
+
* Both inputs should be in vector space [-1, 1].
|
|
660
|
+
*
|
|
661
|
+
* @see https://blog.selfshadow.com/publications/blending-in-detail/
|
|
662
|
+
*/
|
|
663
|
+
declare const blendAngleCorrectedNormals: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node$1, number | Node$1]>;
|
|
664
|
+
/**
|
|
665
|
+
* Reconstructs the Z component of a normal from the X and Y components.
|
|
666
|
+
*
|
|
667
|
+
* @param normalXY - A vec2 containing the X and Y components of the normal
|
|
668
|
+
* @returns A vec3 with the reconstructed normal (X, Y, derived Z)
|
|
669
|
+
*/
|
|
670
|
+
declare const deriveNormalZ: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node$1]>;
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Input type for segment count: either a JS number or a TSL integer node.
|
|
674
|
+
* When a number is provided, it's automatically converted to an int node.
|
|
675
|
+
* When a Node is provided, it should resolve to an integer value.
|
|
676
|
+
*/
|
|
677
|
+
type IntNodeInput = number | ConstNode<number> | Node;
|
|
678
|
+
/**
|
|
679
|
+
* Returns a node that is true for skirt vertices in the vertex stage.
|
|
680
|
+
*
|
|
681
|
+
* @remarks
|
|
682
|
+
* Only valid in the vertex shader. A vertex belongs to the skirt if it is on
|
|
683
|
+
* the outermost ring of the tile grid (first/last column or row). The grid
|
|
684
|
+
* resolution is derived from `segments`.
|
|
685
|
+
*
|
|
686
|
+
* @param segments - The number of inner segments in the terrain grid.
|
|
687
|
+
* @returns A node resolving to a boolean indicating a skirt vertex.
|
|
688
|
+
*/
|
|
689
|
+
declare const isSkirtVertex: three_src_nodes_TSL_js.ShaderNodeFn<[segments: number | Node]>;
|
|
690
|
+
/**
|
|
691
|
+
* Returns a node that is true for skirt UVs.
|
|
692
|
+
*
|
|
693
|
+
* @remarks
|
|
694
|
+
* Uses interpolated UVs and the grid size
|
|
695
|
+
* from `segments` to mark fragments outside the inner range
|
|
696
|
+
* `(step, 1 - step)` on either axis as skirt, where `step = 1 / (segments + 2)`.
|
|
697
|
+
*
|
|
698
|
+
* @param segments - The number of inner segments in the terrain grid.
|
|
699
|
+
* @returns A node resolving to a boolean indicating a skirt fragment.
|
|
700
|
+
*/
|
|
701
|
+
declare const isSkirtUV: three_src_nodes_TSL_js.ShaderNodeFn<[segments: number | Node]>;
|
|
702
|
+
|
|
703
|
+
declare const vGlobalVertexIndex: three_webgpu.PropertyNode;
|
|
704
|
+
declare const vElevation: three_webgpu.PropertyNode;
|
|
705
|
+
|
|
706
|
+
declare const voronoiCells: three_src_nodes_TSL_js.ShaderNodeFn<[three_tsl.ProxiedObject<{
|
|
707
|
+
scale: number;
|
|
708
|
+
facet: number;
|
|
709
|
+
seed: number;
|
|
710
|
+
uv: Node;
|
|
711
|
+
}>]>;
|
|
712
|
+
|
|
713
|
+
export { Dir, TerrainGeometry, TerrainMesh, U32_EMPTY, allocLeafSet, allocSeamTable, beginUpdate, blendAngleCorrectedNormals, buildLeafIndex, buildSeams2to1, compileComputeTask, createComputePipelineTasks, createCubeSphereSurface, createElevationFieldContextTask, createFlatSurface, createInfiniteFlatSurface, createNormalFieldContextTask, createSpatialIndex, createState, createTerrainUniforms, createUniformsTask, deriveNormalZ, elevationFieldStageTask, elevationFn, elevationScale, executeComputeTask, innerTileSegments, instanceIdTask, isSkirtUV, isSkirtVertex, leafGpuBufferTask, leafStorageTask, maxLevel, maxNodes, normalFieldStageTask, origin, positionNodeTask, quadtreeConfigTask, quadtreeUpdate, quadtreeUpdateTask, resetLeafSet, resetSeamTable, rootSize, skirtScale, surface, surfaceTask, terrainGraph, terrainTasks, textureSpaceToVectorSpace, tileNodesTask, update, updateUniformsTask, vElevation, vGlobalVertexIndex, vectorSpaceToTextureSpace, voronoiCells };
|
|
714
|
+
export type { ComputePipeline, ComputeStageCallback, CubeSphereSurfaceConfig, ElevationCallback, ElevationFieldContext, ElevationParams, FlatSurfaceConfig, InfiniteFlatSurfaceConfig, IntNodeInput, LeafGpuBufferState, LeafSet, LeafStorageState, LodMode, NormalFieldContext, QuadtreeConfig, QuadtreeConfigState, QuadtreeState, SeamTable, SpatialIndex, Surface, TerrainTasks, TerrainUniformsContext, TerrainUniformsParams, TileBounds, TileId, UpdateParams };
|