UNPKG

typegpu

Version:

A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.

88 lines (87 loc) 2.15 kB
import { $gpuCallable, $internal, $resolve } from "../../shared/symbols.js"; import { setName } from "../../shared/meta.js"; import { withValue } from "../../data/snippet.js"; /** * The result of calling `tgpu.unroll(...)`. The code responsible for * generating shader code can check if the value of a snippet is * an instance of `UnrollableIterable`, and act accordingly. */ export class UnrollableIterable { [$internal] = true; snippet; constructor(snippet) { this.snippet = snippet; } [$resolve](ctx) { return ctx.resolveSnippet(this.snippet); } } /** * Marks an iterable to be unrolled by the shader generator when used in a for loop. * * @example * ```ts * const neighborOffsets = [d.vec2i(0, 1), d.vec2i(0, -1), d.vec2i(1, 0), d.vec2i(-1, 0)]; * * // Unrolls into 4 blocks of code, one for each offset. * for (const offset of tgpu.unroll(neighborOffsets)) { * // ... * } * ``` * * If you'd like to unroll over a range of numbers, use `tgpu.unroll(std.range(n))`. * * @example * ```ts * // (...) * const FBM_OCTAVES = 3; * * function fbm(pos: d.v3f): number { * 'use gpu'; * let sum = d.f32(); * * // i = 0, 1, 2 * for (const i of tgpu.unroll(std.range(FBM_OCTAVES))) { * sum += * noise3d(pos * (CLOUD_FREQUENCY * FBM_LACUNARITY ** i)) * * (CLOUD_AMPLITUDE * FBM_PERSISTENCE ** i); * } * * return sum; * } * * ``` * * Generates: * * ```wgsl * // (...) * * fn fbm(pos: vec3f) -> f32 { * var sum = 0f; * // unrolled iteration #0 * sum += noise3d(pos * 1.4f) * 1f; * // unrolled iteration #1 * sum += noise3d(pos * 2.8f) * 0.5f; * // unrolled iteration #2 * sum += noise3d(pos * 5.6f) * 0.25f; * // --- * return sum; * } * ``` */ export const unroll = (() => { function jsImpl(iterable) { return iterable; } const impl = jsImpl; setName(impl, 'unroll'); impl.toString = () => 'unroll'; impl[$internal] = true; impl[$gpuCallable] = { call(_ctx, [value]) { return withValue(new UnrollableIterable(value), value); }, }; return impl; })();