Skip to content

Commit d51b214

Browse files
authored
docs: "Jelly Switch" example (#1902)
1 parent 9e4ce90 commit d51b214

File tree

20 files changed

+1500
-0
lines changed

20 files changed

+1500
-0
lines changed
44.9 KB
Binary file not shown.
276 KB
Binary file not shown.
309 KB
Binary file not shown.
276 KB
Binary file not shown.
303 KB
Binary file not shown.
286 KB
Binary file not shown.
299 KB
Binary file not shown.
9.66 KB
Binary file not shown.
10.9 KB
Binary file not shown.
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import type { TgpuRoot, TgpuUniform } from 'typegpu';
2+
import * as d from 'typegpu/data';
3+
import * as m from 'wgpu-matrix';
4+
5+
const Camera = d.struct({
6+
view: d.mat4x4f,
7+
proj: d.mat4x4f,
8+
viewInv: d.mat4x4f,
9+
projInv: d.mat4x4f,
10+
});
11+
12+
function halton(index: number, base: number) {
13+
let result = 0;
14+
let f = 1 / base;
15+
let i = index;
16+
while (i > 0) {
17+
result += f * (i % base);
18+
i = Math.floor(i / base);
19+
f = f / base;
20+
}
21+
return result;
22+
}
23+
24+
function* haltonSequence(base: number) {
25+
let index = 1;
26+
while (true) {
27+
yield halton(index, base);
28+
index++;
29+
}
30+
}
31+
32+
export class CameraController {
33+
#uniform: TgpuUniform<typeof Camera>;
34+
#view: d.m4x4f;
35+
#proj: d.m4x4f;
36+
#viewInv: d.m4x4f;
37+
#projInv: d.m4x4f;
38+
#baseProj: d.m4x4f;
39+
#baseProjInv: d.m4x4f;
40+
#haltonX: Generator<number>;
41+
#haltonY: Generator<number>;
42+
#width: number;
43+
#height: number;
44+
45+
constructor(
46+
root: TgpuRoot,
47+
position: d.v3f,
48+
target: d.v3f,
49+
up: d.v3f,
50+
fov: number,
51+
width: number,
52+
height: number,
53+
near = 0.1,
54+
far = 10,
55+
) {
56+
this.#width = width;
57+
this.#height = height;
58+
59+
this.#view = m.mat4.lookAt(position, target, up, d.mat4x4f());
60+
this.#baseProj = m.mat4.perspective(
61+
fov,
62+
width / height,
63+
near,
64+
far,
65+
d.mat4x4f(),
66+
);
67+
this.#proj = this.#baseProj;
68+
69+
this.#viewInv = m.mat4.invert(this.#view, d.mat4x4f());
70+
this.#baseProjInv = m.mat4.invert(this.#baseProj, d.mat4x4f());
71+
this.#projInv = this.#baseProjInv;
72+
73+
this.#uniform = root.createUniform(Camera, {
74+
view: this.#view,
75+
proj: this.#proj,
76+
viewInv: this.#viewInv,
77+
projInv: this.#projInv,
78+
});
79+
80+
this.#haltonX = haltonSequence(2);
81+
this.#haltonY = haltonSequence(3);
82+
}
83+
84+
jitter() {
85+
const [jx, jy] = [
86+
this.#haltonX.next().value,
87+
this.#haltonY.next().value,
88+
] as [
89+
number,
90+
number,
91+
];
92+
93+
const jitterX = ((jx - 0.5) * 2.0) / this.#width;
94+
const jitterY = ((jy - 0.5) * 2.0) / this.#height;
95+
96+
const jitterMatrix = m.mat4.identity(d.mat4x4f());
97+
jitterMatrix[12] = jitterX; // x translation in NDC
98+
jitterMatrix[13] = jitterY; // y translation in NDC
99+
100+
const jitteredProj = m.mat4.mul(jitterMatrix, this.#baseProj, d.mat4x4f());
101+
const jitteredProjInv = m.mat4.invert(jitteredProj, d.mat4x4f());
102+
103+
this.#uniform.writePartial({
104+
proj: jitteredProj,
105+
projInv: jitteredProjInv,
106+
});
107+
}
108+
109+
updateView(position: d.v3f, target: d.v3f, up: d.v3f) {
110+
this.#view = m.mat4.lookAt(position, target, up, d.mat4x4f());
111+
this.#viewInv = m.mat4.invert(this.#view, d.mat4x4f());
112+
113+
this.#uniform.writePartial({
114+
view: this.#view,
115+
viewInv: this.#viewInv,
116+
});
117+
}
118+
119+
updateProjection(
120+
fov: number,
121+
width: number,
122+
height: number,
123+
near = 0.1,
124+
far = 100,
125+
) {
126+
this.#width = width;
127+
this.#height = height;
128+
129+
this.#baseProj = m.mat4.perspective(
130+
fov,
131+
width / height,
132+
near,
133+
far,
134+
d.mat4x4f(),
135+
);
136+
this.#baseProjInv = m.mat4.invert(this.#baseProj, d.mat4x4f());
137+
138+
this.#uniform.writePartial({
139+
proj: this.#baseProj,
140+
projInv: this.#baseProjInv,
141+
});
142+
}
143+
144+
get cameraUniform() {
145+
return this.#uniform;
146+
}
147+
}

0 commit comments

Comments
 (0)