Skip to content
Merged
Show file tree
Hide file tree
Changes from 104 commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
7513b7a
init
reczkok Jul 1, 2025
62a7558
some work
reczkok Aug 13, 2025
ee2242d
heavy debugging and tweaks
reczkok Aug 14, 2025
11f15d6
working example yay
reczkok Aug 20, 2025
75e8316
remove the old complex example for now
reczkok Aug 20, 2025
66d6b30
Merge branch 'main' into docs/shadows
reczkok Aug 20, 2025
4065f50
Refactor and cleanup
reczkok Aug 20, 2025
4f16176
Merge branch 'main' into docs/shadows
reczkok Aug 22, 2025
bfc5eff
fix wordo
reczkok Aug 22, 2025
e5c0f73
more parameters and kill mr peter pan
reczkok Aug 22, 2025
4175d75
inital schemas
reczkok Aug 26, 2025
615579b
wip
reczkok Aug 26, 2025
244241f
working maybe?
reczkok Aug 26, 2025
4101c6d
adapt examples
reczkok Aug 27, 2025
22f77e3
some fixes
reczkok Aug 27, 2025
a56fcda
new schemas
reczkok Aug 28, 2025
b6fb8a1
the new new api
reczkok Aug 28, 2025
26e6a49
Merge branch 'main' into feat/texture-schemas
reczkok Aug 28, 2025
4f8b93e
fix post merge
reczkok Aug 28, 2025
2022586
cleanup and very fast self review
reczkok Aug 28, 2025
7199789
Merge branch 'main' into feat/texture-schemas
reczkok Sep 1, 2025
b54f8fb
update tests to the new api
reczkok Sep 1, 2025
c583194
fix dumb import
reczkok Sep 1, 2025
9472842
fix doc
reczkok Sep 1, 2025
824d4c5
Merge branch 'main' into feat/texture-schemas
reczkok Sep 2, 2025
c098282
preliminary validation
reczkok Sep 3, 2025
5a240d9
fix (which means validation is working yay)
reczkok Sep 3, 2025
9ccfc87
add legacy support
reczkok Sep 3, 2025
abdd520
add tests
reczkok Sep 3, 2025
7cf5740
fix deprecation message
reczkok Sep 3, 2025
3379883
Merge branch 'main' into feat/texture-schemas
reczkok Sep 4, 2025
ca8dc8c
better types and default view (with validation)
reczkok Sep 4, 2025
14cb6eb
fix bind group layout types and add mild texture validation. Also fixes
reczkok Sep 4, 2025
566adae
good error
reczkok Sep 4, 2025
bac3f8c
fix snapshots
reczkok Sep 4, 2025
611c692
reoreder overloads and fix examples
reczkok Sep 5, 2025
ac572c1
cleanup and dead code reomoval
reczkok Sep 5, 2025
3a960c7
add overloads and little cleanup
reczkok Sep 5, 2025
ce6dcda
more tests and viewFormats type fix and validation
reczkok Sep 5, 2025
4f48632
Merge branch 'main' into feat/texture-schemas
reczkok Sep 9, 2025
50c9efe
more apis and fixes
reczkok Sep 10, 2025
5433e5e
move tests to tests
reczkok Sep 10, 2025
8af290b
rework blur example and update docs
reczkok Sep 10, 2025
bf3a0f4
kill console.log and simplify
reczkok Sep 10, 2025
01e20db
revert thumbnail
reczkok Sep 10, 2025
d4012ff
Merge branch 'main' into feat/texture-schemas
reczkok Sep 10, 2025
1a0f5e1
update test
reczkok Sep 10, 2025
b077cc9
remove bloat
reczkok Sep 10, 2025
a82164c
remove redundancy
reczkok Sep 10, 2025
facdaba
format in a more line friendly way
reczkok Sep 10, 2025
300b1ba
move examples pre merge
reczkok Sep 15, 2025
e776368
Merge branch 'main' into feat/texture-schemas
reczkok Sep 15, 2025
765b8ba
fixes
reczkok Sep 16, 2025
f73e01d
Merge branch 'main' into feat/texture-schemas
reczkok Sep 16, 2025
6929723
Merge branch 'main' into feat/texture-schemas
reczkok Sep 16, 2025
0b013c9
guard against missing render usage when generating mipmaps
reczkok Sep 16, 2025
4674cdb
Merge branch 'main' into feat/texture-schemas
reczkok Sep 16, 2025
c05b9ae
sadly no type level erros since the flags are too limiting (no way to…
reczkok Sep 16, 2025
02794a4
update tests
reczkok Sep 16, 2025
4f3ef6f
update snapshot
reczkok Sep 16, 2025
2f0c3ee
imports and formatting fixes
reczkok Sep 17, 2025
52b1f70
texture instance types
reczkok Sep 18, 2025
a48dea1
some more tests
reczkok Sep 18, 2025
be2aaf8
Merge branch 'main' into feat/texture-schemas
reczkok Sep 18, 2025
5dcdf0f
refactor liquid glass with shellless
reczkok Sep 18, 2025
c69c527
minor liquid glass refactoring
reczkok Sep 18, 2025
1fa2599
add liquid glass test and fix bad helper indent
reczkok Sep 18, 2025
8260671
move cubemap reflection example to the new api
reczkok Sep 18, 2025
b6c2aeb
fix liquid glass
reczkok Sep 18, 2025
b41b7ff
better mock and update tests
reczkok Sep 18, 2025
072e265
better mock
reczkok Sep 18, 2025
7b4b31e
Merge branch 'main' into feat/texture-schemas
reczkok Sep 19, 2025
e93fff6
wip
reczkok Sep 19, 2025
4f52f9f
wip
reczkok Sep 22, 2025
3c37598
normal debug
reczkok Sep 22, 2025
d8795f3
more wip
reczkok Sep 23, 2025
934adce
primitive TAA
reczkok Oct 1, 2025
726bec2
lighter params
reczkok Oct 1, 2025
dcde952
Merge branch 'main' into docs/jelly-slider
reczkok Oct 1, 2025
057d812
tweaks and color gradient
reczkok Oct 1, 2025
1e07ce9
tweaks
reczkok Oct 7, 2025
be9a624
quality settings
reczkok Oct 7, 2025
ea79989
optimization in progress
reczkok Oct 7, 2025
a53f840
work work
reczkok Oct 7, 2025
519beae
progress I guess
reczkok Oct 7, 2025
ce4c7f1
works but at what cost
reczkok Oct 9, 2025
6417c85
wio
reczkok Oct 14, 2025
d490db0
minor
reczkok Oct 14, 2025
f90bc57
work work
reczkok Oct 15, 2025
6bab5a6
Merge branch 'main' into docs/jelly-slider
reczkok Oct 16, 2025
13f78db
texture time
reczkok Oct 16, 2025
9ba79ff
major optimizations
reczkok Oct 16, 2025
a668d84
working but a mess
reczkok Oct 17, 2025
79f2955
some cleanup
reczkok Oct 17, 2025
a033807
tweaks
reczkok Oct 19, 2025
f2389a5
back to hard shadows and customizable color
reczkok Oct 19, 2025
02684b1
text rendering
reczkok Oct 20, 2025
359c998
Merge branch 'main' into docs/jelly-slider
reczkok Oct 20, 2025
16b4543
post merge fixes and little cleanup
reczkok Oct 20, 2025
a694559
caustics wip
reczkok Oct 20, 2025
524b2ed
tweak caustics (still bad) and add auto quality mode (yay)
reczkok Oct 20, 2025
22303a5
initial cleanup
reczkok Oct 20, 2025
18f6e28
more cleanup
reczkok Oct 20, 2025
fd4b15b
cleanup and less bind groups
reczkok Oct 20, 2025
bd07831
review fixes
reczkok Oct 21, 2025
431d427
Merge branch 'main' into docs/jelly-slider
reczkok Oct 21, 2025
06fbb70
higher fps target for auto (since the jelly is more performant when i…
reczkok Oct 21, 2025
152627e
reduce to single pass and simplify/optimize
reczkok Oct 21, 2025
71acf77
simpler light direction
reczkok Oct 21, 2025
61f1a79
Merge branch 'main' into docs/jelly-slider
reczkok Oct 21, 2025
4c1b211
tweaks and updates
reczkok Oct 22, 2025
a081130
docs: Jelly Slider (fake light) (#1848)
iwoplaza Oct 24, 2025
e0b77a7
Merge branch 'main' into docs/jelly-slider
reczkok Oct 28, 2025
bfc2e78
add thumbnail
reczkok Oct 28, 2025
3f98e68
attribution and less text ghosting
reczkok Oct 28, 2025
6702a83
fix interaction
reczkok Oct 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions apps/typegpu-docs/src/examples/rendering/jelly-slider/camera.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import type { TgpuRoot, TgpuUniform } from 'typegpu';
import * as d from 'typegpu/data';
import * as m from 'wgpu-matrix';

const Camera = d.struct({
view: d.mat4x4f,
proj: d.mat4x4f,
viewInv: d.mat4x4f,
projInv: d.mat4x4f,
});

function halton(index: number, base: number) {
let result = 0;
let f = 1 / base;
let i = index;
while (i > 0) {
result += f * (i % base);
i = Math.floor(i / base);
f = f / base;
}
return result;
}

function* haltonSequence(base: number) {
let index = 1;
while (true) {
yield halton(index, base);
index++;
}
}

export class CameraController {
#uniform: TgpuUniform<typeof Camera>;
#view: d.m4x4f;
#proj: d.m4x4f;
#viewInv: d.m4x4f;
#projInv: d.m4x4f;
#baseProj: d.m4x4f;
#baseProjInv: d.m4x4f;
#haltonX: Generator<number>;
#haltonY: Generator<number>;
#width: number;
#height: number;

constructor(
root: TgpuRoot,
position: d.v3f,
target: d.v3f,
up: d.v3f,
fov: number,
width: number,
height: number,
near = 0.1,
far = 10,
) {
this.#width = width;
this.#height = height;

this.#view = m.mat4.lookAt(position, target, up, d.mat4x4f());
this.#baseProj = m.mat4.perspective(
fov,
width / height,
near,
far,
d.mat4x4f(),
);
this.#proj = this.#baseProj;

this.#viewInv = m.mat4.invert(this.#view, d.mat4x4f());
this.#baseProjInv = m.mat4.invert(this.#baseProj, d.mat4x4f());
this.#projInv = this.#baseProjInv;

this.#uniform = root.createUniform(Camera, {
view: this.#view,
proj: this.#proj,
viewInv: this.#viewInv,
projInv: this.#projInv,
});

this.#haltonX = haltonSequence(2);
this.#haltonY = haltonSequence(3);
}

jitter() {
const [jx, jy] = [
this.#haltonX.next().value,
this.#haltonY.next().value,
] as [
number,
number,
];

const jitterX = ((jx - 0.5) * 2.0) / this.#width;
const jitterY = ((jy - 0.5) * 2.0) / this.#height;

const jitterMatrix = m.mat4.identity(d.mat4x4f());
jitterMatrix[12] = jitterX; // x translation in NDC
jitterMatrix[13] = jitterY; // y translation in NDC

const jitteredProj = m.mat4.mul(jitterMatrix, this.#baseProj, d.mat4x4f());
const jitteredProjInv = m.mat4.invert(jitteredProj, d.mat4x4f());

this.#uniform.writePartial({
proj: jitteredProj,
projInv: jitteredProjInv,
});
}

