Skip to content

Commit 92c8c50

Browse files
committed
simplified uniformity example + validation of seed functions presence
1 parent 026a3a3 commit 92c8c50

8 files changed

Lines changed: 150 additions & 149 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PRNG } from './prngs.ts';
22

3-
export const gridSizes = [10, 25, 50, 100, 200, 500, 700, 1000];
4-
export const initialGridSize = gridSizes[3];
3+
export const gridSizes = [8, 16, 32, 64, 128, 256, 512, 1024];
4+
export const initialGridSize = gridSizes[4];
55
export const initialPRNG = PRNG.BPETER;
66
export const prngs: PRNG[] = Object.values(PRNG);

apps/typegpu-docs/src/examples/tests/uniformity/fragment.ts

Lines changed: 0 additions & 21 deletions
This file was deleted.

apps/typegpu-docs/src/examples/tests/uniformity/helpers.ts

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<canvas data-fit-to-container></canvas>
1+
<canvas></canvas>

apps/typegpu-docs/src/examples/tests/uniformity/index.ts

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import tgpu, { type TgpuRenderPipeline } from 'typegpu';
22
import * as d from 'typegpu/data';
3+
import * as std from 'typegpu/std';
4+
import { fullScreenTriangle } from 'typegpu/common';
5+
import { randf, randomGeneratorSlot } from '@typegpu/noise';
36

47
import * as c from './constants.ts';
5-
import { executePipeline, preparePipeline } from './helpers.ts';
6-
import type { PRNG } from './prngs.ts';
8+
import { getPRNG, type PRNG } from './prngs.ts';
79

810
const root = await tgpu.init();
911

@@ -21,23 +23,43 @@ const canvasRatioUniform = root.createUniform(
2123
d.f32,
2224
canvas.width / canvas.height,
2325
);
26+
27+
const fragmentShader = tgpu['~unstable'].fragmentFn({
28+
in: { uv: d.vec2f },
29+
out: d.vec4f,
30+
})((input) => {
31+
const uv = input.uv.add(1).div(2).mul(d.vec2f(canvasRatioUniform.$, 1));
32+
const gridedUV = std.floor(uv.mul(gridSizeUniform.$));
33+
34+
randf.seed2(gridedUV);
35+
36+
return d.vec4f(d.vec3f(randf.sample()), 1.0);
37+
});
38+
2439
const pipelineCache = new Map<PRNG, TgpuRenderPipeline>();
2540
let prng: PRNG = c.initialPRNG;
2641

27-
const redraw = (value: PRNG) => {
28-
let pipeline = pipelineCache.get(value);
42+
const redraw = () => {
43+
let pipeline = pipelineCache.get(prng);
2944
if (!pipeline) {
30-
pipeline = preparePipeline(
31-
root,
32-
presentationFormat,
33-
value,
34-
gridSizeUniform,
35-
canvasRatioUniform,
36-
);
37-
pipelineCache.set(value, pipeline);
45+
pipeline = root['~unstable']
46+
.with(randomGeneratorSlot, getPRNG(prng))
47+
.withVertex(fullScreenTriangle)
48+
.withFragment(
49+
fragmentShader,
50+
{ format: presentationFormat },
51+
)
52+
.createPipeline();
53+
pipelineCache.set(prng, pipeline);
3854
}
3955

40-
executePipeline(pipeline as TgpuRenderPipeline, context);
56+
pipeline
57+
.withColorAttachment({
58+
view: context.getCurrentTexture().createView(),
59+
loadOp: 'clear',
60+
storeOp: 'store',
61+
})
62+
.draw(3);
4163
};
4264

4365
// #region Example controls & Cleanup
@@ -47,41 +69,43 @@ export const controls = {
4769
options: c.prngs,
4870
onSelectChange: (value: PRNG) => {
4971
prng = value;
50-
redraw(value);
72+
redraw();
5173
},
5274
},
5375
'Grid Size': {
5476
initial: c.initialGridSize,
5577
options: c.gridSizes,
5678
onSelectChange: (value: number) => {
5779
gridSizeUniform.write(value);
58-
redraw(prng);
80+
redraw();
5981
},
6082
},
6183
'Test Resolution': import.meta.env.DEV && {
6284
onButtonClick: () => {
85+
const namespace = tgpu['~unstable'].namespace();
6386
c.prngs
6487
.map((prng) =>
65-
tgpu.resolve(
66-
[
67-
preparePipeline(
68-
root,
69-
presentationFormat,
70-
prng,
71-
gridSizeUniform,
72-
canvasRatioUniform,
73-
),
74-
],
75-
)
88+
tgpu.resolve([
89+
root['~unstable']
90+
.with(randomGeneratorSlot, getPRNG(prng))
91+
.withVertex(fullScreenTriangle)
92+
.withFragment(
93+
fragmentShader,
94+
{ format: presentationFormat },
95+
)
96+
.createPipeline(),
97+
], { names: namespace })
7698
)
77-
.map((r) => root.device.createShaderModule({ code: r }));
99+
.map((r) => {
100+
root.device.createShaderModule({ code: r });
101+
});
78102
},
79103
},
80104
};
81105

