[v11] Stories for the 9 converted WebGPU components that have none
The rule this issue now follows
A story for an unconverted component is not a story task — it is part of that component's conversion.
Writing a story against a component that was never really ported produces a red story and no new information: we already know it does not work. So this issue covers only components whose WebGPU implementation is finished and believed ready. For everything else, "write the story" has been moved into the conversion/fix issue for that component, as an acceptance criterion.
Scope: 9 components
src/webgpu/ has 29 components. 17 are already rendered by some story (usually a legacy/core story that routes through PlatformSwitch). Of the 12 that are not, three have been moved out — see the table below. These nine remain:
| Component | Path |
|---|---|
ContactShadows |
src/webgpu/Staging/ContactShadows |
ConvolutionMaterial |
src/webgpu/Materials/ConvolutionMaterial |
DiscardMaterial |
src/webgpu/Materials/DiscardMaterial |
GradientTexture |
src/webgpu/Textures/GradientTexture |
Image |
src/webgpu/UI/Image |
Outlines |
src/webgpu/Effects/Outlines |
Trail |
src/webgpu/Effects/Trail |
Wireframe |
src/webgpu/Geometry/Wireframe |
WireframeMaterial |
src/webgpu/Materials/WireframeMaterial |
One caveat carried in the source rather than in an issue: ContactShadows' color prop is documented as non-functional (ContactShadows.tsx:8-12 — MultiplyBlending on white only supports grayscale). The story should exercise color anyway and record the result; if it is genuinely dead, that is a stub candidate for #2803.
Moved into the conversion issues
| Component | Now tracked in | Why |
|---|---|---|
BlurPass |
#2811 | Still the WebGL implementation. Imports WebGLRenderer/WebGLRenderTarget, not exported from the /webgpu barrel. Nothing to write a story against. |
SpotLightMaterial |
#2663 | "legacy works, webgpu is problematic" — the story is how that gets confirmed fixed. |
BakeShadows |
#2665 | See the note there: it is 13 lines with no shader, and it is not clear it needs a webgpu/ copy at all. |
Also folded in, for components with no src/webgpu/ implementation at all: Text → #2588/#2658, MeshDiscardMaterial → #2660.
Pattern
src/webgpu/Staging/AccumulativeShadows/AccumulativeShadows.stories.tsx is the worked example. The two things that are easy to get wrong:
limitedTo="webgpu"is what actually pins the renderer, notrenderer={context.globals.renderer}.SetupcomputesisLegacy = limitedTo === 'legacy' || (limitedTo === null && renderer === 'legacy'), so withoutlimitedTothe toolbar can toggle asrc/webgpu/component onto the WebGL renderer and it will fail. Tag the storywebgpuOnlytoo.- A story that references a component's ref type will fail typecheck if that type is not exported.
AccumulativeShadowshad exactly this — TS4023/TS4082 out of declaration emit, becausedeclaration: trueis repo-wide. Export the interface; do not annotate around it.
Prefer primitives over a GLTF in the scene. If a story renders nothing, the cause should unambiguously be the component and not an asset that failed to load.
Verification, and its limit
npx vitest run --config vite.config.mts # renders every story headlesslyThis does not prove WebGPU works. The headless runner has no navigator.gpu, so WebGPURenderer silently falls back to WebGLBackend (three/src/renderers/common/Renderer.js, getFallback). Stars is confirmed to render nothing under real WebGPU (#2786) and it passes this suite. A green run means the component mounts and does not throw. Actual WebGPU verification is a browser with a GPU, and that is Dennis.
Acceptance
Each of the nine has a <Name>.stories.tsx beside it that mounts under limitedTo="webgpu", and either renders or has an issue explaining why not. Do not fix broken components here — record and open. Fixing is #2803.
Source: pmndrs/drei