updateView(position: d.v3f, target: d.v3f, up: d.v3f) {
this.#view = m.mat4.lookAt(position, target, up, d.mat4x4f());
this.#viewInv = m.mat4.invert(this.#view, d.mat4x4f());

this.#uniform.writePartial({
view: this.#view,
viewInv: this.#viewInv,
});
}

updateProjection(
fov: number,
width: number,
height: number,
near = 0.1,
far = 100,
) {
this.#width = width;
this.#height = height;

this.#baseProj = m.mat4.perspective(
fov,
width / height,
near,
far,
d.mat4x4f(),
);
this.#baseProjInv = m.mat4.invert(this.#baseProj, d.mat4x4f());

this.#uniform.writePartial({
proj: this.#baseProj,
projInv: this.#baseProjInv,
});
}

get cameraUniform() {
return this.#uniform;
}
}
39 changes: 39 additions & 0 deletions apps/typegpu-docs/src/examples/rendering/jelly-slider/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as d from 'typegpu/data';

// Rendering constants
export const MAX_STEPS = 64;
export const MAX_DIST = 10;
export const SURF_DIST = 0.001;

// Lighting constants
export const AMBIENT_COLOR = d.vec3f(1);
export const AMBIENT_INTENSITY = 0.2;
export const SPECULAR_POWER = 32.0;
export const SPECULAR_INTENSITY = 0.4;

