From 4c0c2de4982fcda08a9189560c88d877f9f8e95c Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Mon, 3 Aug 2026 14:53:16 +0200 Subject: [PATCH] docs: Fix "Vaporrave" on WebKit (vec3f->vec4f) --- .../src/examples/simple/vaporrave/scene.ts | 18 +++++++++++++----- .../individual-example-tests/vaporrave.test.ts | 12 ++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/apps/typegpu-docs/src/examples/simple/vaporrave/scene.ts b/apps/typegpu-docs/src/examples/simple/vaporrave/scene.ts index 8a6b54a4be..7de2e21007 100644 --- a/apps/typegpu-docs/src/examples/simple/vaporrave/scene.ts +++ b/apps/typegpu-docs/src/examples/simple/vaporrave/scene.ts @@ -17,7 +17,10 @@ export async function setupScene(root: TgpuRoot, context: GPUCanvasContext) { const sphereAngleUniform = root.createUniform(d.f32); const glowIntensityUniform = root.createUniform(d.f32, c.INITIAL_GLOW_INTENSITY); const resolutionUniform = root.createUniform(d.vec2f); - const sphereColorUniform = root.createUniform(d.vec3f, c.initialSphereColor); + // NOTE: Padded to vec4f on purpose. A bare vec3f uniform triggers a WebKit + // WGSL->Metal codegen bug on iOS/Safari (missing `__unpack` overload for a + // `packed_float3` uniform), which fails shader compilation. + const sphereColorUniform = root.createUniform(d.vec4f, d.vec4f(c.initialSphereColor, 1)); let floorSpeed = 0.25; let sphereSpeed = 1; @@ -35,7 +38,7 @@ export async function setupScene(root: TgpuRoot, context: GPUCanvasContext) { dist: sdPlane(p, c.planeOrthonormal, c.PLANE_OFFSET), color: floorPatternSlot.$(p.xz, floorAngleUniform.$), }); - const sphere = getSphere(p, sphereColorUniform.$, c.sphereCenter, sphereAngleUniform.$); + const sphere = getSphere(p, sphereColorUniform.$.rgb, c.sphereCenter, sphereAngleUniform.$); return rayUnion(floor, sphere); }); @@ -53,9 +56,14 @@ export async function setupScene(root: TgpuRoot, context: GPUCanvasContext) { for (let i = 0; i < c.MAX_STEPS; i++) { const p = rd * distOrigin + ro; const scene = getSceneRay(p); - const sphereDist = getSphere(p, sphereColorUniform.$, c.sphereCenter, sphereAngleUniform.$); + const sphereDist = getSphere( + p, + sphereColorUniform.$.rgb, + c.sphereCenter, + sphereAngleUniform.$, + ); - glow += d.vec3f(sphereColorUniform.$) * std.exp(-sphereDist.dist); + glow += sphereColorUniform.$.rgb * std.exp(-sphereDist.dist); distOrigin += scene.dist; @@ -166,7 +174,7 @@ export async function setupScene(root: TgpuRoot, context: GPUCanvasContext) { sphereSpeed = value; }, set sphereColor(value: d.v3f) { - sphereColorUniform.write(value); + sphereColorUniform.write(d.vec4f(value, 1)); }, set floorPattern(value: 'grid' | 'circles') { renderPipeline = root diff --git a/apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts b/apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts index a9a5623a9a..dde8afef8e 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/vaporrave.test.ts @@ -104,6 +104,8 @@ describe('vaporrave example', () => { return (dot(point, normal) + height); } + @group(0) @binding(2) var sphereColorUniform: vec4f; + fn rotateAroundZ(angle: f32) -> mat3x3f { return mat3x3f(vec3f(cos(angle), sin(angle), 0f), vec3f(-(sin(angle)), cos(angle), 0f), vec3f(0, 0, 1)); } @@ -116,7 +118,7 @@ describe('vaporrave example', () => { return (length(point) - radius); } - @group(0) @binding(2) var memoryBuffer: array; + @group(0) @binding(3) var memoryBuffer: array; fn getJunctionGradient(pos: vec3i) -> vec3f { let size_i = vec3i(7); @@ -171,8 +173,6 @@ describe('vaporrave example', () => { return Ray(sphereColor, (rawDist + noise)); } - @group(0) @binding(3) var sphereColorUniform: vec3f; - @group(0) @binding(4) var sphereAngleUniform: f32; fn rayUnion(a: Ray, b: Ray) -> Ray { @@ -181,7 +181,7 @@ describe('vaporrave example', () => { fn getSceneRay(p: vec3f) -> Ray { let floor_1 = Ray(circles(p.xz, floorAngleUniform), sdPlane(p, vec3f(0, 1, 0), 1f)); - let sphere = getSphere(p, sphereColorUniform, vec3f(0, 6, 12), sphereAngleUniform); + let sphere = getSphere(p, sphereColorUniform.rgb, vec3f(0, 6, 12), sphereAngleUniform); return rayUnion(floor_1, sphere); } @@ -197,8 +197,8 @@ describe('vaporrave example', () => { for (var i = 0; (i < 1000i); i++) { let p = ((rd * distOrigin) + ro); let scene = getSceneRay(p); - let sphereDist = getSphere(p, sphereColorUniform, vec3f(0, 6, 12), sphereAngleUniform); - glow += (sphereColorUniform * exp(-(sphereDist.dist))); + let sphereDist = getSphere(p, sphereColorUniform.rgb, vec3f(0, 6, 12), sphereAngleUniform); + glow += (sphereColorUniform.rgb * exp(-(sphereDist.dist))); distOrigin += scene.dist; if ((distOrigin > 19f)) { result.dist = 19f;