perf(web): share card texture via shader UV transform
Move the card sprite repeat/offset out of per-card texture clones and into a uniform injected into the material shader. Cards now share the deck sheet (one GPU upload), the shader, and the geometry, with only per-card material uniforms differing, so navigating a deck no longer re-uploads the sheet on every step.
This commit is contained in:
+25
-1
@@ -299,4 +299,28 @@ flips.
|
||||
|
||||
**Alternatives considered:** Reporting only a hit and silently dropping
|
||||
misses. Rejected — a command that needs to react to a wrong tap has no way to
|
||||
do so. World-space trigger points. Rejected — they break when the part moves.
|
||||
do so. World-space trigger points. Rejected — they break when the part moves.
|
||||
|
||||
## D21 — Card sprite UVs live in the material shader, not the texture
|
||||
|
||||
**Decision:** A card's sprite cell is selected by a repeat/offset injected into
|
||||
the material's shader (`cardMaterial.ts` extends `MeshStandardMaterial` via
|
||||
`onBeforeCompile`) rather than by cloning the texture and setting its
|
||||
`repeat`/`offset`.
|
||||
|
||||
**Context:** Cards in a deck share one sprite sheet (drei caches the texture by
|
||||
URL), but each card samples a different cell. The previous approach cloned the
|
||||
texture per card to set its UVs; each clone gets its own WebGL texture binding,
|
||||
so navigating a deck re-uploaded the whole sheet on every step. Moving the
|
||||
transform into a per-material uniform lets cards share the texture (one GPU
|
||||
upload), the shader (identical injected source → one program), and the geometry,
|
||||
with only the material uniforms differing.
|
||||
|
||||
We inject our own uniform rather than setting `texture.repeat`/`offset` because
|
||||
three r185 derives map UVs from a `mapTransform` matrix refreshed from
|
||||
`map.matrix` every frame, which would overwrite a per-material transform set on
|
||||
the shared texture.
|
||||
|
||||
**Alternatives considered:** Cloning the texture per card (previous approach).
|
||||
Rejected — re-uploads the sheet per card. A module-level cache of per-card
|
||||
clones. Rejected — still one upload per unique card instead of one per sheet.
|
||||
@@ -81,9 +81,10 @@ view and the full-setup view.
|
||||
`textureUrl + color + roughness`. drei already caches textures by URL
|
||||
globally, so sharing the material on top avoids per-object material
|
||||
allocation for tiles/tokens with the same image.
|
||||
- **Cards are the exception:** each card clones its texture for sprite UVs, so
|
||||
its face material cannot be shared — but its geometry still can (same card
|
||||
size).
|
||||
- **Cards:** the face/back textures are shared (drei caches them by URL) and
|
||||
the sprite cell is selected via a per-material UV transform injected into the
|
||||
shader (`cardMaterial.ts`), so cards share texture, shader, and geometry —
|
||||
only the material uniforms differ. Materials are cached per card id + tint.
|
||||
- Dispose shared resources on page unmount, or accept a module-level cache for
|
||||
the session (see Open decisions).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user