// Jelly material constants
export const JELLY_IOR = 1.42;
export const JELLY_ABSORB = d.vec3f(1.6, 3.2, 6.0).mul(5);
export const JELLY_SCATTER_TINT = d.vec3f(1.0, 0.3, 0.05).mul(1.5);
export const JELLY_SCATTER_STRENGTH = 1.3;
export const MAX_INTERNAL_STEPS = 7;

// Ambient occlusion constants
export const AO_STEPS = 3;
export const AO_RADIUS = 0.2;
export const AO_INTENSITY = 0.8;
export const AO_BIAS = SURF_DIST * 5;

// Line/slider constants
export const LINE_RADIUS = 0.024;
export const LINE_HALF_THICK = 0.17;

// Mouse interaction constants
export const MOUSE_SMOOTHING = 0.08;
export const MOUSE_MIN_X = 0.45;
export const MOUSE_MAX_X = 0.9;
export const MOUSE_RANGE_MIN = 0.4;
export const MOUSE_RANGE_MAX = 0.9;
export const TARGET_MIN = -0.7;
export const TARGET_MAX = 1.0;
export const TARGET_OFFSET = -0.5;
72 changes: 72 additions & 0 deletions apps/typegpu-docs/src/examples/rendering/jelly-slider/dataTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import tgpu from 'typegpu';
import * as d from 'typegpu/data';

