dreative 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -27
- package/dist/cli/audit.js +206 -0
- package/dist/cli/audit.test.js +79 -0
- package/dist/cli/docsCheck.js +163 -0
- package/dist/cli/docsCheck.test.js +8 -0
- package/dist/cli/index.js +45 -9
- package/dist/server/preview.js +73 -73
- package/dist/server/store.js +11 -0
- package/dist/shared/artifacts.js +162 -0
- package/dist/shared/design.js +42 -22
- package/dist/shared/ruleSystem.js +130 -0
- package/dist/shared/ruleSystem.test.js +187 -0
- package/dist/shared/skillSystem.js +173 -0
- package/dist/shared/skillSystem.test.js +110 -0
- package/dist/ui/assets/{index--vztc_MR.js → index-CKwmbx2j.js} +13 -13
- package/dist/ui/index.html +12 -12
- package/package.json +5 -3
- package/skill/dreative/DESIGN.md +121 -93
- package/skill/dreative/PLAN.md +229 -92
- package/skill/dreative/SKILL.md +218 -137
- package/skill/dreative/frameworks/nextjs.md +13 -0
- package/skill/dreative/frameworks/react-vite.md +12 -0
- package/skill/dreative/frameworks/styling.md +14 -0
- package/skill/dreative/frameworks/sveltekit.md +10 -0
- package/skill/dreative/frameworks/vue-nuxt.md +12 -0
- package/skill/dreative/recipes/3d-recipes.md +44 -0
- package/skill/dreative/recipes/cinematic-recipes.md +19 -0
- package/skill/dreative/recipes/immersive-recipes.md +18 -0
- package/skill/dreative/recipes/media-recipes.md +60 -0
- package/skill/dreative/recipes/motion-recipes.md +44 -0
- package/skill/dreative/references/ARTIFACTS.md +180 -0
- package/skill/dreative/references/REFLEX_FONTS.json +44 -0
- package/skill/dreative/references/RULES.json +186 -0
- package/skill/dreative/references/SKILL_CONTRACT.md +30 -0
- package/skill/dreative/references/TIERS.md +42 -0
- package/skill/dreative/schemas/plan.schema.json +241 -0
- package/skill/dreative/schemas/verify.schema.json +61 -0
- package/skill/dreative/skills/3d.md +94 -267
- package/skill/dreative/skills/cinematic.md +56 -232
- package/skill/dreative/skills/experimental.md +108 -95
- package/skill/dreative/skills/immersive.md +61 -223
- package/skill/dreative/skills/interaction.md +9 -1
- package/skill/dreative/skills/media.md +135 -564
- package/skill/dreative/skills/mobile.md +128 -117
- package/skill/dreative/skills/motion.md +89 -256
- package/skill/dreative/skills/refined.md +116 -102
- package/skill/dreative/skills/ux.md +155 -144
- package/dist/server/ai.js +0 -177
|
@@ -1,267 +1,94 @@
|
|
|
1
|
-
# Dreative Specialist Skill — 3D, WebGL & Shaders
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`metalness` chosen from the real object; `MeshTransmissionMaterial` for glass
|
|
96
|
-
(expensive — one object max). Untextured default-gray = unfinished.
|
|
97
|
-
|
|
98
|
-
## 3. Models
|
|
99
|
-
|
|
100
|
-
- glTF/GLB only, Draco or Meshopt compressed (`gltf-transform optimize in.glb
|
|
101
|
-
out.glb --compress draco`). Budget: hero model ≤ 2-3 MB, ≤ 100k triangles.
|
|
102
|
-
- `useGLTF.preload(url)`; wrap in `<Suspense>` with a poster (not a spinner).
|
|
103
|
-
|
|
104
|
-
**No model available? Walk the realism ladder — in this order:**
|
|
105
|
-
|
|
106
|
-
1. **Real GLB** the repo/user already has, or one the user can supply.
|
|
107
|
-
2. **Image-billboard prop (the DEFAULT for any real-world subject).** Get
|
|
108
|
-
the object as a transparent-background cutout — generate it if an image
|
|
109
|
-
tool exists (media.md §1.5 pipeline — verify the alpha is real); with NO
|
|
110
|
-
image-gen tool, source a real photo instead (a verified stock/CDN photo of
|
|
111
|
-
the subject, matted to transparency with rembg/sharp/ImageMagick if
|
|
112
|
-
available, or a photo whose own background already matches the scene so no
|
|
113
|
-
matte is needed). Put it on a plane in the scene
|
|
114
|
-
(`transparent`, `alphaTest ~0.5`, `toneMapped: false` if pre-graded), and
|
|
115
|
-
sell the depth with scene means: parallax against other layers, damped
|
|
116
|
-
mouse/scroll rotation of ±5-10° (a flat card barely rotating reads as
|
|
117
|
-
dimensional), scroll-linked scale/drift, a soft contact shadow, and a rim
|
|
118
|
-
of scene light via a subtle additive duplicate or shader fresnel. Generate
|
|
119
|
-
2-3 angles of the same subject and crossfade/swap by scroll chapter for a
|
|
120
|
-
pseudo-orbit. This looks photoreal because it IS a photo — it beats coded
|
|
121
|
-
geometry for any organic or textured subject, every time.
|
|
122
|
-
3. **Coded geometry — abstract SUPPORTING forms ONLY.** Primitives/extrusions
|
|
123
|
-
are allowed for geometry that is genuinely abstract or hard-surface-simple
|
|
124
|
-
(shader planes, ribbons, crystals, grids, a device from rounded boxes with
|
|
125
|
-
an `Html` screen) — but only in a SUPPORTING role: background surface,
|
|
126
|
-
particle field, atmosphere. **An abstract coded form may never be the
|
|
127
|
-
promoted signature object.** A floating sphere/orb/blob/torus — however
|
|
128
|
-
shader-textured, however poetic its name ("eclipse", "core", "monolith") —
|
|
129
|
-
reads to a visitor as "a stupid orb"; the signature 3D element must be a
|
|
130
|
-
RECOGNIZABLE subject a stranger names correctly: a rung-1 GLB, a rung-2
|
|
131
|
-
generated/sourced cutout billboard, or a textured mesh of a nameable thing.
|
|
132
|
-
If image-gen exists, the signature defaults to rung 2 — generate the subject
|
|
133
|
-
as a transparent cutout and sell the depth with scene means. Compositing a
|
|
134
|
-
translucent shader sphere ON TOP of a photograph is the canonical form of
|
|
135
|
-
this failure and is a ship-blocker, not a signature.
|
|
136
|
-
**Modeling an organic or richly-textured real object
|
|
137
|
-
(food, beans, plants, fabric, skin, liquid, wood…) from primitives is
|
|
138
|
-
BANNED as a visible element** — an untextured lathe/sphere "coffee bean"
|
|
139
|
-
reads as a red blob, not a bean; that failure is worse than no 3D. If a
|
|
140
|
-
realistic subject must be 3D and no GLB exists, use rung 2.
|
|
141
|
-
4. **Rung 2 unreachable does NOT unlock rung 3.** The organic-subject ban is
|
|
142
|
-
unconditional — it does not relax because the environment has no image-gen
|
|
143
|
-
tool or the cutout failed. If neither a GLB nor any photo source (rung 2's
|
|
144
|
-
no-tool path) exists, the organic 3D element is CUT: replace it with an
|
|
145
|
-
abstract signature (shader plane, particles, ribbons — rung-3-legal forms)
|
|
146
|
-
or with the sourced photography itself as a scroll-reactive media plane
|
|
147
|
-
(media.md §3), and tell the user what asset would unlock the real thing.
|
|
148
|
-
(The rung-3 supporting-only restriction still applies to that replacement:
|
|
149
|
-
it demotes the moment to atmosphere; it does not mint a new hero orb.)
|
|
150
|
-
"We had no tools, so I coded the bean" is the exact failure this rung
|
|
151
|
-
exists to stop.
|
|
152
|
-
|
|
153
|
-
Any coded mesh that DOES ship must carry a real material identity per
|
|
154
|
-
experimental.md §1 — and texture maps can be GENERATED: prompt the image tool
|
|
155
|
-
for a tileable albedo/detail texture ("seamless tileable dark roast coffee-bean
|
|
156
|
-
surface texture, matte, high detail"), load it as `map` + drive `bumpMap`/
|
|
157
|
-
`roughnessMap` from it. With no image tool, source a tileable texture (a real
|
|
158
|
-
photo crop, a CC0 texture CDN) or build material identity in a shader
|
|
159
|
-
(procedural noise-driven roughness/normal, fresnel rim, environment
|
|
160
|
-
reflection). A flat-color `meshStandardMaterial` on a visible custom mesh is a
|
|
161
|
-
ship-blocker, not a style — and "no image tool" is not an exemption; if no
|
|
162
|
-
texture path exists, the mesh doesn't ship.
|
|
163
|
-
|
|
164
|
-
**The subject test is what the element REPRESENTS, not what the code names
|
|
165
|
-
it.** If the plan, copy, aria-label, or your own verify prose describes the
|
|
166
|
-
mesh as a real thing ("roast core… coffee bean", "the bottle", "a leaf"), it
|
|
167
|
-
IS an organic/real subject and the ban applies — renaming a sphere-bean to an
|
|
168
|
-
"abstract signature" while shaping and coloring it as a bean is the exact
|
|
169
|
-
rationalization this section exists to stop. And texture is MECHANICAL, not
|
|
170
|
-
rhetorical: a shipped custom mesh passes only if its material provably carries
|
|
171
|
-
a `map`/`normalMap`/`roughnessMap` texture or a custom shader — point to the
|
|
172
|
-
line in verify.md. `meshPhysicalMaterial` with a flat `color` plus clearcoat/
|
|
173
|
-
roughness numbers is untextured, whatever the verify prose calls it.
|
|
174
|
-
|
|
175
|
-
## 4. Shaders (the highest-leverage 100 lines)
|
|
176
|
-
|
|
177
|
-
A fullscreen/plane fragment shader is the cheapest way to a signature visual:
|
|
178
|
-
animated gradient meshes, flowfields, displacement on hover, image transitions.
|
|
179
|
-
|
|
180
|
-
- Structure: `shaderMaterial` (drei) with `uTime`, `uMouse`, `uResolution`,
|
|
181
|
-
palette colors as `uColorA/B/C` uniforms fed FROM the page palette.
|
|
182
|
-
- Vocabulary: fbm/simplex noise for organic movement (inline a noise fn; don't
|
|
183
|
-
import a library for it), `smoothstep` for banding-free ramps, domain warping
|
|
184
|
-
(`noise(p + noise(p))`) for the expensive look, `mix()` between palette colors
|
|
185
|
-
only — never rainbow hue-rotation.
|
|
186
|
-
- Displace vertices in the vertex shader for cloth/terrain/blob effects; compute
|
|
187
|
-
normals or fake lighting with the noise derivative.
|
|
188
|
-
- Animate `uTime` at 0.05-0.2 speed; slow reads as premium, fast as screensaver.
|
|
189
|
-
- Image effects: sample two textures + a noise mask for transitions; barrel/flow
|
|
190
|
-
distortion on scroll velocity for editorial galleries.
|
|
191
|
-
|
|
192
|
-
## 4.5 Media in the scene (images & video as textures)
|
|
193
|
-
|
|
194
|
-
The other half of shader craft: real page media rendered THROUGH WebGL so
|
|
195
|
-
effects can touch it (the unseen.co gallery mechanic — full pattern in
|
|
196
|
-
`skills/media.md` §3):
|
|
197
|
-
|
|
198
|
-
- **DOM-synced media planes**: the page's `<img>`/`<video>` elements stay in
|
|
199
|
-
the DOM (a11y/layout/fallback, `opacity: 0` never `display:none`) while
|
|
200
|
-
textured planes copy their `getBoundingClientRect()` per rAF (lerped).
|
|
201
|
-
One scene owns ALL planes — never a canvas per image.
|
|
202
|
-
- **Video textures**: `new THREE.VideoTexture(videoEl)` with the element
|
|
203
|
-
`muted playsinline` and playing; `texture.colorSpace = SRGBColorSpace`;
|
|
204
|
-
generated seamless loops (media.md §1) make the best texture sources —
|
|
205
|
-
a pre-rendered loop as a texture often beats a live sim for cost.
|
|
206
|
-
- Effects on media planes: hover ripple/lens (damped `uMouse` + radial UV
|
|
207
|
-
displacement), velocity stretch + RGB split (clamped, damped decay),
|
|
208
|
-
noise-mask dissolves between textures (§4), subtle vertex curvature for
|
|
209
|
-
the floating-paper look.
|
|
210
|
-
- Failure path is wired, not theoretical: WebGL missing/lost or
|
|
211
|
-
reduced-motion → un-hide the DOM media (`opacity: 1`). Verify it fires.
|
|
212
|
-
|
|
213
|
-
## 5. Particles and points
|
|
214
|
-
|
|
215
|
-
Points/instancing, never meshes-per-particle: `<Points>` + `BufferAttribute`
|
|
216
|
-
positions animated in a shader (`uTime` in the vertex shader), or
|
|
217
|
-
`<Instances>`/`InstancedMesh` for repeated geometry (≤ ~10k instances). Counts:
|
|
218
|
-
2-5k points desktop, halve on mobile. Particle color from the page palette at 1-2
|
|
219
|
-
hues; size attenuation on; additive blending only on dark surfaces.
|
|
220
|
-
|
|
221
|
-
## 6. Scroll- and layout-integration
|
|
222
|
-
|
|
223
|
-
- Canvas placement: either a bounded block IN the layout (preferred — it composes
|
|
224
|
-
with the grid) or a full-bleed fixed background with content scrolling over.
|
|
225
|
-
Full-page persistent canvases with DOM scrolled on top: use drei
|
|
226
|
-
`ScrollControls` + `<Scroll html>` so 3D and DOM share one scroll.
|
|
227
|
-
- Scroll-linked 3D: map scroll progress (Motion `useScroll` / ScrollTrigger /
|
|
228
|
-
drei `useScroll`) to camera position along a path or object rotation — damped
|
|
229
|
-
(`damp3`, `dampE`), never raw-set per frame.
|
|
230
|
-
- DOM/3D registration (labels pinned to model parts): drei `<Html transform
|
|
231
|
-
occlude>`; keep text as real DOM for accessibility, never texture-baked type.
|
|
232
|
-
- The block's `data-dreative-id` goes on the wrapper div around the Canvas.
|
|
233
|
-
|
|
234
|
-
## 7. Performance & fallbacks (ship-blockers)
|
|
235
|
-
|
|
236
|
-
- `<Canvas dpr={[1, 2]}>` (cap device pixel ratio), `frameloop="demand"` +
|
|
237
|
-
`invalidate()` for static-until-interacted scenes; pause the loop when the
|
|
238
|
-
canvas leaves the viewport (IntersectionObserver) and on `document.hidden`.
|
|
239
|
-
- One `useFrame` per concern; no allocations inside it (reuse vectors created
|
|
240
|
-
outside). Dispose on unmount (R3F handles it; imperative three must
|
|
241
|
-
`dispose()` geometries/materials/textures).
|
|
242
|
-
- Mobile: halve particle counts, drop post-processing, consider a poster image
|
|
243
|
-
below 768px — a janky 3D hero is worse than none.
|
|
244
|
-
- `prefers-reduced-motion`: stop idle rotation/particle drift; render one static
|
|
245
|
-
well-lit frame (`frameloop="demand"` makes this free).
|
|
246
|
-
- WebGL unavailable/context-lost → the poster fallback, never a blank block.
|
|
247
|
-
- Keyboard/screen-reader: canvas gets `role="img"` + `aria-label`; any 3D-driven
|
|
248
|
-
interaction has a DOM equivalent.
|
|
249
|
-
|
|
250
|
-
## 8. Recipes
|
|
251
|
-
|
|
252
|
-
- **Product hero**: GLB + `Environment` + key light + `ContactShadows`, `Float`
|
|
253
|
-
idle, damped mouse parallax, scroll scrubs a 90° orbit. Poster until loaded.
|
|
254
|
-
**Variant trick (ciaoenergy.com):** ONE model, N variants — swap only the
|
|
255
|
-
label/albedo texture (`TextureLoader`, one AVIF per flavor/colorway) on the
|
|
256
|
-
same geometry as the user browses variants, and pair each with a
|
|
257
|
-
pre-rendered background video loop. Photoreal product-line 3D for the cost
|
|
258
|
-
of one GLB. The label texture can be GENERATED (image-gen at the label's
|
|
259
|
-
unwrapped aspect) when no real artwork exists.
|
|
260
|
-
- **Gradient-mesh hero background**: one plane, fbm + domain-warp fragment shader
|
|
261
|
-
mixing 3 palette colors, `uTime` 0.08, `uMouse` warps locally. ~120 lines, no
|
|
262
|
-
model, no lighting — the best effort/impact ratio in this file.
|
|
263
|
-
- **Point-cloud globe**: sphere-distributed points, shader-animated shimmer,
|
|
264
|
-
arcs as `TubeGeometry`/fat lines between coords, slow idle rotation, drag to
|
|
265
|
-
spin (damped).
|
|
266
|
-
- **Scroll story**: `ScrollControls pages={4}` + camera on a `CatmullRomCurve3`
|
|
267
|
-
path, DOM copy in `<Scroll html>`, one damped lookAt target per section.
|
|
1
|
+
# Dreative Specialist Skill — 3D, WebGL & Shaders
|
|
2
|
+
|
|
3
|
+
## Contract
|
|
4
|
+
|
|
5
|
+
Follow `../references/SKILL_CONTRACT.md`. Dependencies: `ux`, `mobile`; add
|
|
6
|
+
`motion` when scroll/time drives the scene. Deliver a named spatial purpose,
|
|
7
|
+
asset/material source, staged berth, budgets, semantic/poster fallback, and
|
|
8
|
+
runtime evidence.
|
|
9
|
+
|
|
10
|
+
Load for real spatial subjects, WebGL, three.js/R3F, shaders, particles, globes,
|
|
11
|
+
or a plan-defined dimensional signature. 3D is expensive in bytes, battery, and
|
|
12
|
+
attention; it must serve the subject or concept.
|
|
13
|
+
|
|
14
|
+
## 0. Explore before recipes
|
|
15
|
+
|
|
16
|
+
Record three original brand-native spatial concepts before opening
|
|
17
|
+
`../recipes/3d-recipes.md`. Begin with subject, spatial purpose, recurrence,
|
|
18
|
+
interaction, and berth—not a primitive or shader technique.
|
|
19
|
+
|
|
20
|
+
## 1. Hard gates
|
|
21
|
+
|
|
22
|
+
- **No coded organic subjects (`3d.noCodedOrganic`).** Food, plants, fabric,
|
|
23
|
+
skin, liquid, wood, or other richly textured real objects never ship as crude
|
|
24
|
+
primitives. Use a real GLB, photoreal cutout, sourced photo, or cut the object.
|
|
25
|
+
- WebGL/context loss/loading/low power/mobile/reduced motion always has a real
|
|
26
|
+
poster or DOM fallback (`effects.runtimeFallback`, `motion.reducedMotion`).
|
|
27
|
+
- Canvas and traveling objects never cover content or controls; pointer events
|
|
28
|
+
and keyboard paths remain intact (`spatial.noOcclusion`, `ux.functional`).
|
|
29
|
+
- Text remains semantic DOM, not texture-baked. Content is visible without 3D.
|
|
30
|
+
- Models/textures/materials named as shipped assets exist and are tracked.
|
|
31
|
+
- Verification proves a live context/draw, interaction, performance, and
|
|
32
|
+
fallback behavior with structured evidence.
|
|
33
|
+
|
|
34
|
+
## 2. Award spatial signature
|
|
35
|
+
|
|
36
|
+
`award.spatialSignature` requires one unmistakable dimensional or spatial
|
|
37
|
+
signature with depth, recurrence, input response, and visual dominance on
|
|
38
|
+
desktop and mobile.
|
|
39
|
+
|
|
40
|
+
The proven default is:
|
|
41
|
+
|
|
42
|
+
1. a recognizable real GLB; or
|
|
43
|
+
2. a photoreal transparent cutout billboard staged with parallax, restrained
|
|
44
|
+
rotation, contact shadow, rim light, and—when useful—multiple angles.
|
|
45
|
+
|
|
46
|
+
This default exists because dogfood coded/shader hero objects repeatedly read as
|
|
47
|
+
generic demos. Valid registered alternatives include spatial typography,
|
|
48
|
+
layered photographic depth, a persistent interactive scene instrument, or a
|
|
49
|
+
data-driven spatial structure that meets declared observable criteria.
|
|
50
|
+
|
|
51
|
+
A generic orb, blob, sphere, torus, or untextured coded form remains invalid as
|
|
52
|
+
a signature. `3d.signatureRecognizable` permits a brand-native abstract
|
|
53
|
+
instrument only when it has a nameable function, material identity, recurrence,
|
|
54
|
+
and input response; ambient decoration does not qualify.
|
|
55
|
+
|
|
56
|
+
## 3. Staging and material
|
|
57
|
+
|
|
58
|
+
Every object gets a planned berth: section/lane, space reserved by type/layout,
|
|
59
|
+
crop, light direction, shadow/ground, travel states, and hidden states when no
|
|
60
|
+
safe berth exists. It never floats over other imagery unless genuinely
|
|
61
|
+
composited with matched light and cast/contact shadow.
|
|
62
|
+
|
|
63
|
+
Realism comes from material and light, not geometry count:
|
|
64
|
+
|
|
65
|
+
- environment/IBL plus one coherent key direction;
|
|
66
|
+
- deliberate exposure/color management;
|
|
67
|
+
- contact/cast shadow or defensible weightlessness;
|
|
68
|
+
- texture/normal/roughness or a custom procedural shader for visible coded
|
|
69
|
+
geometry;
|
|
70
|
+
- camera FOV/framing appropriate to the subject;
|
|
71
|
+
- damped input and subtle idle behavior.
|
|
72
|
+
|
|
73
|
+
## 4. Architecture
|
|
74
|
+
|
|
75
|
+
React uses R3F + drei unless the existing stack strongly dictates otherwise;
|
|
76
|
+
one simple shader plane may use OGL/three.js. Lazy-load the whole spatial bundle
|
|
77
|
+
outside the critical path. One scene owns related planes/objects. Reuse vectors
|
|
78
|
+
and buffers; avoid allocations in render loops.
|
|
79
|
+
|
|
80
|
+
Models use optimized GLB/glTF with measured bytes/triangles and a poster during
|
|
81
|
+
load. Particles use points/instancing, not mesh-per-particle. DOM-synced media
|
|
82
|
+
planes keep semantic source media for layout and fallback.
|
|
83
|
+
|
|
84
|
+
## 5. Performance and verification
|
|
85
|
+
|
|
86
|
+
- Cap DPR and complexity; pause off-screen/hidden work.
|
|
87
|
+
- Mobile reduces particles/post effects or uses a purpose-designed poster.
|
|
88
|
+
- Reduced motion renders a stable, intentional frame.
|
|
89
|
+
- Dispose imperative resources and test route transitions/context restoration.
|
|
90
|
+
- Record transferred weight, frame-time/FPS sample, context/draw evidence,
|
|
91
|
+
object/material identity, desktop/mobile screenshots, input response, and
|
|
92
|
+
poster/context-loss fallback.
|
|
93
|
+
|
|
94
|
+
Recipe reference: `../recipes/3d-recipes.md`, after concept exploration only.
|