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