82106
const resizeObserver = new ResizeObserver(() => {
83107
canvasRatioUniform.write(canvas.width / canvas.height);
84-
redraw(prng);
108+
redraw();
85109
});
86110
resizeObserver.observe(canvas);
87111

apps/typegpu-docs/src/examples/tests/uniformity/lcg.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,14 @@ import * as std from 'typegpu/std';
66
export const LCG: StatefulGenerator = (() => {
77
const seed = tgpu.privateVar(d.u32);
88

9-
const u32To01Float = tgpu.fn([d.u32], d.f32)`(val){
10-
let exponent: u32 = 0x3f800000;
11-
let mantissa: u32 = 0x007fffff & val;
12-
var ufloat: u32 = (exponent | mantissa);
13-
return bitcast<f32>(ufloat) - 1f;
14-
}`;
9+
const u32To01Float = tgpu.fn([d.u32], d.f32)((value) => {
10+
const mantissa = value >> 9;
11+
const bits = 0x3F800000 | mantissa;
12+
const f = std.bitcastU32toF32(bits);
13+
return f - 1;
14+
});
1515

1616
return {
17-
seed: (value: number) => {
18-
'use gpu';
19-
seed.$ = d.u32(value * std.pow(32, 3));
20-
},
2117
seed2: (value: d.v2f) => {
2218
'use gpu';
2319
seed.$ = d.u32(value.x * std.pow(32, 3) + value.y * std.pow(32, 2));

packages/typegpu-noise/src/generator.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import * as d from 'typegpu/data';
33
import { add, cos, dot, fract } from 'typegpu/std';
44

55
export interface StatefulGenerator {
6-
seed: TgpuFn<(seed: d.F32) => d.Void> | ((seed: number) => void);
7-
seed2?: TgpuFn<(seed: d.Vec2f) => d.Void> | ((seed: d.v2f) => void);
8-
seed3?: TgpuFn<(seed: d.Vec3f) => d.Void> | ((seed: d.v3f) => void);
9-
seed4?: TgpuFn<(seed: d.Vec4f) => d.Void> | ((seed: d.v4f) => void);
10-
sample: TgpuFn<() => d.F32> | (() => number);
6+
seed?: (seed: number) => void;
7+
seed2?: (seed: d.v2f) => void;
8+
seed3?: (seed: d.v3f) => void;
9+
seed4?: (seed: d.v4f) => void;
10+
sample: () => number;
1111
}
1212

1313
export const randomGeneratorShell: TgpuFnShell<[], d.F32> = tgpu.fn([], d.f32);
@@ -21,28 +21,28 @@ export const BPETER: StatefulGenerator = (() => {
2121

2222
return {
2323
seed: tgpu.fn([d.f32])((value) => {
24-
seed.value = d.vec2f(value, 0);
24+
seed.$ = d.vec2f(value, 0);
2525
}),
2626

2727
seed2: tgpu.fn([d.vec2f])((value) => {
28-
seed.value = d.vec2f(value);
28+
seed.$ = d.vec2f(value);
2929
}),
3030

3131
seed3: tgpu.fn([d.vec3f])((value) => {
32-
seed.value = add(value.xy, d.vec2f(value.z));
32+
seed.$ = add(value.xy, d.vec2f(value.z));
3333
}),
3434

3535
seed4: tgpu.fn([d.vec4f])((value) => {
36-
seed.value = add(value.xy, value.zw);
36+
seed.$ = add(value.xy, value.zw);
3737
}),
3838

3939
sample: randomGeneratorShell(() => {
4040
'use gpu';
41-
const a = dot(seed.value, d.vec2f(23.14077926, 232.61690225));
42-
const b = dot(seed.value, d.vec2f(54.47856553, 345.84153136));
43-
seed.value.x = fract(cos(a) * 136.8168);
44-
seed.value.y = fract(cos(b) * 534.7645);
45-
return seed.value.y;
41+
const a = dot(seed.$, d.vec2f(23.14077926, 232.61690225));
42+
const b = dot(seed.$, d.vec2f(54.47856553, 345.84153136));
43+
seed.$.x = fract(cos(a) * 136.8168);
44+
seed.$.y = fract(cos(b) * 534.7645);
45+
return seed.$.y;
4646
}),
4747
};
4848
})();

0 commit comments

Comments
 (0)