Skip to content

Commit 8576384

Browse files
authored
docs: disco example (#1656)
1 parent bfd9e4b commit 8576384

File tree

8 files changed

+438
-0
lines changed

8 files changed

+438
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import tgpu from 'typegpu';
2+
import * as d from 'typegpu/data';
3+
4+
export const timeAccess = tgpu['~unstable'].accessor(d.f32);
5+
export const resolutionAccess = tgpu['~unstable'].accessor(d.vec2f); // (width, height)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<canvas data-fit-to-container></canvas>
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import tgpu from 'typegpu';
2+
import * as d from 'typegpu/data';
3+
import { mainVertex } from './shaders/vertex.ts';
4+
import { resolutionAccess, timeAccess } from './consts.ts';
5+
import {
6+
mainFragment,
7+
mainFragment2,
8+
mainFragment3,
9+
mainFragment4,
10+
mainFragment5,
11+
mainFragment6,
12+
mainFragment7,
13+
} from './shaders/fragment.ts';
14+
15+
const canvas = document.querySelector('canvas') as HTMLCanvasElement;
16+
const context = canvas.getContext('webgpu') as GPUCanvasContext;
17+
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
18+
const root = await tgpu.init();
19+
const device = root.device;
20+
21+
context.configure({
22+
device,
23+
format: presentationFormat,
24+
alphaMode: 'premultiplied',
25+
});
26+
27+
// Uniforms
28+
const time = root.createUniform(d.f32, 0);
29+
const resolutionUniform = root.createUniform(
30+
d.vec2f,
31+
d.vec2f(canvas.width, canvas.height),
32+
);
33+
34+
const fragmentShaders = [
35+
mainFragment,
36+
mainFragment2,
37+
mainFragment3,
38+
mainFragment4,
39+
mainFragment5,
40+
mainFragment6,
41+
mainFragment7,
42+
];
43+
44+
const pipelines = fragmentShaders.map((fragment) =>
45+
root['~unstable']
46+
.with(timeAccess, time)
47+
.with(resolutionAccess, resolutionUniform)
48+
.withVertex(mainVertex, {})
49+
.withFragment(fragment, { format: presentationFormat })
50+
.createPipeline()
51+
);
52+
53+
let currentPipeline = pipelines[0];
54+
55+
let startTime = performance.now();
56+
let frameId: number;
57+
58+
function render() {
59+
const timestamp = (performance.now() - startTime) / 1000;
60+
if (timestamp > 500.0) startTime = performance.now();
61+
time.write(timestamp);
62+
resolutionUniform.write(d.vec2f(canvas.width, canvas.height));
63+
64+
currentPipeline
65+
.withColorAttachment({
66+
view: context.getCurrentTexture().createView(),
67+
clearValue: [0, 0, 0, 1],
68+
loadOp: 'clear',
69+
storeOp: 'store',
70+
})
71+
.draw(6);
72+
73+
frameId = requestAnimationFrame(render);
74+
}
75+
76+
frameId = requestAnimationFrame(render);
77+
78+
export function onCleanup() {
79+
cancelAnimationFrame(frameId);
80+
root.destroy();
81+
}
82+
83+
export const controls = {
84+
Pattern: {
85+
initial: 'pattern1',
86+
options: [
87+
'pattern1',
88+
'pattern2',
89+
'pattern3',
90+
'pattern4',
91+
'pattern5',
92+
'pattern6',
93+
'pattern7',
94+
],
95+
onSelectChange(value: string) {
96+
const patternIndex = {
97+
pattern1: 0,
98+
pattern2: 1,
99+
pattern3: 2,
100+
pattern4: 3,
101+
pattern5: 4,
102+
pattern6: 5,
103+
pattern7: 6,
104+
}[value];
105+
if (patternIndex !== undefined) {
106+
currentPipeline = pipelines[patternIndex];
107+
render();
108+
}
109+
},
110+
},
111+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"title": "Disco",
3+
"category": "simple",
4+
"tags": ["experimental"]
5+
}

0 commit comments

Comments
 (0)