three-virtual-geometry 0.0.0-stage → 0.1.0

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/AGENTS.md ADDED
@@ -0,0 +1,65 @@
1
+ # AGENTS.md
2
+
3
+ Guidance for AI coding agents working on this repository. To **use** the library in another project, read
4
+ [docs/public/llms.txt](docs/public/llms.txt) instead.
5
+
6
+ ## What this is
7
+
8
+ three-virtual-geometry: virtual geometry (a cluster LOD hierarchy with GPU-driven selection and culling) for
9
+ three.js WebGPU, written in TypeScript with TSL compute shaders. An independent implementation, not affiliated with
10
+ Epic Games. Do not copy code from, or describe this as derived from, any proprietary engine.
11
+
12
+ ## Commands
13
+
14
+ ```bash
15
+ npm install
16
+ npm run dev # demo at http://localhost:8090 (?scene=ruins|map|world|import|stress|test)
17
+ npm test # vitest: DAG invariants, partitioner, serialization, import grouping (Node, no GPU)
18
+ npm run typecheck # tsc --noEmit
19
+ npm run build # library (dist/index.js + .d.ts) and the vg-bake CLI (dist/bake.mjs)
20
+ npm run build:demo # demo into dist-demo/
21
+ npm run docs:dev # VitePress docs site; the embedded demo player (/live) loads the demo from `npm run dev`
22
+ npm run bench # uncapped FPS of every demo scene in Chrome (Playwright) -> docs/benchmarks.json
23
+ ```
24
+
25
+ GPU code can only be checked in a WebGPU browser. After runtime changes, load the demo scenes and check the console
26
+ for WebGPU validation errors and the HUD for `overflow`.
27
+
28
+ ## Layout
29
+
30
+ | Path | Role |
31
+ | --- | --- |
32
+ | `src/index.ts` | Public API. Everything users import is re-exported here. |
33
+ | `src/source.ts` | `fromBufferGeometry`, `mergeSources`: three.js geometry to a welded `VirtualMeshSource`. |
34
+ | `src/core/preprocess/buildVirtualMesh.ts` | Builds the cluster DAG (meshoptimizer clusterize and simplify, with locked borders). |
35
+ | `src/core/preprocess/partition.ts` | Groups meshlets by shared edges. |
36
+ | `src/core/preprocess/voxelProxy.ts` | Voxel proxy surfaces for coarse levels of aggregate geometry. |
37
+ | `src/core/io/serialize.ts` | `.vgeo` binary format. |
38
+ | `src/core/io/cache.ts` | IndexedDB build cache. Bump `VG_BUILD_VERSION` when build output changes. |
39
+ | `src/core/runtime/VirtualGeometry.ts` | Context: settings, pools, per-frame update, stats, threshold controller. |
40
+ | `src/core/runtime/GeometryPool.ts` | Shared buffers for many meshes and the compute passes (cells, instances, meshlets, prefix, expand). |
41
+ | `src/core/runtime/VirtualMesh.ts` | A three.js `Mesh` that draws its region of a pool with an indirect draw. |
42
+ | `src/core/runtime/OcclusionCulling.ts` | Depth pre-pass, hierarchical depth buffer, automatic on/off tuning. |
43
+ | `src/core/runtime/vgMaterial.ts` | `vgUv`, `vgTexture` and material rewiring. |
44
+ | `src/core/runtime/cut.ts` | CPU reference of the GPU selection, used by tests. |
45
+ | `src/core/import/` | `vg.add()`: grouping an `Object3D` into instanced meshes, material conversion. |
46
+ | `scripts/bake.ts` | The `vg-bake` CLI. |
47
+ | `examples/` | Demo app (Vite root). Scenes are generated procedurally in `examples/demo/`. |
48
+ | `docs/` | VitePress site, deployed with the demo to GitHub Pages. |
49
+
50
+ ## Invariants
51
+
52
+ - A meshlet is drawn when `projectedError <= threshold < projectedParentError`. Errors must grow monotonically up
53
+ the DAG; `tests/preprocess.test.ts` checks it. Breaking it causes holes or overlaps.
54
+ - Meshlets have at most 128 triangles (`MAX_MESHLET_TRIANGLES`); the draw index encodes `slot << 7 | local`.
55
+ - Storage-buffer bindings must stay under 128 MB: pools cap their buffers by `maxPoolBytes`.
56
+ - In compute shaders, `workgroupBarrier()` must be reached in uniform control flow: no early return before it.
57
+ - If the build output changes, bump `VG_BUILD_VERSION` and update the fingerprint in `tests/buildversion.test.ts`.
58
+
59
+ ## Conventions
60
+
61
+ - TypeScript, 2-space indentation, single quotes. Keep the public API small and stable, and document new options in
62
+ `docs/` and `llms.txt`.
63
+ - The engine decides how to render, never what: new optimizations must be automatic with an opt-out setting, not
64
+ something users must call.
65
+ - Use three.js and meshoptimizer for what they already do instead of reimplementing it.
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Elad Ben-Haim
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ Portions of this software are derived from nanite-webgpu; see THIRD_PARTY_NOTICES.md.
package/README.md CHANGED
@@ -1,3 +1,166 @@
1
- # Temporary Holding Version
1
+ # three-virtual-geometry
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **Virtual geometry for three.js WebGPU.** Put in your models at full detail. The engine draws only the triangles
4
+ you can see: about one per pixel, wherever you are.
5
+
6
+ [**Live demo**](https://elad12390.github.io/three-virtual-geometry/live) ·
7
+ [**Docs**](https://elad12390.github.io/three-virtual-geometry/) ·
8
+ [API](https://elad12390.github.io/three-virtual-geometry/api) ·
9
+ [Use it from a CDN](#use-it-from-a-cdn-no-build-step) ·
10
+ [Set it up with your AI agent](#set-it-up-with-your-ai-agent)
11
+
12
+ **Measured results** (uncapped, no vsync, shadows on; MacBook Pro with an M4 Pro, Chrome 154):
13
+
14
+ - **5.7 billion triangles** in the ruins scene at **160 to 230 FPS** at 1080p, and 103 to 158 FPS at 4K.
15
+ - **37.5 billion triangles in 3 million instances** (a 6 km world) at **147 to 150 FPS** at 1080p.
16
+ - **1 million instances** (39.5 billion triangles) at **177 FPS** or more at 1080p.
17
+ - **Over 100 FPS in every scene and camera view, even at 4K**, with at most 0.6 ms of CPU time per frame.
18
+
19
+ ![An ancient city of 5.7 billion triangles drawn with about 8 million](docs/public/screenshots/ruins-wide.jpg)
20
+
21
+ | | |
22
+ | --- | --- |
23
+ | ![Close-up: every brick and carving is real geometry](docs/public/screenshots/ruins-closeup.jpg) | ![Clusters colored by detail level](docs/public/screenshots/world-meshlets.jpg) |
24
+ | ![3 million instances over 6 km](docs/public/screenshots/world.jpg) | ![Textured glTF models converted with one call](docs/public/screenshots/import.jpg) |
25
+
26
+ - **One line to adopt.** `await vg.add(gltf.scene)` converts every static mesh, with its materials and textures.
27
+ - **Billions of triangles.** The ruins scene holds 5.7 billion and draws 7 to 9 million a frame, at 160 to 230 FPS
28
+ at 1080p on a MacBook Pro (M4 Pro).
29
+ - **No visible LOD switching.** Detail changes cluster by cluster, below one pixel of error. No hand-made LODs.
30
+ - **GPU-driven.** Frustum, size and occlusion culling and level selection run in compute shaders. One draw call
31
+ per mesh, millions of instances.
32
+ - **Everything three.js.** Node materials, lights, shadows, fog and tone mapping work unchanged.
33
+
34
+ ## Benchmarks
35
+
36
+ Uncapped frame rates (no vsync) on a MacBook Pro with an M4 Pro, Chrome 154, 1 px error threshold, shadows on.
37
+ Ranges span several camera views per scene. [Details and how to run them](https://elad12390.github.io/three-virtual-geometry/guide/performance#benchmarks):
38
+ `npm run bench`.
39
+
40
+ | Scene | Full-detail triangles | Instances | Drawn per frame | FPS at 1080p | FPS at 4K |
41
+ | --- | --- | --- | --- | --- | --- |
42
+ | Ruins | 5.7B | 113k | 6.5M – 9.0M | 160 – 230 | 103 – 158 |
43
+ | World (6 km) | 37.5B | 3.0M | 8.3M – 9.1M | 147 – 150 | 101 – 120 |
44
+ | Valley (2 km) | 1.1B | 152k | 3.1M – 8.6M | 159 – 329 | 109 – 203 |
45
+ | glTF import | 5.1M | 12k | 0.5M – 0.6M | 941 – 964 | 468 – 516 |
46
+ | Stress, 1M instances | 39.5B | 1.0M | 0.6M – 8.4M | 177 – 1,404 | 154 – 696 |
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ npm install three-virtual-geometry three
52
+ ```
53
+
54
+ Needs three.js r180+ and a browser with WebGPU (Chrome or Edge 113+, Safari 26+, Firefox 141+ on Windows).
55
+
56
+ ### Use it from a CDN (no build step)
57
+
58
+ No npm needed: one import in a plain HTML file. The all-in-one build includes three.js, `GLTFLoader`,
59
+ `OrbitControls` and `RoomEnvironment`:
60
+
61
+ ```html
62
+ <script type="module">
63
+ import { THREE, VirtualGeometry, GLTFLoader } from
64
+ 'https://cdn.jsdelivr.net/npm/three-virtual-geometry@0.1/dist/three-virtual-geometry.all.min.js';
65
+ // ... same code as below, with THREE from this import
66
+ </script>
67
+ ```
68
+
69
+ Already using three.js on the page? The minimal build (`dist/three-virtual-geometry.min.js`) leaves three.js out and
70
+ uses yours through an import map. The [CDN guide](https://elad12390.github.io/three-virtual-geometry/guide/cdn)
71
+ has complete pages for both, every line explained.
72
+
73
+ ## Use it
74
+
75
+ ```ts
76
+ import * as THREE from 'three/webgpu';
77
+ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
78
+ import { VirtualGeometry } from 'three-virtual-geometry';
79
+
80
+ const renderer = new THREE.WebGPURenderer({ antialias: true });
81
+ await renderer.init();
82
+
83
+ const vg = new VirtualGeometry();
84
+ const gltf = await new GLTFLoader().loadAsync('level.glb');
85
+ await vg.add(gltf.scene); // every static mesh becomes virtual geometry, in place
86
+ scene.add(gltf.scene);
87
+
88
+ renderer.setAnimationLoop(() => renderer.render(scene, camera)); // render as usual
89
+ ```
90
+
91
+ That's the whole integration. Repeated props are instanced automatically, builds are cached in the browser, and
92
+ level of detail and culling run before every render. Everything else is an optional lever:
93
+
94
+ ```ts
95
+ vg.errorThreshold.value = 1.5; // coarser and faster (pixels of error, default 1)
96
+ vg.triangleBudget = 6_000_000; // or adapt detail to a budget (off by default)
97
+ grass.maxDrawDistance = 400; // per mesh: stop drawing small clutter far away
98
+ ```
99
+
100
+ Geometry made in code works too:
101
+
102
+ ```ts
103
+ const data = await buildVirtualMeshCached(fromBufferGeometry(geometry));
104
+ scene.add(vg.createMesh(data, material, { matrices })); // 16 floats per instance
105
+ ```
106
+
107
+ See the [guide](https://elad12390.github.io/three-virtual-geometry/guide/getting-started) for importing,
108
+ instancing, settings, baking `.vgeo` files with `npx vg-bake`, and performance tips.
109
+
110
+ ## Set it up with your AI agent
111
+
112
+ Paste this into Claude Code, Cursor, Copilot or any coding agent, in your project:
113
+
114
+ ```text
115
+ Add three-virtual-geometry (https://github.com/elad12390/three-virtual-geometry) to this project so that every
116
+ static mesh is rendered as virtual geometry. Read https://elad12390.github.io/three-virtual-geometry/llms.txt first.
117
+ Install it, make sure the renderer is THREE.WebGPURenderer from 'three/webgpu' (await renderer.init()), create one
118
+ VirtualGeometry, and call await vg.add(model) for each loaded model before adding it to the scene. Keep the render
119
+ loop, materials, lights and shadows as they are. Run the app and confirm there are no console errors.
120
+ ```
121
+
122
+ [More on agent setup](https://elad12390.github.io/three-virtual-geometry/guide/ai-agents) · [llms.txt](docs/public/llms.txt)
123
+ · [AGENTS.md](AGENTS.md) (for agents working on this repository).
124
+
125
+ ## How it works
126
+
127
+ Each mesh is split into clusters of up to 128 triangles, which are grouped, simplified with locked borders, and
128
+ split again, level by level, into a hierarchy where every cluster knows its own error and its parent's. Every frame,
129
+ compute shaders pick, per instance and per cluster, the version whose error projects to under a pixel. Because
130
+ errors grow monotonically up the hierarchy, the selection never has cracks. Many meshes share pooled buffers, so
131
+ the per-frame cost doesn't grow with the number of unique meshes.
132
+ [Read more](https://elad12390.github.io/three-virtual-geometry/guide/how-it-works).
133
+
134
+ ## Run the demos locally
135
+
136
+ ```bash
137
+ git clone https://github.com/elad12390/three-virtual-geometry && cd three-virtual-geometry
138
+ npm install
139
+ npm run dev # http://localhost:8090/?scene=ruins (also map, world, import, stress, test)
140
+ npm test # build invariants, partitioner, file format and import tests (Node)
141
+ ```
142
+
143
+ ## Limitations
144
+
145
+ - Static meshes (no skinning or morph targets); instances can move. Skinned meshes are left as normal three.js meshes.
146
+ - One UV channel. Hardware rasterization only (no software rasterizer for pixel-sized triangles).
147
+ - Occlusion culling needs a perspective camera with standard depth; it turns itself off otherwise.
148
+
149
+ ## About this project
150
+
151
+ This is an independent, open-source implementation of *virtual geometry* (a cluster LOD hierarchy selected per
152
+ frame on the GPU), the rendering technique popularized by Nanite. It is written from scratch in TypeScript for
153
+ three.js, based on public descriptions of the technique and on the MIT-licensed
154
+ [nanite-webgpu](https://github.com/Scthe/nanite-webgpu) by Marcin Matuszczyk.
155
+
156
+ - It contains no source code, shaders, binaries or assets from Epic Games or their engine, and nothing in it is
157
+ derived from their code or compiled code.
158
+ - It is not affiliated with, endorsed by or sponsored by Epic Games, Inc. "Nanite" is a trademark of Epic Games,
159
+ Inc., used here only to name the technique.
160
+
161
+ Built on [three.js](https://threejs.org) and [meshoptimizer](https://github.com/zeux/meshoptimizer). The demo's
162
+ cars are the [Kenney Car Kit](https://kenney.nl/assets/car-kit) (CC0). See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
163
+
164
+ ## License
165
+
166
+ [MIT](LICENSE) © 2026 Elad Ben-Haim
@@ -0,0 +1,42 @@
1
+ # Third-party notices
2
+
3
+ ## nanite-webgpu
4
+
5
+ Parts of the mesh preprocessing (`src/nanite/preprocess/buildNaniteMesh.ts`) and of the GPU culling
6
+ pipeline (`src/nanite/runtime/NaniteMesh.ts`) were ported from
7
+ [nanite-webgpu](https://github.com/Scthe/nanite-webgpu) and have since been substantially rewritten.
8
+
9
+ ```
10
+ The MIT License (MIT)
11
+
12
+ Copyright (c) 2024 Marcin Matuszczyk
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ ```
32
+
33
+ ## Runtime dependencies
34
+
35
+ `three` and `meshoptimizer` are npm dependencies (both MIT) and are not vendored here; their licenses
36
+ ship with their packages.
37
+
38
+ ## Demo assets (not part of the npm package)
39
+
40
+ `examples/public/models/kenney-car-kit/`: [Car Kit](https://kenney.nl/assets/car-kit) by Kenney (www.kenney.nl),
41
+ CC0 1.0 Universal (public domain). See `License.txt` in that folder. All other demo scenes are generated
42
+ procedurally in code.