Skip to content

Commit 61ab04f

Browse files
piacchoiwoplaza
authored andcommitted
feat(@typegpu/react): Implement useUniformValue hook (#1694)
1 parent f417740 commit 61ab04f

File tree

4 files changed

+70
-15
lines changed

4 files changed

+70
-15
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<div id='example-app'></div>
1+
<div id="example-app"></div>

apps/typegpu-docs/src/content/examples/react/triangle/index.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1-
import { vec4f } from 'typegpu/data';
2-
import { useRender } from '@typegpu/react';
1+
import * as d from 'typegpu/data';
2+
import { useFrame, useRender, useUniformValue } from '@typegpu/react';
3+
import { hsvToRgb } from '@typegpu/color';
34

45
function App() {
6+
const time = useUniformValue(d.f32, 0);
7+
8+
useFrame(() => {
9+
time.value = performance.now() / 1000;
10+
});
11+
512
const { ref } = useRender({
6-
fragment: ({ uv }) => {
13+
fragment: () => {
714
'kernel';
8-
return vec4f(uv.x, uv.y, 1, 1);
15+
const t = time.$;
16+
const rgb = hsvToRgb(d.vec3f(t * 0.5, 1, 1));
17+
return d.vec4f(rgb, 1);
918
},
1019
});
1120

12-
// TODO: Provide a time variable to the shader with useUniformValue
13-
// TODO: Make the gradient shift colors over time using hsvToRgb from @typegpu/color
14-
1521
return (
1622
<main>
1723
<canvas ref={ref} width='256' height='256' />
@@ -28,7 +34,7 @@ const reactRoot = createRoot(
2834
reactRoot.render(<App />);
2935

3036
export function onCleanup() {
31-
reactRoot.unmount();
37+
setTimeout(() => reactRoot.unmount(), 0);
3238
}
3339

3440
// #endregion

apps/typegpu-docs/vitest.config.mts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createJiti } from 'jiti';
2-
import { defineConfig } from 'vitest/config';
2+
import { defineConfig, type Plugin } from 'vitest/config';
33
import { imagetools } from 'vite-imagetools';
44
import type TypeGPUPlugin from 'unplugin-typegpu/vite';
55

@@ -13,7 +13,7 @@ export default defineConfig({
1313
plugins: [
1414
typegpu({ include: [/\.m?[jt]sx?/] }),
1515
/** @type {any} */ imagetools(),
16-
],
16+
] as Plugin[],
1717
server: {
1818
proxy: {
1919
'/TypeGPU': {
Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,62 @@
11
import type * as d from 'typegpu/data';
2+
import { useRoot } from './root-context.tsx';
3+
import { useEffect, useMemo, useRef, useState } from 'react';
4+
import type { ValidateUniformSchema } from 'typegpu';
25

36
interface UniformValue<TSchema, TValue extends d.Infer<TSchema>> {
47
schema: TSchema;
5-
value: TValue;
8+
value: TValue | undefined;
9+
readonly $: d.InferGPU<TSchema>;
610
}
711

8-
export function useUniformValue<TSchema, TValue extends d.Infer<TSchema>>(
9-
schema: d.AnyWgslData,
12+
export function useUniformValue<
13+
TSchema extends d.AnyWgslData,
14+
TValue extends d.Infer<TSchema>,
15+
>(
16+
schema: ValidateUniformSchema<TSchema>,
1017
initialValue?: TValue | undefined,
1118
): UniformValue<TSchema, TValue> {
12-
// TODO: Implement
19+
const root = useRoot();
20+
21+
const [uniformBuffer] = useState(() => {
22+
return root.createUniform(
23+
schema,
24+
initialValue,
25+
);
26+
});
27+
28+
const cleanupRef = useRef<ReturnType<typeof setTimeout> | null>(null);
29+
useEffect(() => {
30+
if (cleanupRef.current) {
31+
clearTimeout(cleanupRef.current);
32+
}
33+
34+
return () => {
35+
cleanupRef.current = setTimeout(() => {
36+
uniformBuffer.buffer.destroy();
37+
}, 200);
38+
};
39+
}, [uniformBuffer]);
40+
41+
// biome-ignore lint/correctness/useExhaustiveDependencies: This value needs to be stable
42+
const uniformValue = useMemo(() => {
43+
let currentValue = initialValue;
44+
return {
45+
schema,
46+
get value() {
47+
return currentValue;
48+
},
49+
set value(newValue: TValue | undefined) {
50+
currentValue = newValue;
51+
if (newValue !== undefined) {
52+
uniformBuffer.write(newValue);
53+
}
54+
},
55+
get $() {
56+
return uniformBuffer.$;
57+
},
58+
};
59+
}, []);
60+
61+
return uniformValue as UniformValue<TSchema, TValue>;
1362
}

0 commit comments

Comments
 (0)