@hello-terrain/three 0.0.0-alpha.10 → 0.0.0-alpha.11
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/dist/index.cjs +1374 -590
- package/dist/index.d.cts +488 -245
- package/dist/index.d.mts +488 -245
- package/dist/index.d.ts +488 -245
- package/dist/index.mjs +1355 -586
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,14 @@ import * as three_tsl from 'three/tsl';
|
|
|
13
13
|
* This geometry ensures that corner triangles are subdivided correctly.
|
|
14
14
|
*/
|
|
15
15
|
declare class TerrainGeometry extends BufferGeometry {
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* @param flipWinding Reverse triangle winding so front faces point the
|
|
18
|
+
* opposite way. The default winding makes flat tiles front-face `+Y`; the
|
|
19
|
+
* cube-sphere maps `(u→right, v→up)`, which would otherwise leave the
|
|
20
|
+
* planet's outer shell back-facing, so it passes `flipWinding` to render
|
|
21
|
+
* the outer surface with `FrontSide`.
|
|
22
|
+
*/
|
|
23
|
+
constructor(innerSegments?: number, extendUV?: boolean, flipWinding?: boolean);
|
|
17
24
|
/**
|
|
18
25
|
* Generate indices for terrain geometry with proper skirt corner handling.
|
|
19
26
|
* The key improvement is in how corner triangles are subdivided.
|
|
@@ -96,218 +103,6 @@ declare class TerrainGeometry extends BufferGeometry {
|
|
|
96
103
|
private generateNormals;
|
|
97
104
|
}
|
|
98
105
|
|
|
99
|
-
type TerrainFieldStorageBackendType = "array-texture" | "atlas" | "texture-3d";
|
|
100
|
-
type TerrainFieldStorageFormat = "rgba16float" | "rgba32float";
|
|
101
|
-
type TerrainFieldStorageOptions = {
|
|
102
|
-
backend?: TerrainFieldStorageBackendType;
|
|
103
|
-
filter?: "nearest" | "linear";
|
|
104
|
-
format?: TerrainFieldStorageFormat;
|
|
105
|
-
};
|
|
106
|
-
interface TerrainFieldStorage {
|
|
107
|
-
readonly backendType: TerrainFieldStorageBackendType;
|
|
108
|
-
readonly edgeVertexCount: number;
|
|
109
|
-
readonly tileCount: number;
|
|
110
|
-
readonly texture: StorageArrayTexture | StorageTexture;
|
|
111
|
-
uv(ix: Node, iy: Node, tileIndex: Node): Node;
|
|
112
|
-
texel(ix: Node, iy: Node, tileIndex: Node): Node;
|
|
113
|
-
/** UV-based filtered sample. `u, v` in [0, 1] tile-local space. */
|
|
114
|
-
sample(u: Node, v: Node, tileIndex: Node): Node;
|
|
115
|
-
resize(width: number, height: number, tileCount: number): void;
|
|
116
|
-
}
|
|
117
|
-
declare function ArrayTextureBackend(edgeVertexCount: number, tileCount: number, options: Required<Pick<TerrainFieldStorageOptions, "format" | "filter">>): TerrainFieldStorage;
|
|
118
|
-
declare function AtlasBackend(edgeVertexCount: number, tileCount: number, options: Required<Pick<TerrainFieldStorageOptions, "format" | "filter">>): TerrainFieldStorage;
|
|
119
|
-
/**
|
|
120
|
-
* Placeholder backend for future true 3D storage-texture support in Three.js.
|
|
121
|
-
* We keep it present to preserve the backend API shape.
|
|
122
|
-
*/
|
|
123
|
-
declare function Texture3DBackend(edgeVertexCount: number, tileCount: number, options: Required<Pick<TerrainFieldStorageOptions, "format" | "filter">>): TerrainFieldStorage;
|
|
124
|
-
declare function createTerrainFieldStorage(edgeVertexCount: number, tileCount: number, renderer?: WebGPURenderer, options?: TerrainFieldStorageOptions): TerrainFieldStorage;
|
|
125
|
-
declare function storeTerrainField(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node, value: Node): Node;
|
|
126
|
-
declare function loadTerrainField(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
127
|
-
declare function loadTerrainFieldElevation(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
128
|
-
declare function loadTerrainFieldNormal(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
129
|
-
/**
|
|
130
|
-
* UV-based filtered sample. `u, v` are in [0, 1] tile-local space.
|
|
131
|
-
* Respects the filter mode (nearest / linear) set on the storage.
|
|
132
|
-
*/
|
|
133
|
-
declare function sampleTerrainField(storage: TerrainFieldStorage, u: Node, v: Node, tileIndex: Node): Node;
|
|
134
|
-
declare function sampleTerrainFieldElevation(storage: TerrainFieldStorage, u: Node, v: Node, tileIndex: Node): Node;
|
|
135
|
-
declare function sampleTerrainFieldNormal(storage: TerrainFieldStorage, u: Node, v: Node, tileIndex: Node): Node;
|
|
136
|
-
declare function packTerrainFieldSample(height: Node, normalXZ: Node, extra?: Node): Node;
|
|
137
|
-
|
|
138
|
-
interface ElevationParams {
|
|
139
|
-
worldPosition: Node$1;
|
|
140
|
-
rootSize: Node$1;
|
|
141
|
-
rootUV: Node$1;
|
|
142
|
-
tileUV: Node$1;
|
|
143
|
-
tileLevel: Node$1;
|
|
144
|
-
tileSize: Node$1;
|
|
145
|
-
tileOriginVec2: Node$1;
|
|
146
|
-
nodeIndex: Node$1;
|
|
147
|
-
}
|
|
148
|
-
type ElevationCallback = (params: ElevationParams) => Node$1;
|
|
149
|
-
|
|
150
|
-
interface TerrainUniformsParams {
|
|
151
|
-
rootSize: number;
|
|
152
|
-
rootOrigin: Vector3Like;
|
|
153
|
-
innerTileSegments: number;
|
|
154
|
-
skirtScale: number;
|
|
155
|
-
elevationScale: number;
|
|
156
|
-
instanceId: string;
|
|
157
|
-
}
|
|
158
|
-
interface TerrainUniformsContext {
|
|
159
|
-
uRootOrigin: UniformNode<Vector3>;
|
|
160
|
-
uRootSize: UniformNode<number>;
|
|
161
|
-
uInnerTileSegments: UniformNode<number>;
|
|
162
|
-
uSkirtScale: UniformNode<number>;
|
|
163
|
-
uElevationScale: UniformNode<number>;
|
|
164
|
-
}
|
|
165
|
-
interface LeafStorageState {
|
|
166
|
-
data: Int32Array<ArrayBuffer>;
|
|
167
|
-
attribute: StorageBufferAttribute;
|
|
168
|
-
node: StorageBufferNode;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
interface GpuSpatialIndexContext {
|
|
172
|
-
data: Uint32Array<ArrayBuffer>;
|
|
173
|
-
size: number;
|
|
174
|
-
mask: number;
|
|
175
|
-
stampGen: UniformNode<number>;
|
|
176
|
-
attribute: StorageBufferAttribute;
|
|
177
|
-
node: StorageBufferNode;
|
|
178
|
-
}
|
|
179
|
-
interface TerrainSampler {
|
|
180
|
-
sampleElevation: (worldX: Node, worldZ: Node) => Node;
|
|
181
|
-
sampleNormal: (worldX: Node, worldZ: Node) => Node;
|
|
182
|
-
sampleTerrain: (worldX: Node, worldZ: Node) => Node;
|
|
183
|
-
sampleValidity: (worldX: Node, worldZ: Node) => Node;
|
|
184
|
-
evaluateElevation: (worldX: Node, worldZ: Node) => Node;
|
|
185
|
-
evaluateNormal: (worldX: Node, worldZ: Node, epsilon?: Node) => Node;
|
|
186
|
-
}
|
|
187
|
-
interface CreateTerrainSamplerParams {
|
|
188
|
-
terrainFieldStorage: TerrainFieldStorage;
|
|
189
|
-
spatialIndex: GpuSpatialIndexContext;
|
|
190
|
-
uniforms: TerrainUniformsContext;
|
|
191
|
-
elevationCallback: ElevationCallback;
|
|
192
|
-
}
|
|
193
|
-
interface TerrainSample {
|
|
194
|
-
elevation: number;
|
|
195
|
-
normal: Vector3$1;
|
|
196
|
-
valid: boolean;
|
|
197
|
-
}
|
|
198
|
-
interface TerrainElevationSample {
|
|
199
|
-
elevation: number;
|
|
200
|
-
valid: boolean;
|
|
201
|
-
}
|
|
202
|
-
interface TerrainSampleBatch {
|
|
203
|
-
elevations: Float32Array;
|
|
204
|
-
normals: Float32Array;
|
|
205
|
-
valid: Uint8Array;
|
|
206
|
-
generation: number;
|
|
207
|
-
}
|
|
208
|
-
interface TerrainTile {
|
|
209
|
-
level: number;
|
|
210
|
-
x: number;
|
|
211
|
-
y: number;
|
|
212
|
-
index: number;
|
|
213
|
-
}
|
|
214
|
-
interface TerrainTileBounds extends TerrainTile {
|
|
215
|
-
minElevation: number;
|
|
216
|
-
maxElevation: number;
|
|
217
|
-
}
|
|
218
|
-
interface ElevationRange {
|
|
219
|
-
min: number;
|
|
220
|
-
max: number;
|
|
221
|
-
}
|
|
222
|
-
interface TerrainQuery {
|
|
223
|
-
getElevation(worldX: number, worldZ: number): number | null;
|
|
224
|
-
getNormal(worldX: number, worldZ: number): Vector3$1 | null;
|
|
225
|
-
getTile(worldX: number, worldZ: number): TerrainTile | null;
|
|
226
|
-
getTileBounds(worldX: number, worldZ: number): TerrainTileBounds | null;
|
|
227
|
-
getGlobalElevationRange(): ElevationRange | null;
|
|
228
|
-
sampleTerrain(worldX: number, worldZ: number): TerrainSample;
|
|
229
|
-
sampleTerrainBatch(positions: Float32Array): TerrainSampleBatch;
|
|
230
|
-
readonly generation: number;
|
|
231
|
-
}
|
|
232
|
-
interface RaycastOptions {
|
|
233
|
-
maxSteps?: number;
|
|
234
|
-
refinementSteps?: number;
|
|
235
|
-
maxDistance?: number;
|
|
236
|
-
}
|
|
237
|
-
interface TerrainRaycastResult {
|
|
238
|
-
position: Vector3$1;
|
|
239
|
-
normal: Vector3$1;
|
|
240
|
-
distance: number;
|
|
241
|
-
}
|
|
242
|
-
interface TerrainRaycast {
|
|
243
|
-
pick(ray: Ray, options?: RaycastOptions): TerrainRaycastResult | null;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
type TerrainMeshParams = {
|
|
247
|
-
innerTileSegments: number;
|
|
248
|
-
maxNodes: number;
|
|
249
|
-
material: NodeMaterial;
|
|
250
|
-
};
|
|
251
|
-
declare class TerrainMesh extends InstancedMesh {
|
|
252
|
-
private _innerTileSegments;
|
|
253
|
-
private _maxNodes;
|
|
254
|
-
terrainRaycast: TerrainRaycast | null;
|
|
255
|
-
constructor(params?: Partial<TerrainMeshParams>);
|
|
256
|
-
get innerTileSegments(): number;
|
|
257
|
-
set innerTileSegments(tileSegments: number);
|
|
258
|
-
get maxNodes(): number;
|
|
259
|
-
set maxNodes(maxNodes: number);
|
|
260
|
-
raycast(raycaster: Raycaster, intersects: Intersection[]): void;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
interface TileBoundsContext {
|
|
264
|
-
data: Float32Array<ArrayBuffer>;
|
|
265
|
-
attribute: StorageBufferAttribute;
|
|
266
|
-
node: StorageBufferNode;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
type ComputeStageCallback = (nodeIndex: Node, globalVertexIndex: Node, uv: Node, localCoordinates: Node, texelSize: Node) => void;
|
|
270
|
-
type ComputePipeline = ComputeStageCallback[];
|
|
271
|
-
|
|
272
|
-
/** Default compile task — uses terrainFieldStageTask as the leaf. */
|
|
273
|
-
declare const compileComputeTask: _hello_terrain_work.Task<{
|
|
274
|
-
execute: (renderer: WebGPURenderer, instanceCount: number) => void;
|
|
275
|
-
}, string, unknown>;
|
|
276
|
-
/** Default execute task — dispatches the compiled kernel. */
|
|
277
|
-
declare const executeComputeTask: _hello_terrain_work.Task<any, string, {
|
|
278
|
-
renderer: WebGPURenderer;
|
|
279
|
-
}>;
|
|
280
|
-
/**
|
|
281
|
-
* Factory for user-extensible pipelines.
|
|
282
|
-
*
|
|
283
|
-
* Users who add custom compute stages create their own stage tasks using
|
|
284
|
-
* the accumulation pattern (`get()` predecessor, spread, append), then pass
|
|
285
|
-
* their leaf stage to this helper to get compile + execute tasks.
|
|
286
|
-
*
|
|
287
|
-
* @example
|
|
288
|
-
* ```ts
|
|
289
|
-
* const erosionStageTask = task((get, work) => {
|
|
290
|
-
* const upstream = get(elevationFieldStageTask);
|
|
291
|
-
* return work((): ComputePipeline => [
|
|
292
|
-
* ...upstream,
|
|
293
|
-
* (nodeIndex, globalVertexIndex, uv) => {
|
|
294
|
-
* // custom erosion logic
|
|
295
|
-
* },
|
|
296
|
-
* ]);
|
|
297
|
-
* });
|
|
298
|
-
*
|
|
299
|
-
* const { compile, execute } = createComputePipelineTasks(erosionStageTask);
|
|
300
|
-
* ```
|
|
301
|
-
*/
|
|
302
|
-
declare function createComputePipelineTasks(leafStageTask: TaskRef<ComputePipeline>): {
|
|
303
|
-
compile: _hello_terrain_work.Task<{
|
|
304
|
-
execute: (renderer: WebGPURenderer, instanceCount: number) => void;
|
|
305
|
-
}, string, unknown>;
|
|
306
|
-
execute: _hello_terrain_work.Task<any, string, {
|
|
307
|
-
renderer: WebGPURenderer;
|
|
308
|
-
}>;
|
|
309
|
-
};
|
|
310
|
-
|
|
311
106
|
declare const Dir: {
|
|
312
107
|
readonly LEFT: 0;
|
|
313
108
|
readonly RIGHT: 1;
|
|
@@ -333,10 +128,27 @@ type TileBounds = {
|
|
|
333
128
|
/** conservative radius */
|
|
334
129
|
r: number;
|
|
335
130
|
};
|
|
336
|
-
type
|
|
131
|
+
type TopologyProjection = "flat" | "cubeSphere";
|
|
132
|
+
type Topology = {
|
|
337
133
|
spaceCount: number;
|
|
338
134
|
/** maximum number of roots returned by `rootTiles` */
|
|
339
135
|
maxRootCount: number;
|
|
136
|
+
/**
|
|
137
|
+
* GPU position/normal assembly projection. Defaults to `flat` when absent.
|
|
138
|
+
* `cubeSphere` selects radial sphere mapping from cube faces.
|
|
139
|
+
*/
|
|
140
|
+
projection?: TopologyProjection;
|
|
141
|
+
/** Sphere radius in world units (cube-sphere projection only). */
|
|
142
|
+
radius?: number;
|
|
143
|
+
/**
|
|
144
|
+
* Planet center in world space (cube-sphere projection only). Used to apply
|
|
145
|
+
* the camera elevation offset along the radial up-direction during LOD.
|
|
146
|
+
*/
|
|
147
|
+
center?: {
|
|
148
|
+
x: number;
|
|
149
|
+
y: number;
|
|
150
|
+
z: number;
|
|
151
|
+
};
|
|
340
152
|
/**
|
|
341
153
|
* Compute the same-level neighbor TileId in the requested direction.
|
|
342
154
|
* Returns false if the neighbor is outside the valid topology.
|
|
@@ -400,9 +212,11 @@ type UpdateParams = {
|
|
|
400
212
|
z: number;
|
|
401
213
|
};
|
|
402
214
|
/**
|
|
403
|
-
* Terrain elevation
|
|
404
|
-
*
|
|
405
|
-
*
|
|
215
|
+
* Terrain elevation beneath the camera (from the previous frame). During
|
|
216
|
+
* refinement it offsets the camera toward the terrain surface so LOD distance
|
|
217
|
+
* is measured relative to the surface rather than the datum:
|
|
218
|
+
* - flat: subtracted from `cameraOrigin.y`.
|
|
219
|
+
* - cube-sphere: subtracted along the radial up-direction from the planet center.
|
|
406
220
|
*/
|
|
407
221
|
elevationAtCameraXZ?: number;
|
|
408
222
|
/**
|
|
@@ -488,18 +302,18 @@ type QuadtreeState = {
|
|
|
488
302
|
scratchNeighbor: TileId;
|
|
489
303
|
scratchBounds: TileBounds;
|
|
490
304
|
scratchRootTiles: TileId[];
|
|
491
|
-
/**
|
|
305
|
+
/** topology space count is fixed for a given state */
|
|
492
306
|
spaceCount: number;
|
|
493
307
|
};
|
|
494
|
-
declare function createState(cfg: QuadtreeConfig,
|
|
495
|
-
declare function beginUpdate(state: QuadtreeState,
|
|
308
|
+
declare function createState(cfg: QuadtreeConfig, topology: Topology): QuadtreeState;
|
|
309
|
+
declare function beginUpdate(state: QuadtreeState, topology: Topology, params: UpdateParams): void;
|
|
496
310
|
|
|
497
311
|
/**
|
|
498
|
-
* Update the quadtree for the given
|
|
312
|
+
* Update the quadtree for the given topology + camera parameters.
|
|
499
313
|
*
|
|
500
314
|
* Produces a LeafSet of TileIds (SoA typed arrays).
|
|
501
315
|
*/
|
|
502
|
-
declare function update(state: QuadtreeState,
|
|
316
|
+
declare function update(state: QuadtreeState, topology: Topology, params: UpdateParams, outLeaves?: LeafSet): LeafSet;
|
|
503
317
|
|
|
504
318
|
/**
|
|
505
319
|
* Build a fixed-width seam/neighbor table for balanced leaves (2:1).
|
|
@@ -507,9 +321,9 @@ declare function update(state: QuadtreeState, surface: Surface, params: UpdatePa
|
|
|
507
321
|
* Output neighbors are leaf-list indices, with U32_EMPTY for missing entries.
|
|
508
322
|
* Layout: neighbors[leafIndex * 8 + edge*2 + slot].
|
|
509
323
|
*/
|
|
510
|
-
declare function buildSeams2to1(
|
|
324
|
+
declare function buildSeams2to1(topology: Topology, leaves: LeafSet, outSeams: SeamTable, outIndex?: SpatialIndex): SeamTable;
|
|
511
325
|
|
|
512
|
-
type
|
|
326
|
+
type FlatTopologyConfig = {
|
|
513
327
|
/**
|
|
514
328
|
* World-space size of the root tile edge.
|
|
515
329
|
* The root tile covers [-rootSize/2, +rootSize/2] around origin in X/Z.
|
|
@@ -523,9 +337,9 @@ type FlatSurfaceConfig = {
|
|
|
523
337
|
/** optional conservative vertical extent, included in bounds radius */
|
|
524
338
|
maxHeight?: number;
|
|
525
339
|
};
|
|
526
|
-
declare function
|
|
340
|
+
declare function createFlatTopology(cfg: FlatTopologyConfig): Topology;
|
|
527
341
|
|
|
528
|
-
type
|
|
342
|
+
type InfiniteFlatTopologyConfig = {
|
|
529
343
|
rootSize: number;
|
|
530
344
|
origin: {
|
|
531
345
|
x: number;
|
|
@@ -537,24 +351,368 @@ type InfiniteFlatSurfaceConfig = {
|
|
|
537
351
|
/** half-width of root grid in root tiles (1 => 3x3 roots) */
|
|
538
352
|
rootGridRadius?: number;
|
|
539
353
|
};
|
|
540
|
-
declare function
|
|
354
|
+
declare function createInfiniteFlatTopology(cfg: InfiniteFlatTopologyConfig): Topology;
|
|
541
355
|
|
|
542
|
-
type
|
|
356
|
+
type CubeSphereTopologyConfig = {
|
|
357
|
+
/** Sphere radius in world units. */
|
|
543
358
|
radius: number;
|
|
359
|
+
/** Planet center in world space (defaults to origin). */
|
|
360
|
+
center?: {
|
|
361
|
+
x: number;
|
|
362
|
+
y: number;
|
|
363
|
+
z: number;
|
|
364
|
+
};
|
|
365
|
+
/** Optional conservative vertical extent, included in bounds radius. */
|
|
544
366
|
maxHeight?: number;
|
|
545
367
|
};
|
|
546
368
|
/**
|
|
547
|
-
*
|
|
369
|
+
* Cube-sphere topology: six quadtree faces wrapped onto a sphere.
|
|
370
|
+
*
|
|
371
|
+
* Topology (`neighborSameLevel`) is derived numerically from the shared
|
|
372
|
+
* `CUBE_FACES` basis so cross-face edges (including rotated pole edges)
|
|
373
|
+
* resolve to the correct neighbor tile without hand-coded transforms.
|
|
374
|
+
*/
|
|
375
|
+
declare function createCubeSphereTopology(cfg: CubeSphereTopologyConfig): Topology;
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Canonical cube-sphere face basis.
|
|
379
|
+
*
|
|
380
|
+
* Shared single source of truth between the CPU surface topology
|
|
381
|
+
* (`cubeSphere.ts`) and the GPU position/normal assembly (`tsl/cubeSphere.ts`)
|
|
382
|
+
* so both agree on geometry and faces seam correctly.
|
|
383
|
+
*
|
|
384
|
+
* Each face maps a face-local coordinate (u, v) in [0, 1] to a point on the
|
|
385
|
+
* cube `[-1, 1]^3` via:
|
|
386
|
+
*
|
|
387
|
+
* s = 2u - 1, t = 2v - 1
|
|
388
|
+
* cube = forward + s * right + t * up
|
|
389
|
+
*
|
|
390
|
+
* Normalizing `cube` yields the unit-sphere direction for that vertex.
|
|
391
|
+
*
|
|
392
|
+
* Bases are right-handed (`forward = right x up`) and outward-facing.
|
|
393
|
+
* Space indices: 0:+X 1:-X 2:+Y 3:-Y 4:+Z 5:-Z.
|
|
394
|
+
*/
|
|
395
|
+
type Vec3 = readonly [number, number, number];
|
|
396
|
+
type CubeFace = {
|
|
397
|
+
forward: Vec3;
|
|
398
|
+
right: Vec3;
|
|
399
|
+
up: Vec3;
|
|
400
|
+
};
|
|
401
|
+
declare const CUBE_FACE_COUNT = 6;
|
|
402
|
+
declare const CUBE_FACES: readonly CubeFace[];
|
|
403
|
+
|
|
404
|
+
type Vec3Mutable = [number, number, number];
|
|
405
|
+
/**
|
|
406
|
+
* Cube-space point for a face-local coordinate (u, v) in [0, 1]:
|
|
407
|
+
* cube = forward + (2u-1) * right + (2v-1) * up
|
|
408
|
+
* The result is unnormalized; normalize it to obtain the sphere direction.
|
|
409
|
+
*/
|
|
410
|
+
declare function faceUVToCube(face: number, u: number, v: number, out: Vec3Mutable): void;
|
|
411
|
+
/** Pick the cube face whose normal axis dominates the direction. */
|
|
412
|
+
declare function directionToFace(d: Vec3): number;
|
|
413
|
+
/** Face-local (u, v) in [0, 1] for a direction known to fall on `face`. */
|
|
414
|
+
declare function directionToFaceUV(face: number, d: Vec3, out: [number, number]): void;
|
|
415
|
+
/**
|
|
416
|
+
* Convert latitude/longitude (degrees) to a unit sphere direction.
|
|
417
|
+
*
|
|
418
|
+
* Convention matches `CUBE_FACES` (+Y is the north pole):
|
|
419
|
+
* - latitude is the angle above the equator, in `[-90, 90]`
|
|
420
|
+
* - longitude is the angle around the +Y axis, in `[-180, 180]`,
|
|
421
|
+
* measured from +Z toward +X (lon = 0 points along +Z).
|
|
422
|
+
*/
|
|
423
|
+
declare function latLongToDirection(latDeg: number, lonDeg: number, out: Vec3Mutable): void;
|
|
424
|
+
/** Inverse of {@link latLongToDirection}; returns degrees. */
|
|
425
|
+
declare function directionToLatLong(d: Vec3): {
|
|
426
|
+
latitude: number;
|
|
427
|
+
longitude: number;
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
type TerrainFieldStorageBackendType = "array-texture" | "atlas" | "texture-3d";
|
|
431
|
+
type TerrainFieldStorageFormat = "rgba16float" | "rgba32float";
|
|
432
|
+
type TerrainFieldStorageOptions = {
|
|
433
|
+
backend?: TerrainFieldStorageBackendType;
|
|
434
|
+
filter?: "nearest" | "linear";
|
|
435
|
+
format?: TerrainFieldStorageFormat;
|
|
436
|
+
};
|
|
437
|
+
interface TerrainFieldStorage {
|
|
438
|
+
readonly backendType: TerrainFieldStorageBackendType;
|
|
439
|
+
readonly edgeVertexCount: number;
|
|
440
|
+
readonly tileCount: number;
|
|
441
|
+
readonly texture: StorageArrayTexture | StorageTexture;
|
|
442
|
+
uv(ix: Node, iy: Node, tileIndex: Node): Node;
|
|
443
|
+
texel(ix: Node, iy: Node, tileIndex: Node): Node;
|
|
444
|
+
/** UV-based filtered sample. `u, v` in [0, 1] tile-local space. */
|
|
445
|
+
sample(u: Node, v: Node, tileIndex: Node): Node;
|
|
446
|
+
resize(width: number, height: number, tileCount: number): void;
|
|
447
|
+
}
|
|
448
|
+
declare function ArrayTextureBackend(edgeVertexCount: number, tileCount: number, options: Required<Pick<TerrainFieldStorageOptions, "format" | "filter">>): TerrainFieldStorage;
|
|
449
|
+
declare function AtlasBackend(edgeVertexCount: number, tileCount: number, options: Required<Pick<TerrainFieldStorageOptions, "format" | "filter">>): TerrainFieldStorage;
|
|
450
|
+
declare function createTerrainFieldStorage(edgeVertexCount: number, tileCount: number, renderer?: WebGPURenderer, options?: TerrainFieldStorageOptions): TerrainFieldStorage;
|
|
451
|
+
declare function storeTerrainField(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node, value: Node): Node;
|
|
452
|
+
declare function loadTerrainField(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
453
|
+
declare function loadTerrainFieldElevation(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
454
|
+
declare function loadTerrainFieldNormal(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
455
|
+
/**
|
|
456
|
+
* UV-based filtered sample. `u, v` are in [0, 1] tile-local space.
|
|
457
|
+
* Respects the filter mode (nearest / linear) set on the storage.
|
|
458
|
+
*/
|
|
459
|
+
declare function sampleTerrainField(storage: TerrainFieldStorage, u: Node, v: Node, tileIndex: Node): Node;
|
|
460
|
+
declare function sampleTerrainFieldElevation(storage: TerrainFieldStorage, u: Node, v: Node, tileIndex: Node): Node;
|
|
461
|
+
declare function packTerrainFieldSample(height: Node, normalXZ: Node, extra?: Node): Node;
|
|
462
|
+
|
|
463
|
+
interface ElevationParams {
|
|
464
|
+
worldPosition: Node$1;
|
|
465
|
+
rootSize: Node$1;
|
|
466
|
+
rootUV: Node$1;
|
|
467
|
+
tileUV: Node$1;
|
|
468
|
+
tileLevel: Node$1;
|
|
469
|
+
tileSize: Node$1;
|
|
470
|
+
tileOriginVec2: Node$1;
|
|
471
|
+
nodeIndex: Node$1;
|
|
472
|
+
}
|
|
473
|
+
type ElevationCallback = (params: ElevationParams) => Node$1;
|
|
474
|
+
|
|
475
|
+
interface TerrainUniformsParams {
|
|
476
|
+
rootSize: number;
|
|
477
|
+
rootOrigin: Vector3Like;
|
|
478
|
+
innerTileSegments: number;
|
|
479
|
+
skirtScale: number;
|
|
480
|
+
elevationScale: number;
|
|
481
|
+
radius: number;
|
|
482
|
+
instanceId: string;
|
|
483
|
+
}
|
|
484
|
+
interface TerrainUniformsContext {
|
|
485
|
+
uRootOrigin: UniformNode<Vector3>;
|
|
486
|
+
uRootSize: UniformNode<number>;
|
|
487
|
+
uInnerTileSegments: UniformNode<number>;
|
|
488
|
+
uSkirtScale: UniformNode<number>;
|
|
489
|
+
uElevationScale: UniformNode<number>;
|
|
490
|
+
uRadius: UniformNode<number>;
|
|
491
|
+
}
|
|
492
|
+
interface LeafStorageState {
|
|
493
|
+
data: Int32Array<ArrayBuffer>;
|
|
494
|
+
attribute: StorageBufferAttribute;
|
|
495
|
+
node: StorageBufferNode;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
interface GpuSpatialIndexContext {
|
|
499
|
+
data: Uint32Array<ArrayBuffer>;
|
|
500
|
+
size: number;
|
|
501
|
+
mask: number;
|
|
502
|
+
stampGen: UniformNode<number>;
|
|
503
|
+
attribute: StorageBufferAttribute;
|
|
504
|
+
node: StorageBufferNode;
|
|
505
|
+
}
|
|
506
|
+
interface TerrainSampler {
|
|
507
|
+
sampleElevation: (worldX: Node, worldZ: Node) => Node;
|
|
508
|
+
sampleNormal: (worldX: Node, worldZ: Node) => Node;
|
|
509
|
+
sampleTerrain: (worldX: Node, worldZ: Node) => Node;
|
|
510
|
+
sampleValidity: (worldX: Node, worldZ: Node) => Node;
|
|
511
|
+
evaluateElevation: (worldX: Node, worldZ: Node) => Node;
|
|
512
|
+
evaluateNormal: (worldX: Node, worldZ: Node, epsilon?: Node) => Node;
|
|
513
|
+
/** Packed `vec4(elevation, nx, ny, nz)` where the normal is tangent-space. */
|
|
514
|
+
sampleTerrainByDirection?: (direction: Node) => Node;
|
|
515
|
+
sampleElevationByDirection?: (direction: Node) => Node;
|
|
516
|
+
/** World-space surface normal reconstructed in the sphere tangent frame. */
|
|
517
|
+
sampleNormalByDirection?: (direction: Node) => Node;
|
|
518
|
+
sampleValidityByDirection?: (direction: Node) => Node;
|
|
519
|
+
}
|
|
520
|
+
interface CreateTerrainSamplerParams {
|
|
521
|
+
terrainFieldStorage: TerrainFieldStorage;
|
|
522
|
+
spatialIndex: GpuSpatialIndexContext;
|
|
523
|
+
uniforms: TerrainUniformsContext;
|
|
524
|
+
elevationCallback: ElevationCallback;
|
|
525
|
+
/** Maximum quadtree level to probe during tile lookup. */
|
|
526
|
+
maxLevel: number;
|
|
527
|
+
projection?: TopologyProjection;
|
|
528
|
+
}
|
|
529
|
+
interface TerrainSample {
|
|
530
|
+
elevation: number;
|
|
531
|
+
normal: Vector3$1;
|
|
532
|
+
valid: boolean;
|
|
533
|
+
}
|
|
534
|
+
interface TerrainSampleBatch {
|
|
535
|
+
elevations: Float32Array;
|
|
536
|
+
normals: Float32Array;
|
|
537
|
+
valid: Uint8Array;
|
|
538
|
+
generation: number;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Result of sampling a cube-sphere surface from a direction/position/lat-long.
|
|
542
|
+
*
|
|
543
|
+
* `elevation` is the radial displacement above the base radius (already scaled
|
|
544
|
+
* by `elevationScale`); `position` is the full world-space surface point
|
|
545
|
+
* `center + direction * (radius + elevation)`.
|
|
546
|
+
*/
|
|
547
|
+
interface TerrainSurfaceSample {
|
|
548
|
+
position: Vector3$1;
|
|
549
|
+
normal: Vector3$1;
|
|
550
|
+
direction: Vector3$1;
|
|
551
|
+
elevation: number;
|
|
552
|
+
valid: boolean;
|
|
553
|
+
}
|
|
554
|
+
interface TerrainSurfaceSampleBatch {
|
|
555
|
+
positions: Float32Array;
|
|
556
|
+
normals: Float32Array;
|
|
557
|
+
elevations: Float32Array;
|
|
558
|
+
valid: Uint8Array;
|
|
559
|
+
generation: number;
|
|
560
|
+
}
|
|
561
|
+
interface TerrainTile {
|
|
562
|
+
/** Surface space index: 0 for flat terrain, 0..5 for cube-sphere faces. */
|
|
563
|
+
space: number;
|
|
564
|
+
level: number;
|
|
565
|
+
x: number;
|
|
566
|
+
y: number;
|
|
567
|
+
index: number;
|
|
568
|
+
}
|
|
569
|
+
interface TerrainTileBounds extends TerrainTile {
|
|
570
|
+
minElevation: number;
|
|
571
|
+
maxElevation: number;
|
|
572
|
+
}
|
|
573
|
+
interface ElevationRange {
|
|
574
|
+
min: number;
|
|
575
|
+
max: number;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Flat (heightfield) terrain query, keyed on world XZ. For cube-sphere
|
|
579
|
+
* surfaces use {@link TerrainSphereQuery} instead.
|
|
580
|
+
*/
|
|
581
|
+
interface TerrainQuery {
|
|
582
|
+
getElevation(worldX: number, worldZ: number): number | null;
|
|
583
|
+
getNormal(worldX: number, worldZ: number): Vector3$1 | null;
|
|
584
|
+
getTile(worldX: number, worldZ: number): TerrainTile | null;
|
|
585
|
+
getTileBounds(worldX: number, worldZ: number): TerrainTileBounds | null;
|
|
586
|
+
getGlobalElevationRange(): ElevationRange | null;
|
|
587
|
+
sampleTerrain(worldX: number, worldZ: number): TerrainSample;
|
|
588
|
+
sampleTerrainBatch(positions: Float32Array): TerrainSampleBatch;
|
|
589
|
+
readonly generation: number;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Cube-sphere terrain query. A surface location is identified by a direction
|
|
593
|
+
* from the planet center (the canonical form); `ByPosition` projects any world
|
|
594
|
+
* point onto its direction, and `ByLatLong` takes degrees (latitude
|
|
595
|
+
* `[-90, 90]`, longitude `[-180, 180]`). Elevation is the radial displacement
|
|
596
|
+
* above the base radius.
|
|
597
|
+
*
|
|
598
|
+
* Exposed only when the active surface uses the `cubeSphere` projection
|
|
599
|
+
* (otherwise `null` on the query context / runtime).
|
|
600
|
+
*/
|
|
601
|
+
interface TerrainSphereQuery {
|
|
602
|
+
readonly generation: number;
|
|
603
|
+
getElevationByDirection(direction: Vector3$1): number | null;
|
|
604
|
+
getElevationByPosition(position: Vector3$1): number | null;
|
|
605
|
+
getElevationByLatLong(latitudeDeg: number, longitudeDeg: number): number | null;
|
|
606
|
+
getNormalByDirection(direction: Vector3$1): Vector3$1 | null;
|
|
607
|
+
getNormalByPosition(position: Vector3$1): Vector3$1 | null;
|
|
608
|
+
getNormalByLatLong(latitudeDeg: number, longitudeDeg: number): Vector3$1 | null;
|
|
609
|
+
sampleTerrainByDirection(direction: Vector3$1): TerrainSurfaceSample;
|
|
610
|
+
sampleTerrainByPosition(position: Vector3$1): TerrainSurfaceSample;
|
|
611
|
+
sampleTerrainByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainSurfaceSample;
|
|
612
|
+
getTileByDirection(direction: Vector3$1): TerrainTile | null;
|
|
613
|
+
getTileByPosition(position: Vector3$1): TerrainTile | null;
|
|
614
|
+
getTileByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainTile | null;
|
|
615
|
+
getTileBoundsByDirection(direction: Vector3$1): TerrainTileBounds | null;
|
|
616
|
+
getTileBoundsByPosition(position: Vector3$1): TerrainTileBounds | null;
|
|
617
|
+
getTileBoundsByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainTileBounds | null;
|
|
618
|
+
/** Batch sample; `directions` is a Float32Array of xyz triples. */
|
|
619
|
+
sampleTerrainBatchByDirection(directions: Float32Array): TerrainSurfaceSampleBatch;
|
|
620
|
+
}
|
|
621
|
+
interface RaycastOptions {
|
|
622
|
+
maxSteps?: number;
|
|
623
|
+
refinementSteps?: number;
|
|
624
|
+
maxDistance?: number;
|
|
625
|
+
}
|
|
626
|
+
interface TerrainRaycastResult {
|
|
627
|
+
position: Vector3$1;
|
|
628
|
+
normal: Vector3$1;
|
|
629
|
+
distance: number;
|
|
630
|
+
}
|
|
631
|
+
interface TerrainRaycast {
|
|
632
|
+
pick(ray: Ray, options?: RaycastOptions): TerrainRaycastResult | null;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
type TerrainMeshParams = {
|
|
636
|
+
innerTileSegments: number;
|
|
637
|
+
maxNodes: number;
|
|
638
|
+
material: NodeMaterial;
|
|
639
|
+
/**
|
|
640
|
+
* Reverse tile triangle winding. Cube-sphere surfaces set this so the
|
|
641
|
+
* planet's outer shell is front-facing and renders with `FrontSide`.
|
|
642
|
+
*/
|
|
643
|
+
flipWinding: boolean;
|
|
644
|
+
};
|
|
645
|
+
declare class TerrainMesh extends InstancedMesh {
|
|
646
|
+
private _innerTileSegments;
|
|
647
|
+
private _maxNodes;
|
|
648
|
+
private _flipWinding;
|
|
649
|
+
terrainRaycast: TerrainRaycast | null;
|
|
650
|
+
constructor(params?: Partial<TerrainMeshParams>);
|
|
651
|
+
get innerTileSegments(): number;
|
|
652
|
+
set innerTileSegments(tileSegments: number);
|
|
653
|
+
get flipWinding(): boolean;
|
|
654
|
+
set flipWinding(flip: boolean);
|
|
655
|
+
get maxNodes(): number;
|
|
656
|
+
set maxNodes(maxNodes: number);
|
|
657
|
+
raycast(raycaster: Raycaster, intersects: Intersection[]): void;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
interface TileBoundsContext {
|
|
661
|
+
data: Float32Array<ArrayBuffer>;
|
|
662
|
+
attribute: StorageBufferAttribute;
|
|
663
|
+
node: StorageBufferNode;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
type ComputeStageCallback = (nodeIndex: Node, globalVertexIndex: Node, uv: Node, localCoordinates: Node, texelSize: Node) => void;
|
|
667
|
+
type ComputePipeline = ComputeStageCallback[];
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Default compile + execute tasks — uses terrainFieldStageTask as the leaf.
|
|
671
|
+
* Derived from the same factory as user pipelines to avoid duplicated logic.
|
|
672
|
+
*/
|
|
673
|
+
declare const compileComputeTask: _hello_terrain_work.Task<{
|
|
674
|
+
execute: (renderer: WebGPURenderer, instanceCount: number) => void;
|
|
675
|
+
}, string, unknown>;
|
|
676
|
+
declare const executeComputeTask: _hello_terrain_work.Task<any, string, {
|
|
677
|
+
renderer: WebGPURenderer;
|
|
678
|
+
}>;
|
|
679
|
+
/**
|
|
680
|
+
* Factory for user-extensible pipelines.
|
|
681
|
+
*
|
|
682
|
+
* Users who add custom compute stages create their own stage tasks using
|
|
683
|
+
* the accumulation pattern (`get()` predecessor, spread, append), then pass
|
|
684
|
+
* their leaf stage to this helper to get compile + execute tasks.
|
|
685
|
+
*
|
|
686
|
+
* @example
|
|
687
|
+
* ```ts
|
|
688
|
+
* const erosionStageTask = task((get, work) => {
|
|
689
|
+
* const upstream = get(elevationFieldStageTask);
|
|
690
|
+
* return work((): ComputePipeline => [
|
|
691
|
+
* ...upstream,
|
|
692
|
+
* (nodeIndex, globalVertexIndex, uv) => {
|
|
693
|
+
* // custom erosion logic
|
|
694
|
+
* },
|
|
695
|
+
* ]);
|
|
696
|
+
* });
|
|
548
697
|
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
698
|
+
* const { compile, execute } = createComputePipelineTasks(erosionStageTask);
|
|
699
|
+
* ```
|
|
551
700
|
*/
|
|
552
|
-
declare function
|
|
701
|
+
declare function createComputePipelineTasks(leafStageTask: TaskRef<ComputePipeline>): {
|
|
702
|
+
compile: _hello_terrain_work.Task<{
|
|
703
|
+
execute: (renderer: WebGPURenderer, instanceCount: number) => void;
|
|
704
|
+
}, string, unknown>;
|
|
705
|
+
execute: _hello_terrain_work.Task<any, string, {
|
|
706
|
+
renderer: WebGPURenderer;
|
|
707
|
+
}>;
|
|
708
|
+
};
|
|
553
709
|
|
|
554
|
-
declare function createTileCompute(leafStorage: LeafStorageState, uniforms: TerrainUniformsContext): {
|
|
710
|
+
declare function createTileCompute(leafStorage: LeafStorageState, uniforms: TerrainUniformsContext, projection?: TopologyProjection): {
|
|
555
711
|
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
712
|
+
tileFace: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
556
713
|
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
557
714
|
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
715
|
+
tileFaceUV: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node, number | Node]>;
|
|
558
716
|
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node, number | Node]>;
|
|
559
717
|
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node, number | Node]>;
|
|
560
718
|
};
|
|
@@ -567,6 +725,10 @@ type TerrainQueryConfig = {
|
|
|
567
725
|
innerTileSegments: number;
|
|
568
726
|
elevationScale: number;
|
|
569
727
|
maxLevel: number;
|
|
728
|
+
/** Topology projection; `cubeSphere` enables the direction/lat-long queries. */
|
|
729
|
+
projection: TopologyProjection;
|
|
730
|
+
/** Sphere radius in world units (cube-sphere projection only). */
|
|
731
|
+
radius: number;
|
|
570
732
|
};
|
|
571
733
|
interface CpuTerrainCache {
|
|
572
734
|
readonly generation: number;
|
|
@@ -580,11 +742,27 @@ interface CpuTerrainCache {
|
|
|
580
742
|
getGlobalElevationRange(): ElevationRange | null;
|
|
581
743
|
sampleTerrainBatch(positions: Float32Array): TerrainSampleBatch;
|
|
582
744
|
sampleTerrain(worldX: number, worldZ: number): TerrainSample;
|
|
745
|
+
getElevationByDirection(direction: Vector3$1): number | null;
|
|
746
|
+
getElevationByPosition(position: Vector3$1): number | null;
|
|
747
|
+
getElevationByLatLong(latitudeDeg: number, longitudeDeg: number): number | null;
|
|
748
|
+
getNormalByDirection(direction: Vector3$1): Vector3$1 | null;
|
|
749
|
+
getNormalByPosition(position: Vector3$1): Vector3$1 | null;
|
|
750
|
+
getNormalByLatLong(latitudeDeg: number, longitudeDeg: number): Vector3$1 | null;
|
|
751
|
+
sampleTerrainByDirection(direction: Vector3$1): TerrainSurfaceSample;
|
|
752
|
+
sampleTerrainByPosition(position: Vector3$1): TerrainSurfaceSample;
|
|
753
|
+
sampleTerrainByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainSurfaceSample;
|
|
754
|
+
getTileByDirection(direction: Vector3$1): TerrainTile | null;
|
|
755
|
+
getTileByPosition(position: Vector3$1): TerrainTile | null;
|
|
756
|
+
getTileByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainTile | null;
|
|
757
|
+
getTileBoundsByDirection(direction: Vector3$1): TerrainTileBounds | null;
|
|
758
|
+
getTileBoundsByPosition(position: Vector3$1): TerrainTileBounds | null;
|
|
759
|
+
getTileBoundsByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainTileBounds | null;
|
|
760
|
+
sampleTerrainBatchByDirection(directions: Float32Array): TerrainSurfaceSampleBatch;
|
|
583
761
|
}
|
|
584
762
|
|
|
585
763
|
interface QuadtreeConfigState {
|
|
586
764
|
state: QuadtreeState;
|
|
587
|
-
|
|
765
|
+
topology: Topology;
|
|
588
766
|
}
|
|
589
767
|
interface LeafGpuBufferState extends LeafStorageState {
|
|
590
768
|
count: number;
|
|
@@ -597,6 +775,8 @@ interface ElevationFieldContext {
|
|
|
597
775
|
interface TerrainQueryContext {
|
|
598
776
|
cache: CpuTerrainCache;
|
|
599
777
|
query: TerrainQuery;
|
|
778
|
+
/** Cube-sphere query; `null` unless the topology uses the cubeSphere projection. */
|
|
779
|
+
sphereQuery: TerrainSphereQuery | null;
|
|
600
780
|
shapeKey: string;
|
|
601
781
|
}
|
|
602
782
|
/** Task refs for the standard terrain pipeline. */
|
|
@@ -604,7 +784,7 @@ interface TerrainTasks {
|
|
|
604
784
|
instanceId: TaskRef<string>;
|
|
605
785
|
quadtreeConfig: TaskRef<QuadtreeConfigState>;
|
|
606
786
|
quadtreeUpdate: TaskRef<LeafSet>;
|
|
607
|
-
|
|
787
|
+
topology: TaskRef<Topology>;
|
|
608
788
|
leafStorage: TaskRef<LeafStorageState>;
|
|
609
789
|
leafGpuBuffer: TaskRef<LeafGpuBufferState>;
|
|
610
790
|
gpuSpatialIndexStorage: TaskRef<GpuSpatialIndexContext>;
|
|
@@ -641,8 +821,10 @@ declare const createElevationFieldContextTask: _hello_terrain_work.Task<{
|
|
|
641
821
|
}, string, unknown>;
|
|
642
822
|
declare const tileNodesTask: _hello_terrain_work.Task<{
|
|
643
823
|
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
824
|
+
tileFace: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
644
825
|
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
645
826
|
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
827
|
+
tileFaceUV: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
646
828
|
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
647
829
|
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
648
830
|
}, string, unknown>;
|
|
@@ -689,22 +871,24 @@ declare const origin: _hello_terrain_work.ParamRef<{
|
|
|
689
871
|
z: number;
|
|
690
872
|
}>;
|
|
691
873
|
/**
|
|
692
|
-
*
|
|
693
|
-
*
|
|
874
|
+
* Default number of segments per inner tile edge. The effective edge vertex
|
|
875
|
+
* count is `innerTileSegments + 3`
|
|
694
876
|
*/
|
|
695
877
|
declare const innerTileSegments: _hello_terrain_work.ParamRef<number>;
|
|
696
878
|
/** Skirt scale factor. */
|
|
697
879
|
declare const skirtScale: _hello_terrain_work.ParamRef<number>;
|
|
698
880
|
/** Elevation vertical scale. */
|
|
699
881
|
declare const elevationScale: _hello_terrain_work.ParamRef<number>;
|
|
882
|
+
/** Sphere radius in world units (cube-sphere projection only). */
|
|
883
|
+
declare const radius: _hello_terrain_work.ParamRef<number>;
|
|
700
884
|
/** Maximum quadtree nodes. */
|
|
701
885
|
declare const maxNodes: _hello_terrain_work.ParamRef<number>;
|
|
702
886
|
/** Maximum quadtree subdivision level. */
|
|
703
887
|
declare const maxLevel: _hello_terrain_work.ParamRef<number>;
|
|
704
888
|
/** Quadtree update configuration (camera, mode, etc.). */
|
|
705
889
|
declare const quadtreeUpdate: _hello_terrain_work.ParamRef<UpdateParams>;
|
|
706
|
-
/** Optional custom terrain
|
|
707
|
-
declare const
|
|
890
|
+
/** Optional custom terrain topology; defaults to bounded flat topology when null. */
|
|
891
|
+
declare const topology: _hello_terrain_work.ParamRef<Topology | null>;
|
|
708
892
|
/** Terrain field texture filter mode. */
|
|
709
893
|
declare const terrainFieldFilter: _hello_terrain_work.ParamRef<"nearest" | "linear">;
|
|
710
894
|
/** Terrain elevation control function (per vertex, in gpu compute) */
|
|
@@ -727,11 +911,11 @@ declare const elevationFn: _hello_terrain_work.ParamRef<ElevationCallback>;
|
|
|
727
911
|
declare const positionNodeTask: _hello_terrain_work.Task<three_src_nodes_TSL_js.ShaderCallNodeInternal, string, unknown>;
|
|
728
912
|
|
|
729
913
|
/**
|
|
730
|
-
* Derives the terrain
|
|
914
|
+
* Derives the terrain topology from `rootSize` and `origin`.
|
|
731
915
|
* Automatically recomputes when either param changes, keeping the
|
|
732
916
|
* quadtree refinement in sync with the GPU-side tile positioning.
|
|
733
917
|
*/
|
|
734
|
-
declare const
|
|
918
|
+
declare const topologyTask: _hello_terrain_work.Task<Topology, string, unknown>;
|
|
735
919
|
declare const quadtreeConfigTask: _hello_terrain_work.Task<QuadtreeConfigState, string, unknown>;
|
|
736
920
|
declare const quadtreeUpdateTask: _hello_terrain_work.Task<LeafSet, string, unknown>;
|
|
737
921
|
/**
|
|
@@ -763,14 +947,13 @@ declare const createUniformsTask: _hello_terrain_work.Task<TerrainUniformsContex
|
|
|
763
947
|
*/
|
|
764
948
|
declare const updateUniformsTask: _hello_terrain_work.Task<TerrainUniformsContext, string, unknown>;
|
|
765
949
|
|
|
766
|
-
declare function terrainGraph(): TerrainGraph;
|
|
767
950
|
/** All terrain task refs for direct access. */
|
|
768
951
|
declare const terrainTasks: {
|
|
769
952
|
readonly instanceId: _hello_terrain_work.Task<`${string}-${string}-${string}-${string}-${string}`, string, unknown>;
|
|
770
953
|
readonly quadtreeConfig: _hello_terrain_work.Task<QuadtreeConfigState, string, unknown>;
|
|
771
954
|
readonly quadtreeUpdate: _hello_terrain_work.Task<LeafSet, string, unknown>;
|
|
772
955
|
readonly leafStorage: _hello_terrain_work.Task<LeafStorageState, string, unknown>;
|
|
773
|
-
readonly
|
|
956
|
+
readonly topology: _hello_terrain_work.Task<Topology, string, unknown>;
|
|
774
957
|
readonly leafGpuBuffer: _hello_terrain_work.Task<{
|
|
775
958
|
count: number;
|
|
776
959
|
data: Int32Array<ArrayBuffer>;
|
|
@@ -789,8 +972,10 @@ declare const terrainTasks: {
|
|
|
789
972
|
}, string, unknown>;
|
|
790
973
|
readonly createTileNodes: _hello_terrain_work.Task<{
|
|
791
974
|
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
975
|
+
tileFace: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
792
976
|
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
793
977
|
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
978
|
+
tileFaceUV: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
794
979
|
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
795
980
|
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
796
981
|
}, string, unknown>;
|
|
@@ -818,6 +1003,7 @@ declare const terrainTasks: {
|
|
|
818
1003
|
}>;
|
|
819
1004
|
readonly terrainRaycast: _hello_terrain_work.Task<TerrainRaycast, string, unknown>;
|
|
820
1005
|
};
|
|
1006
|
+
declare function terrainGraph(): TerrainGraph;
|
|
821
1007
|
|
|
822
1008
|
type ComputeDeviceLimits = {
|
|
823
1009
|
maxWorkgroupSizeX: number;
|
|
@@ -828,7 +1014,10 @@ declare function getDeviceComputeLimits(renderer: WebGPURenderer): ComputeDevice
|
|
|
828
1014
|
|
|
829
1015
|
declare function createTerrainSampler(params: CreateTerrainSamplerParams): TerrainSampler;
|
|
830
1016
|
|
|
1017
|
+
/** Flat (heightfield) query, keyed on world XZ. */
|
|
831
1018
|
declare function createTerrainQuery(cache: CpuTerrainCache): TerrainQuery;
|
|
1019
|
+
/** Cube-sphere query, keyed on a direction / position / lat-long. */
|
|
1020
|
+
declare function createTerrainSphereQuery(cache: CpuTerrainCache): TerrainSphereQuery;
|
|
832
1021
|
|
|
833
1022
|
type CpuRaycastConfig = {
|
|
834
1023
|
rootSize: number;
|
|
@@ -836,14 +1025,68 @@ type CpuRaycastConfig = {
|
|
|
836
1025
|
originZ: number;
|
|
837
1026
|
minY: number;
|
|
838
1027
|
maxY: number;
|
|
1028
|
+
/** Topology projection; `cubeSphere` selects the radial sphere raycast. */
|
|
1029
|
+
projection?: TopologyProjection;
|
|
1030
|
+
/** Planet center (cube-sphere only). */
|
|
1031
|
+
centerX?: number;
|
|
1032
|
+
centerY?: number;
|
|
1033
|
+
centerZ?: number;
|
|
1034
|
+
/** Base sphere radius (cube-sphere only). */
|
|
1035
|
+
radius?: number;
|
|
1036
|
+
/** Inner/outer radial bounds of the terrain shell (cube-sphere only). */
|
|
1037
|
+
minRadius?: number;
|
|
1038
|
+
maxRadius?: number;
|
|
839
1039
|
};
|
|
840
1040
|
|
|
841
1041
|
type TerrainRaycastConfig = CpuRaycastConfig;
|
|
842
1042
|
declare function createTerrainRaycast(params: {
|
|
843
1043
|
getTerrainQuery: () => TerrainQuery | null;
|
|
1044
|
+
getSphereQuery: () => TerrainSphereQuery | null;
|
|
844
1045
|
getConfig: () => TerrainRaycastConfig;
|
|
845
1046
|
}): TerrainRaycast;
|
|
846
1047
|
|
|
1048
|
+
type CubeFaceBasis = {
|
|
1049
|
+
forward: Node;
|
|
1050
|
+
right: Node;
|
|
1051
|
+
up: Node;
|
|
1052
|
+
};
|
|
1053
|
+
/** Per-face basis vectors selected by the dynamic face index. */
|
|
1054
|
+
declare function cubeFaceBasis(face: Node): CubeFaceBasis;
|
|
1055
|
+
/**
|
|
1056
|
+
* Cube-space point for face-local (u, v) in [0, 1]:
|
|
1057
|
+
* cube = forward + (2u-1) * right + (2v-1) * up
|
|
1058
|
+
*/
|
|
1059
|
+
declare function cubeFacePoint(basis: CubeFaceBasis, u: Node, v: Node): Node;
|
|
1060
|
+
/** Unit-sphere direction for face-local (u, v). */
|
|
1061
|
+
declare function cubeFaceDirection(basis: CubeFaceBasis, u: Node, v: Node): Node;
|
|
1062
|
+
/**
|
|
1063
|
+
* Project a basis axis onto the tangent plane at `dir` and normalize.
|
|
1064
|
+
* Used to build the sphere tangent frame for normal reconstruction.
|
|
1065
|
+
*/
|
|
1066
|
+
declare function tangentFromAxis(dir: Node, axis: Node): Node;
|
|
1067
|
+
/**
|
|
1068
|
+
* Reconstruct a unit tangent-space normal from its packed horizontal
|
|
1069
|
+
* components: `ny = sqrt(max(0, 1 - nx² - nz²))`.
|
|
1070
|
+
*/
|
|
1071
|
+
declare function unpackTangentNormal(nx: Node, nz: Node): Node;
|
|
1072
|
+
/**
|
|
1073
|
+
* Rotate a tangent-space normal into the sphere tangent frame
|
|
1074
|
+
* `(tu, dir, tv)` at `dir` and normalize.
|
|
1075
|
+
*
|
|
1076
|
+
* Mirrors: the CPU `computeSphereNormal` in `query/cpu-terrain-cache.ts`.
|
|
1077
|
+
*/
|
|
1078
|
+
declare function sphereTangentFrameNormal(dir: Node, basis: CubeFaceBasis, tangentNormal: Node): Node;
|
|
1079
|
+
/**
|
|
1080
|
+
* Pick the cube face index (0..5) whose normal axis dominates `dir`.
|
|
1081
|
+
* GPU mirror of `directionToFace` in `quadtree/topology/cubeSphereInverse.ts`.
|
|
1082
|
+
*/
|
|
1083
|
+
declare function cubeFaceFromDirection(dir: Node): Node;
|
|
1084
|
+
/**
|
|
1085
|
+
* Face-local (u, v) in [0, 1] for a direction known to fall on `face`.
|
|
1086
|
+
* GPU mirror of `directionToFaceUV` in `quadtree/topology/cubeSphereInverse.ts`.
|
|
1087
|
+
*/
|
|
1088
|
+
declare function cubeFaceUVFromDirection(basis: CubeFaceBasis, dir: Node): Node;
|
|
1089
|
+
|
|
847
1090
|
/**
|
|
848
1091
|
* Maps a value or node from texture space [0, 1] to vector space [-1, 1].
|
|
849
1092
|
*
|
|
@@ -916,5 +1159,5 @@ declare const voronoiCells: three_src_nodes_TSL_js.ShaderNodeFn<[three_tsl.Proxi
|
|
|
916
1159
|
uv: Node;
|
|
917
1160
|
}>]>;
|
|
918
1161
|
|
|
919
|
-
export { ArrayTextureBackend, AtlasBackend, Dir, TerrainGeometry, TerrainMesh,
|
|
920
|
-
export type { ComputePipeline, ComputeStageCallback, CreateTerrainSamplerParams,
|
|
1162
|
+
export { ArrayTextureBackend, AtlasBackend, CUBE_FACES, CUBE_FACE_COUNT, Dir, TerrainGeometry, TerrainMesh, U32_EMPTY, allocLeafSet, allocSeamTable, beginUpdate, blendAngleCorrectedNormals, buildLeafIndex, buildSeams2to1, compileComputeTask, createComputePipelineTasks, createCubeSphereTopology, createElevationFieldContextTask, createFlatTopology, createInfiniteFlatTopology, createSpatialIndex, createState, createTerrainFieldStorage, createTerrainFieldTextureTask, createTerrainQuery, createTerrainRaycast, createTerrainSampler, createTerrainSamplerTask, createTerrainSphereQuery, createTerrainUniforms, createUniformsTask, cubeFaceBasis, cubeFaceDirection, cubeFaceFromDirection, cubeFacePoint, cubeFaceUVFromDirection, deriveNormalZ, directionToFace, directionToFaceUV, directionToLatLong, elevationFieldStageTask, elevationFn, elevationScale, executeComputeTask, faceUVToCube, getDeviceComputeLimits, gpuSpatialIndexStorageTask, gpuSpatialIndexUploadTask, innerTileSegments, instanceIdTask, isSkirtUV, isSkirtVertex, latLongToDirection, leafGpuBufferTask, leafStorageTask, loadTerrainField, loadTerrainFieldElevation, loadTerrainFieldNormal, maxLevel, maxNodes, origin, packTerrainFieldSample, positionNodeTask, quadtreeConfigTask, quadtreeUpdate, quadtreeUpdateTask, radius, resetLeafSet, resetSeamTable, rootSize, sampleTerrainField, sampleTerrainFieldElevation, skirtScale, sphereTangentFrameNormal, storeTerrainField, tangentFromAxis, terrainFieldFilter, terrainFieldStageTask, terrainGraph, terrainQueryTask, terrainRaycastTask, terrainReadbackTask, terrainTasks, textureSpaceToVectorSpace, tileNodesTask, topology, topologyTask, unpackTangentNormal, update, updateUniformsTask, vElevation, vGlobalVertexIndex, vectorSpaceToTextureSpace, voronoiCells };
|
|
1163
|
+
export type { ComputePipeline, ComputeStageCallback, CreateTerrainSamplerParams, CubeFace, CubeFaceBasis, CubeSphereTopologyConfig, ElevationCallback, ElevationFieldContext, ElevationParams, ElevationRange, FlatTopologyConfig, GpuSpatialIndexContext, InfiniteFlatTopologyConfig, IntNodeInput, LeafGpuBufferState, LeafSet, LeafStorageState, LodMode, QuadtreeConfig, QuadtreeConfigState, QuadtreeState, RaycastOptions, SeamTable, SpatialIndex, TerrainFieldStorage, TerrainFieldStorageBackendType, TerrainFieldStorageFormat, TerrainFieldStorageOptions, TerrainGraph, TerrainQuery, TerrainQueryContext, TerrainRaycast, TerrainRaycastConfig, TerrainRaycastResult, TerrainSample, TerrainSampleBatch, TerrainSampler, TerrainSphereQuery, TerrainSurfaceSample, TerrainSurfaceSampleBatch, TerrainTasks, TerrainTile, TerrainTileBounds, TerrainUniformsContext, TerrainUniformsParams, TileBounds, TileId, Topology, TopologyProjection, UpdateParams, Vec3, Vec3Mutable };
|