Skip to content

Commit 3de9a51

Browse files
reczkokiwoplazaaleksanderkatanlurszcieplypolar
authored
feat: Add @typegpu/three package and Three.js integration example (#1453)
* feat: tgpu.comptime, tgpu.rawCodeSnippet and `this` allowed in TypeGPU shader functions * Fix tests * Better docs for rawCodeSnippet * Docs for comptime * - Namable comptime - Turned `extensionEnabled` into a comptime function * Fixes * Add @typegpu/three package and Three.js integration example (very WIP) * Update tgpuThree.ts * Three.js types for example code view * More tweaks and experiments * More work * A bit more work * More work * Using @typegpu/noise in Three.js * Add a new example * Testing compute in Three.js * Update examples * Update typegpu-material.ts * Update index.ts * Some more work * Works again * TypeGPU compute shaders in TSL! * A bit of a refactor of the cloth example * Cleanup 🧹 * Comparing Three and TypeGPU output * triNoise3D in TypeGPU * comptime * Support for 'this' in TypeGPU shader functions * Update verlet.ts * feat: Attractors example (#1949) * Tweaks * feat: Tweaks to feat/tgpu-three (#1954) * Some review fixes * Thumbnails and tags * Comptime fromTSL * Update shellless.test.ts * fix: Calling `toTSL` multiple times (#1974) * feat: Inform user about type mismatches (#1988) * Fix renderer resizing when browser zoom * docs: Cloth example controls (#1986) * feat: ThreeJS 'Compute Particles' with tgpu (#1947) * feat: ThreeJS 'Compute Geometry' with tgpu (#1948) * feat: ThreeJS 'Compute Snow Particles' example in tgpu (#1972) * fix: @typegpu/three toTSL should have a per-stage namespace (#1994) --------- Co-authored-by: Iwo Plaza <iwoplaza@gmail.com> Co-authored-by: Aleksander Katan <56294622+aleksanderkatan@users.noreply.github.com> Co-authored-by: Rafal Lukosz <93160829+lursz@users.noreply.github.com> Co-authored-by: Szymon Szulc <103948576+cieplypolar@users.noreply.github.com>
1 parent f71969f commit 3de9a51

61 files changed

Lines changed: 3258 additions & 179 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/typegpu-docs/astro.config.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,15 @@ export default defineConfig({
211211
label: '@typegpu/noise',
212212
slug: 'ecosystem/typegpu-noise',
213213
},
214+
{
215+
label: '@typegpu/three',
216+
slug: 'ecosystem/typegpu-three',
217+
badge: { text: 'new' },
218+
},
214219
{
215220
label: '@typegpu/sdf',
216221
slug: 'ecosystem/typegpu-sdf',
222+
badge: { text: 'new' },
217223
},
218224
DEV && {
219225
label: '@typegpu/color',

apps/typegpu-docs/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
"@typegpu/color": "workspace:*",
2929
"@typegpu/geometry": "workspace:*",
3030
"@typegpu/noise": "workspace:*",
31+
"@typegpu/three": "workspace:*",
3132
"@typegpu/sdf": "workspace:*",
33+
"three": "catalog:example",
3234
"@types/react": "^19.1.8",
3335
"@types/react-dom": "^19.1.6",
3436
"arktype": "catalog:",
@@ -68,9 +70,9 @@
6870
"@types/babel__standalone": "^7.1.9",
6971
"@types/babel__template": "^7.4.4",
7072
"@types/babel__traverse": "^7.20.7",
71-
"@types/dom-mediacapture-record": "^1.0.22",
7273
"@types/node": "^24.7.0",
7374
"@vitejs/plugin-basic-ssl": "^2.1.0",
75+
"@types/three": "catalog:types",
7476
"@webgpu/types": "catalog:types",
7577
"astro-vtbot": "^2.1.6",
7678
"autoprefixer": "^10.4.21",
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Creative Commons Licence
2+
Infinite, 3D Head Scan by Lee Perry-Smith is licensed under a Creative Commons Attribution 3.0 Unported License.
3+
Based on a work at www.triplegangers.com.
4+
Permissions beyond the scope of this license may be available at http://www.ir-ltd.net/
5+
Please remember: Do what you want with the files, but always mention where you got them from...
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
title: "@typegpu/three"
3+
---
4+
5+
[TSL (Three.js Shading Language)](https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language#function) is a node-based shader composition system for Three.js. Shader logic and control flow is built up by composing special functions,
6+
with a focus on composability, intuitive sharing of logic across modules and customizability. TypeGPU fits naturally into this system thanks to the `@typegpu/three` package. You can choose to write your TSL building blocks in TypeGPU, which has a few benefits:
7+
- Control-flow like `if` statements and `for` loops makes use of familiar JavaScript syntax instead of special functions.
8+
- The code you write is semantically valid JavaScript, with types flowing through each expression.
9+
- Unit-testability, since you can call these functions on the CPU
10+
11+
Below are a select few cases comparing TSL and TypeGPU:
12+
13+
import { Card, CardGrid } from '@astrojs/starlight/components';
14+
15+
## Node definition
16+
17+
TSL:
18+
```ts
19+
const simulate = Fn(() => {
20+
//
21+
// ... TSL code ...
22+
//
23+
});
24+
```
25+
26+
TypeGPU:
27+
```ts twoslash
28+
import * as t3 from '@typegpu/three';
29+
// ---cut---
30+
const simulate = t3.toTSL(() => {
31+
'use gpu';
32+
//
33+
// ... TypeGPU code ...
34+
//
35+
});
36+
```
37+
38+
## Function definition
39+
40+
TSL:
41+
```ts
42+
const oscSine = Fn(([t = time]) => {
43+
return t.add(0.75).mul(Math.PI * 2).sin().mul(0.5).add(0.5);
44+
});
45+
```
46+
47+
TypeGPU:
48+
```ts twoslash
49+
import * as std from 'typegpu/std';
50+
// ---cut---
51+
const oscSine = (t: number) => {
52+
'use gpu';
53+
return std.sin((t + 0.75) * Math.PI * 2) * 0.5 + 0.5;
54+
};
55+
```
56+
57+
## If statements
58+
59+
TSL:
60+
```ts
61+
If(instanceIndex.greaterThanEqual(uint(vertexCount)), () => {
62+
Return();
63+
});
64+
```
65+
66+
TypeGPU:
67+
```ts twoslash
68+
import * as t3 from '@typegpu/three';
69+
declare const vertexCount: number;
70+
const some = () => {
71+
// ---cut-before---
72+
if (t3.instanceIndex.$ >= vertexCount) {
73+
return;
74+
}
75+
// ---cut-after---
76+
};
77+
```
78+
79+
## For loops
80+
81+
TSL:
82+
```ts
83+
Loop({ start: ptrStart, end: ptrEnd, type: 'uint', condition: '<' }, ({ i }) => {
84+
const springId = springListBuffer.element( i ).toVar( 'springId' );
85+
const springForce = springForceBuffer.element( springId );
86+
const springVertexIds = springVertexIdBuffer.element( springId );
87+
const factor = select( springVertexIds.x.equal( instanceIndex ), 1.0, - 1.0 );
88+
force.addAssign( springForce.mul( factor ) );
89+
});
90+
```
91+
92+
TypeGPU:
93+
```ts
94+
for (let i = ptrStart; i < ptrEnd; i++) {
95+
const springId = springListBuffer.$[i];
96+
const springForce = springForceBuffer.$[springId];
97+
const springVertexIds = springVertexIdBuffer.$[springId];
98+
const factor = std.select(-1, 1, springVertexIds.x === idx);
99+
force = force.add(springForce.mul(d.f32(factor)));
100+
}
101+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<canvas data-fit-to-container></canvas>

0 commit comments

Comments
 (0)