@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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # @hello-terrain/three
2
- Realtime web terrain engine, for vast virtual worlds. Built for [three.js](https://threejs.org/).
2
+
3
+ Realtime web terrain engine for vast virtual worlds. Built for [three.js](https://threejs.org/) WebGPU.
4
+
3
5
  ## Features
4
6
 
5
7
  - Performant variable LOD system for huge (earth-scale!) open worlds
@@ -7,36 +9,190 @@ Realtime web terrain engine, for vast virtual worlds. Built for [three.js](https
7
9
  - TSL-based elevation and texture assignment nodes
8
10
  - Composable compute stage plugins
9
11
 
10
- ## Getting Started
12
+ ## Quick Start
13
+
14
+ ### React Three Fiber
15
+
16
+ ```jsx
17
+ import { useRef, useMemo, useEffect } from "react";
18
+ import { Canvas, extend, useFrame, useThree } from "@react-three/fiber";
19
+ import { OrbitControls } from "@react-three/drei";
20
+ import * as THREE from "three/webgpu";
21
+ import { float, Fn, vec2 } from "three/tsl";
22
+ import {
23
+ terrainGraph,
24
+ TerrainGeometry,
25
+ TerrainMesh,
26
+ innerTileSegments,
27
+ elevationScale,
28
+ elevationFn,
29
+ quadtreeUpdate,
30
+ quadtreeUpdateTask,
31
+ positionNodeTask,
32
+ voronoiCells,
33
+ } from "@hello-terrain/three";
34
+ import { task } from "@hello-terrain/work";
35
+
36
+ extend(THREE);
37
+ extend({ TerrainGeometry, TerrainMesh });
38
+
39
+ function Terrain({ graph }) {
40
+ const meshRef = useRef(null);
41
+ const materialRef = useRef(null);
42
+
43
+ // Define the elevation function (runs on the GPU)
44
+ useEffect(() => {
45
+ graph.set(elevationFn, () => ({ worldPosition }) => {
46
+ return voronoiCells({
47
+ scale: float(1),
48
+ facet: 0,
49
+ seed: 0,
50
+ uv: vec2(worldPosition.x, worldPosition.z).mul(0.5),
51
+ }).mul(0.5);
52
+ });
53
+ graph.set(elevationScale, () => 10);
54
+ }, [graph]);
55
+
56
+ // Apply position node to the material when graph produces it
57
+ useEffect(() => {
58
+ graph.add(
59
+ task((get, work) => {
60
+ const positionNode = get(positionNodeTask);
61
+ const leafSet = get(quadtreeUpdateTask);
62
+ return work(() => {
63
+ const mesh = meshRef.current;
64
+ const material = materialRef.current;
65
+ if (mesh && leafSet?.count !== undefined) mesh.count = leafSet.count;
66
+ if (material && positionNode) {
67
+ material.positionNode = positionNode;
68
+ material.needsUpdate = true;
69
+ }
70
+ });
71
+ }).displayName("applyPositionNodeTask"),
72
+ );
73
+ }, [graph]);
74
+
75
+ // Update camera and run the graph each frame
76
+ useFrame(async ({ camera, gl }) => {
77
+ graph.set(quadtreeUpdate, (prev) => {
78
+ prev.cameraOrigin.x = camera.position.x;
79
+ prev.cameraOrigin.y = camera.position.y;
80
+ prev.cameraOrigin.z = camera.position.z;
81
+ return prev;
82
+ });
83
+ await graph.run({ resources: { renderer: gl } });
84
+ });
85
+
86
+ return (
87
+ <terrainMesh ref={meshRef} innerTileSegments={innerTileSegments.get()} maxNodes={1024}>
88
+ <meshStandardNodeMaterial ref={materialRef} />
89
+ </terrainMesh>
90
+ );
91
+ }
92
+
93
+ export default function App() {
94
+ const graph = useMemo(() => terrainGraph(), []);
95
+ return (
96
+ <Canvas
97
+ gl={async (props) => {
98
+ const renderer = new THREE.WebGPURenderer({ ...props, antialias: true });
99
+ await renderer.init();
100
+ return renderer;
101
+ }}
102
+ camera={{ position: [0, 30, 60] }}
103
+ >
104
+ <ambientLight intensity={0.5} />
105
+ <directionalLight position={[1, 1, 1]} />
106
+ <Terrain graph={graph} />
107
+ <OrbitControls />
108
+ </Canvas>
109
+ );
110
+ }
111
+ ```
11
112
 
12
- 1. Read the [Introduction](http://hello-terrain.kenny.wtf/docs) to understand the architecture and see how it's used.
113
+ ### Vanilla Three.js
13
114
 
14
- 2. Read the [Installation](http://hello-terrain.kenny.wtf/docs/installation) instructions.
115
+ ```js
116
+ import * as THREE from "three/webgpu";
117
+ import { float, vec2 } from "three/tsl";
118
+ import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
119
+ import {
120
+ terrainGraph,
121
+ TerrainMesh,
122
+ innerTileSegments,
123
+ elevationScale,
124
+ elevationFn,
125
+ quadtreeUpdate,
126
+ quadtreeUpdateTask,
127
+ positionNodeTask,
128
+ voronoiCells,
129
+ } from "@hello-terrain/three";
130
+ import { task } from "@hello-terrain/work";
15
131
 
16
- 3. Review the [Examples](http://hello-terrain.kenny.wtf/examples) to get an idea of how to do things.
132
+ // Renderer
133
+ const renderer = new THREE.WebGPURenderer({ antialias: true });
134
+ renderer.setSize(window.innerWidth, window.innerHeight);
135
+ document.body.appendChild(renderer.domElement);
136
+ await renderer.init();
17
137
 
18
- 4. For support, join the [Discord server](https://discord.gg/HgTd2B828n).
138
+ // Scene & camera
139
+ const scene = new THREE.Scene();
140
+ const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100000);
141
+ camera.position.set(0, 30, 60);
142
+ const controls = new OrbitControls(camera, renderer.domElement);
19
143
 
20
- ## Project Architecture
21
- This library uses [unbuild](https://github.com/unjs/unbuild) for building.
22
- - `src/index.ts` is the main entry point for your library exports
23
- - Add your library code in the `src` folder
24
- - `tests/` contains your test files
144
+ // Terrain
145
+ const material = new THREE.MeshStandardNodeMaterial();
146
+ const mesh = new TerrainMesh({ innerTileSegments: innerTileSegments.get(), maxNodes: 1024, material });
147
+ scene.add(mesh);
148
+ scene.add(new THREE.AmbientLight(0xffffff, 0.5));
149
+ scene.add(new THREE.DirectionalLight(0xffffff, 1));
25
150
 
151
+ // Task graph
152
+ const graph = terrainGraph();
26
153
 
27
- ## Libraries
28
- The following libraries are used - checkout the linked docs to learn more
29
- - [unbuild](https://github.com/unjs/unbuild) - Unified JavaScript build system
154
+ graph.set(elevationFn, () => ({ worldPosition }) => {
155
+ return voronoiCells({
156
+ scale: float(1),
157
+ facet: 0,
158
+ seed: 0,
159
+ uv: vec2(worldPosition.x, worldPosition.z).mul(0.5),
160
+ }).mul(0.5);
161
+ });
162
+ graph.set(elevationScale, () => 10);
30
163
 
164
+ // Apply graph outputs to the mesh
165
+ graph.add(
166
+ task((get, work) => {
167
+ const positionNode = get(positionNodeTask);
168
+ const leafSet = get(quadtreeUpdateTask);
169
+ return work(() => {
170
+ if (leafSet?.count !== undefined) mesh.count = leafSet.count;
171
+ if (positionNode) {
172
+ material.positionNode = positionNode;
173
+ material.needsUpdate = true;
174
+ }
175
+ });
176
+ }).displayName("applyPositionNodeTask"),
177
+ );
31
178
 
32
- ## Tools
33
- - [Vitest](https://vitest.dev/) - Fast unit test framework powered by Vite
34
- - [Oxlint](https://oxc.rs/docs/guide/usage/linter) - A fast linter for JavaScript and TypeScript
35
- - [Oxfmt](https://oxc.rs/docs/guide/usage/formatter) - Fast Prettier-compatible code formatter
179
+ // Render loop
180
+ renderer.setAnimationLoop(async () => {
181
+ controls.update();
182
+ graph.set(quadtreeUpdate, (prev) => {
183
+ prev.cameraOrigin.x = camera.position.x;
184
+ prev.cameraOrigin.y = camera.position.y;
185
+ prev.cameraOrigin.z = camera.position.z;
186
+ return prev;
187
+ });
188
+ await graph.run({ resources: { renderer } });
189
+ renderer.render(scene, camera);
190
+ });
191
+ ```
36
192
 
193
+ ## Documentation
37
194
 
38
- ## Development Commands
39
- - `pnpm install` to install the dependencies
40
- - `pnpm run build` to build the library into the `dist` folder
41
- - `pnpm run test` to run the tests
42
- - `pnpm run release` to build and publish to npm
195
+ 1. Read the [Introduction](http://hello-terrain.kenny.wtf/docs) to understand the architecture.
196
+ 2. Read the [Installation](http://hello-terrain.kenny.wtf/docs/installation) guide.
197
+ 3. Browse the [Examples](http://hello-terrain.kenny.wtf/examples).
198
+ 4. Join the [Discord](https://discord.gg/HgTd2B828n) for support.