export const DirectionalLight = d.struct({
direction: d.vec3f,
color: d.vec3f,
});

export const ObjectType = {
SLIDER: 1,
BACKGROUND: 2,
} as const;

export const HitInfo = d.struct({
distance: d.f32,
objectType: d.i32,
t: d.f32,
});

export const LineInfo = d.struct({
t: d.f32,
distance: d.f32,
normal: d.vec2f,
});

export const BoxIntersection = d.struct({
hit: d.bool,
tMin: d.f32,
tMax: d.f32,
});

export const Ray = d.struct({
origin: d.vec3f,
direction: d.vec3f,
});

export const SdfBbox = d.struct({
left: d.f32,
right: d.f32,
bottom: d.f32,
top: d.f32,
});

export const backgroundDistLayout = tgpu.bindGroupLayout({
distanceTexture: {
storageTexture: d.textureStorage2d('r32float', 'write-only'),
},
});

export const rayMarchLayout = tgpu.bindGroupLayout({
backgroundDistTexture: {
storageTexture: d.textureStorage2d('r32float', 'read-only'),
},
});

export const taaResolveLayout = tgpu.bindGroupLayout({
currentTexture: {
texture: d.texture2d(),
},
historyTexture: {
texture: d.texture2d(),
},
outputTexture: {
storageTexture: d.textureStorage2d('rgba8unorm', 'write-only'),
},
});

export const sampleLayout = tgpu.bindGroupLayout({
currentTexture: {
texture: d.texture2d(),
},
});
93 changes: 93 additions & 0 deletions apps/typegpu-docs/src/examples/rendering/jelly-slider/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {
MOUSE_MAX_X,
MOUSE_MIN_X,
MOUSE_RANGE_MAX,
MOUSE_RANGE_MIN,
MOUSE_SMOOTHING,
TARGET_MAX,
TARGET_MIN,
TARGET_OFFSET,
} from './constants.ts';

export class EventHandler {
private canvas: HTMLCanvasElement;
private mouseX = 1.0;
private targetMouseX = 1.0;
private isMouseDown = false;

constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas;
this.setupEventListeners();
}

private setupEventListeners() {
// Mouse events
this.canvas.addEventListener('mouseup', () => {
this.isMouseDown = false;
});

this.canvas.addEventListener('mouseleave', () => {
this.isMouseDown = false;
});

this.canvas.addEventListener('mousedown', (e) => {
this.handlePointerDown(e.clientX);
});

this.canvas.addEventListener('mousemove', (e) => {
if (!this.isMouseDown) return;
this.handlePointerMove(e.clientX);
});

// Touch events
this.canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
const touch = e.touches[0];
this.handlePointerDown(touch.clientX);
});

this.canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
if (!this.isMouseDown) return;
const touch = e.touches[0];
this.handlePointerMove(touch.clientX);
});

this.canvas.addEventListener('touchend', (e) => {
e.preventDefault();
this.isMouseDown = false;
});
}

private handlePointerDown(clientX: number) {
this.isMouseDown = true;
this.updateTargetMouseX(clientX);
}

private handlePointerMove(clientX: number) {
this.updateTargetMouseX(clientX);
}

private updateTargetMouseX(clientX: number) {
const rect = this.canvas.getBoundingClientRect();
const normalizedX = (clientX - rect.left) / rect.width;
const clampedX = Math.max(MOUSE_MIN_X, Math.min(MOUSE_MAX_X, normalizedX));
this.targetMouseX =
((clampedX - MOUSE_RANGE_MIN) / (MOUSE_RANGE_MAX - MOUSE_RANGE_MIN)) *
(TARGET_MAX - TARGET_MIN) + TARGET_OFFSET;
}

update() {
if (this.isMouseDown) {
this.mouseX += (this.targetMouseX - this.mouseX) * MOUSE_SMOOTHING;
}
}

get currentMouseX() {
return this.mouseX;
}

get isPointerDown() {
return this.isMouseDown;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<canvas></canvas>
Loading