hilo3d 2.0.0-alpha.3 → 2.0.0-alpha.5

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/CHANGELOG.md CHANGED
@@ -1,3 +1,413 @@
1
+ # Unreleased
2
+
3
+ ### Breaking changes
4
+
5
+ - Move skin history validity from the removed `SkinningBlock.u_skinHistoryParams.x` to
6
+ `ModelBlock.u_modelHistoryParams.y`. The two 128-joint palettes now occupy exactly 16,384 bytes,
7
+ fitting the WebGL2 minimum uniform-block capacity. Custom shaders and block producers must use the
8
+ new location; model and skin validity remain independent.
9
+
10
+ - Integrate typed particle parameters into emission and spawn initialization across CPU, stateless,
11
+ and stateful WebGPU command generation; runtime value changes no longer require recompilation.
12
+ Apply `ParticleBudgetManager` decisions directly to live capacity, spawn rate, sorting, soft
13
+ particles, collision, and ribbon work. Connect the bounded stateless WebGPU generator to Render
14
+ Graph compute, indirect storage raster, and device-loss regeneration, with explicit CPU fallback
15
+ for unsupported definitions and manual emission. Explicit stateful GPU emitters now reject
16
+ `replace-oldest`; unsupported module/backend pairs fail compilation instead of doing nothing.
17
+ - Replace the mutable `Material` monolith with immutable `MaterialDefinition` plus
18
+ `MaterialInstance`. Remove legacy topology mutation, WebGL-style blend/side fields, material-owned
19
+ render order and shadow participation, material display transforms, shared UV matrices, shadow
20
+ proxy materials, `onBeforeCompile`, and `shaderCacheId`. Move object ordering and shadow flags to
21
+ `Mesh`; require construction-time topology, explicit coverage/compositing, typed
22
+ `MaterialAttributeSemantic`/`MaterialUniformSemantic`/`MaterialTextureSemantic` bindings, and
23
+ explicit pass pipeline state. This is a direct migration with no compatibility adapter.
24
+ - Split per-texture-slot std140 metadata out of `MaterialBlock` into the fixed
25
+ `MaterialTextureBlock`. The material scalar block is now 448 bytes and includes
26
+ `u_temporalReactiveFactor`; the texture-slot block is 1,920 bytes, WebGPU material textures begin
27
+ at binding 2, and custom uniform block registrations begin after ten built-in WebGL2 binding
28
+ points.
29
+ - Advance the shared GPU PBR material record to `builtin-pbr-storage-v3`. The byte length is
30
+ unchanged, but the third surface vector's formerly reserved W component now stores authored
31
+ temporal reactivity for the fused GPU Scene depth/motion pass.
32
+ - Expand the fixed Camera/Model/Skinning/Morph/Instance std140 ABI with current/previous transforms,
33
+ stable and jittered camera projections, render origins, and per-domain history/depth flags. Custom
34
+ shaders that redeclare built-in blocks must use the updated field order and capacities. Add
35
+ `u_modelLayerParams` to `ModelBlock` so direct and GPU Scene clustered shading share the uint32
36
+ receiver light-layer contract.
37
+ - Make forward feature color encoding explicit. `replaceColor()` now requires `linear` or `srgb`,
38
+ and the default Forward pipeline always routes surface presentation through the Render Graph so
39
+ the final output transfer is owned by the output stage rather than individual materials.
40
+ - Replace the Forward-specific color-encoding type with the shared `RenderColorEncoding`. Manual
41
+ RenderTarget presentation now accepts an explicit `colorEncoding`; linear inputs receive the final
42
+ sRGB transfer, while display-transformed `srgb` inputs are preserved without a second conversion.
43
+ - Make `ClusteredForwardPlusPipelineFactory.create()` asynchronous so renderer initialization can
44
+ finish its declared material-variant warmup before the first frame.
45
+
46
+ ### Changes
47
+
48
+ - Add tag-driven npm releases: the release command creates and pushes an annotated tag matching all
49
+ three package versions, then GitHub Actions validates the tagged commit and publishes `hilo3d`,
50
+ `@hilo/addon-particle`, and `@hilo/addon-physics` under one dist-tag through npm Trusted
51
+ Publishing. Addon peer dependencies use the exact synchronized core version, and safe workflow
52
+ retries skip package versions that are already present in npm.
53
+ - Allow local Playwright release validation to select an unoccupied loopback port with
54
+ `HILO3D_PLAYWRIGHT_PORT`; CI retains the deterministic default port.
55
+ - Make `site:build` own the complete public API declaration/check prerequisite for the core and both
56
+ addon packages. The Pages and CI preflight workflows now invoke self-contained `site:build` and
57
+ `lint` commands, while the Node-side repository preflight prevents clean-checkout jobs from
58
+ calling built-only commands without addon declarations.
59
+ - Replace the unenrolled Linux-only RHI performance-rig contract with an auditable Apple M3 Max
60
+ macOS/Metal profile. Require AC power, High Power Mode, a warning-free thermal state, exact
61
+ Node/Playwright/Chromium identity, physical Metal, GPU timers, precise memory, and allocation
62
+ profiling before collection or immutable baseline freezing. Size the release benchmark for a small
63
+ engine with three rounds, 500 timing/GPU frames, bounded one-frame allocation profiles, and a
64
+ single-draw absolute-allocation sentinel while retaining stress allocation data diagnostically.
65
+ Add per-phase progress and abortable browser/heap-profiler waits so a lost response fails
66
+ explicitly instead of hanging a formal run. Keep the large-instancing workload's 640,000-byte
67
+ dynamic budget scoped to instance transforms instead of incorrectly requiring the dynamic-texture
68
+ fixture, and distinguish a persistent shadow caster from steady shadow redraws after the atlas
69
+ cache is warm. Keep the sole churn shadow caster identity stable while cycling all ordinary mesh
70
+ slots, and explicitly budget the two shadow-view redraws caused by scene-child churn. Give the
71
+ depthless MRT/MSAA source workload the same explicit no-depth-write state as its fullscreen
72
+ continuation passes. Count first-complex-frame dynamic shadow invalidation and its final
73
+ linear-to-sRGB surface transfer in the declared steady draw budget. Keep targeted churn smoke
74
+ bounded to one complete ordinary-mesh replacement cycle unless its 10,000-frame tail is explicitly
75
+ requested; formal enrolled-rig capture still completes the full workload.
76
+ - Add the versioned, dependency-aware public Stage System ABI with typed services, transactional
77
+ asynchronous setup, synchronous frame hooks, dynamic leaf installation, and reverse-order
78
+ teardown. Add the separately packaged `@hilo/addon-physics` portable 2D/3D runtime with bounded
79
+ fixed stepping, interpolated Hilo node bindings, bodies, colliders, joints, events, filtered ray
80
+ and shape queries, bounded overlaps, point projection, kinematic character controllers, snapshots,
81
+ debug geometry, diagnostics, and independently importable Rapier 2D/3D adapters. Replace the
82
+ Cannon example and dependency with a Rapier 3D System example.
83
+ - Move the authored particle runtime out of the `hilo3d` entry into the independently tree-shakable
84
+ `@hilo/addon-particle` ESM package. Add a Stage-owned particle runtime and frame budget service,
85
+ route addon rendering through a generic core render-node capability, migrate maintained particle
86
+ examples and package types, and add Rapier material, joint, and 2D sensor showcases.
87
+
88
+ - Rebuild portable GTAO around view-relative dual horizons, projected-normal analytic visible-arc
89
+ integration, depth-derived or hybrid normals, a separately controlled contact lobe, integrated
90
+ bent normals, distance/edge fading, and explicit low/medium/high/ultra budgets. Add logarithmic-
91
+ depth reconstruction, per-camera pass/UBO isolation, closest-depth motion selection, depth/normal
92
+ confidence, variance clipping, vector-space bent-normal filtering, unblurred rejection depth, and
93
+ joint bilateral upsampling. Feed color-aware multi-bounce visibility and bent-cone specular
94
+ visibility into ordinary and Clustered PBR, retune The Silent Dragon, and add a deterministic GTAO
95
+ Acceptance Lab with corner, thin-card, slab, stair, normal-map, dielectric/metal, moving-occluder,
96
+ screen-edge, log-depth, on/off, temporal, and WebGL2/WebGPU parity gates.
97
+ - Upgrade WebGPU high-end SSR with response-aware 8×8 tile masks, coherent prefix compaction,
98
+ indirect stochastic visible-GGX tracing, roughness-adaptive ray budgets, refined depth crossings,
99
+ hit-normal facing validation, and explicit uncertain/backface outcomes. Evaluate receiver- and
100
+ hit-motion-domain history candidates against real previous material/depth state, authored reactive
101
+ masks, YCoCg neighborhood variance and roughness-adaptive sample counts; replace four fixed
102
+ filters with one adaptive bilateral hole-fill and a full-resolution edge-aware resolve. Align
103
+ clearcoat/anisotropy trace lobes with forward IBL, keep fallback removal independent from SSR
104
+ intensity, replace absolute half-float hit UVs with motion/depth state, compress material
105
+ attributes to `rgba8unorm`, prefer `rg11b10ufloat` reflection MRTs when supported, and expose
106
+ mutually exclusive uncertain/backface and history diagnostics alongside active/hit/miss counters.
107
+ Cap compacted active-tile indirect work to a two-dimensional 65,535-wide dispatch, retain
108
+ reflection-response/material identity in temporal history and spatial filtering, and make ordinary
109
+ Forward reflection MRTs reuse the main PBR GTAO visibility and iridescence parameters.
110
+ - Add the first S0 production shadow-cache slice. Stable atlas tiles now use exact light/caster
111
+ snapshots, scissored portable depth clears, per-slice invalidation, submission commit/rollback,
112
+ recovery invalidation, and `RendererDiagnostics.caches.shadowAtlas`; static slices issue no shadow
113
+ pass, while local-light changes redraw only their affected faces.
114
+ - Extend S0 shadows with clustered GPU Scene caster culling and fixed-bucket indirect depth draws;
115
+ receiver-driven local/cascade resolution; deterministic slice budgets and 1/2/4/8-frame CSM
116
+ cadence; and submission-aware 128-pixel page residency with coalesced page-scissored updates that
117
+ avoid replaying the caster queue once per adjacent page. Expose page
118
+ request/update/defer/residency and budget-overflow counts in frame diagnostics.
119
+ - Add opt-in WebGPU Clustered virtual directional shadows through
120
+ `ClusteredForwardPlusPipelineOptions.virtualShadows`: previous-Hi-Z receiver classification,
121
+ atomic GPU request deduplication and deterministic ordering, arbitrary logical-to-physical page
122
+ remapping with LRU eviction, deferred dirty-page retry, per-page GPU caster compact/indirect depth
123
+ draws, and camera-centered directional clipmaps. Double-buffer page tables, residency, and clipmap
124
+ epochs commit only after successful submission; failed frames roll back and device recovery
125
+ reinitializes mappings without CPU request readback. Expose on-demand virtual-shadow diagnostics
126
+ and retain shared CSM fallback for missing pages and non-GPU caster scenes.
127
+ - Complete the WebGPU high-end Clustered Forward+ P0 closure. Globally sorted compatible transparent
128
+ PBR and direct GPU Scene skin, morph, and layered glTF PBR now consume the native storage light
129
+ list, while mixed Transmission/custom/particle transparent queues fail closed to the shared
130
+ Forward path. Add transparent/transmission and isolated GPU-particle reactive, depth-agreement,
131
+ history-resurrection composition; analytic Spot cookie/IES records and uint32 light-layer
132
+ filtering; a public material-variant manifest with asynchronous warmup, transactional runtime
133
+ admission, fixed budgets, and diagnostics; and real WebGPU pixel/UI coverage for rollback, device
134
+ loss, recovery, layered/deformed lighting, particles, and mixed-queue fallback. Fix the stateless
135
+ particle WGSL hash expression for strict browser parser precedence.
136
+
137
+ - Resolve the `hilo3d-game` starter dependency from the npm `next` dist-tag, validate its supported
138
+ 2.0 release shape, and pin the resolved concrete version for reproducible installs.
139
+ - Update the standalone `hilo3d-game` skill for immutable material topology, Mesh-owned ordering and
140
+ shadow participation, and the completed portable/WebGPU particle authoring workflow.
141
+ - Normalize managed particle textures through the shared top-left UV boundary for CPU and WebGPU
142
+ sprite, mesh, motion-vector, ribbon, and trail shaders. Fix WebGPU 2D Sprite orientation when
143
+ `Texture.flipY` is false, and extend the asymmetric row-direction fixture across WebGL 2/WebGPU
144
+ render targets, ordinary materials, 2D Sprites, particles, and cube textures.
145
+
146
+ - Add the versioned public `ParticleSystemDefinition`/`ParticleSystem` API through P0-P3. Compile
147
+ immutable fixed modules into liveness-based SoA layouts with deterministic counter RNG and shared
148
+ curve/gradient LUTs; provide portable CPU fixed-step simulation with one interleaved instanced
149
+ sprite draw on WebGL 2/WebGPU; and add renderer-owned stateful WebGPU simulation, alive/dead
150
+ compaction, spawn commands, indirect arguments, Bitonic/distance-bucket sorting, recovery-aware
151
+ commit/rollback, and constrained storage-aware sprite raster through the default Forward Render
152
+ Graph. Keep the existing specialized compute-particle showcase unchanged until the remaining
153
+ particle phases are complete. Add stateless eligibility metadata and asset-level diagnostics,
154
+ absolute-time CPU reconstruction, a no-state Naga-validated WebGPU renderer-data generator,
155
+ deterministic live budget/quality application, and reusable short-effect system pooling.
156
+ - Extend the particle runtime through P4 with analytic collision and triggers, WebGPU scene-depth
157
+ collision, sampled-depth soft sprites with fragment depth comparison, compact bounded CPU events,
158
+ typed `ParticleEventChannel`, asynchronous aggregate reads, and GPU-resident event
159
+ capture/sub-emitter routing without count or state readback. Allow constrained storage graphics
160
+ shaders to specialize ordinary GLSL numeric depth samplers into WGSL depth textures.
161
+ - Complete particle P5 with portable mesh instancing and per-mesh buckets, ribbon/trail topology and
162
+ dense segment streams, WebGPU mesh scatter plus per-asset indirect draws, per-view GPU ribbon
163
+ topology sorting/segment compaction/indirect raster, ambient plus bounded directional Lambert
164
+ lighting, soft ribbons, explicit Bloom/TAA composition semantics, and opt-in motion vectors for
165
+ supported portable opaque/masked mesh output. Add fail-closed advanced quality gates instead of
166
+ silently degrading unsupported tiers. Allow the built-in opaque GPU particle boundary to request
167
+ opaque/transparent Forward splitting only on frames that actually draw eligible particles.
168
+ - Add the first particle P6 authoring slice with normalized versioned JSON serialization, strict
169
+ parsing and compiler validation, sequential application-owned upgrades, document-local shared
170
+ parameter identities, and stable application-resolved Texture/Geometry references. Reject future
171
+ versions, missing or skipped upgrades, unknown schema fields/tags, and unresolved or wrong-kind
172
+ resources before runtime construction.
173
+ - Add versioned reusable in-memory particle simulation checkpoints. Capture and restore CPU SoA,
174
+ fixed-step scheduler, pending manual emission, bounded events, playback/budget/culling state, and
175
+ stateless GPU absolute time without production-loop readback. Bind checkpoints to definition,
176
+ compiled plan, seed, parameter identity/revision, and event capacity; reject stateful GPU capture
177
+ until an explicit asynchronous device-state transfer contract exists.
178
+ - Add bounded deterministic particle baking APIs. Export stable-ID/generation-sorted frame-major
179
+ mesh instance caches with motion/orientation inputs and bounds, and pack application-rendered,
180
+ tightly packed render-target readbacks into native-format flipbook atlases. Restore the caller's
181
+ simulation checkpoint after success or failure, bound frame/particle/atlas work, and reject
182
+ stateful GPU baking rather than introducing synchronous device-state readback.
183
+ - Complete particle P6 external authoring with a published fixed-module graph JSON Schema,
184
+ deterministic definition-to-graph conversion, strict ownership/compiler validation,
185
+ node-addressable diagnostics, normalized inspector IR, and a versioned preview controller for
186
+ compile/play/pause/restart/seek/step/inspect/dispose without GPU particle readback.
187
+ - Allow a Forward feature runtime to request sampled single-sample scene depth per frame before
188
+ attachment allocation, so scene-dependent effects do not force unrelated RenderTarget frames
189
+ through an intermediate depth path.
190
+ - Add an integrated WebGPU physical atmosphere and weather chain to Clustered Forward+: cached
191
+ Rayleigh/Mie/ozone transmittance and multiple-scattering LUTs, a per-frame sky-view LUT, aerial
192
+ perspective, physical sun disc, procedural weather map, quality-tier Perlin/Worley volumetric
193
+ cloud ray marching, blue-noise sampling, representative-depth temporal reprojection, cloud shadows
194
+ for registered PBR directional light and froxel scattering, and storm lightning/sun-shaft
195
+ lighting. Add GPU histogram percentile exposure with asymmetric eye adaptation, on-demand
196
+ diagnostics, and submission-aware `rgba16float` exposure history; add configurable filmic Color
197
+ Uber and Clustered display transforms. Add the interactive Stormfront Observatory WebGPU example
198
+ with solar time, cloud, wind, storm, quality, debug, and camera controls.
199
+ - Add production dynamic resolution and authored reactive masks to `TemporalAA` and the integrated
200
+ Clustered Forward+ temporal path. Dynamic resolution is explicitly gated by WebGPU
201
+ `timestamp-query`, consumes asynchronous Render Graph GPU pass durations without stalling the
202
+ frame, and applies EWMA smoothing, hysteresis, quantized steps, warmup, settling, min/max bounds,
203
+ duplicate-sample rejection, and fail-closed handling for unavailable, failed, or saturated
204
+ timings. Resolution changes synchronously resize scene color/depth/motion/reactive, Hi-Z,
205
+ clusters, GTAO/SSGI/SSR, volumetric, atmosphere and cloud resources while invalidating
206
+ size-dependent history; color/depth history, transparent/UI composition and presentation remain
207
+ output resolution. Add `MaterialInstance.temporalReactiveFactor`, write it through a second
208
+ `r8unorm` motion MRT in ordinary Forward and the fused GPU Scene prepass, conservatively dilate it
209
+ 3×3, and combine it with luminance reactivity during TAA/TAAU rejection. Expose single-runtime
210
+ Forward diagnostics and Clustered scale/GPU-time diagnostics, with tests for controller stability,
211
+ ABI validation, material revisions, shared GPU packing, fallback and resource requirements.
212
+ - Complete the native GPU Scene/Clustered Forward+ coverage slice for alpha-masked PBR, shared
213
+ shadows, and area lights. Alpha coverage now uses base-color/opacity slot transforms, channels,
214
+ encodings, factors, and cutoff consistently in indirect depth, motion, material-attribute, and
215
+ color passes. Directional, spot, and point lights keep GPU Scene objects on the clustered path
216
+ while sampling the renderer's exact shared shadow-atlas graph texture with standard/reversed-depth
217
+ 3×3 PCF, cascades, slope bias, shadow strength, and per-mesh `receiveShadows`. Area lights use the
218
+ ordinary Forward LTC LUTs as global storage-light records with explicit-LOD WebGPU sampling rather
219
+ than point-light approximation or whole-camera fallback. `RenderPipelineContext.recordShadows()`
220
+ now returns frame-scoped atlas, light order, bias, cascade, and matrix data for custom pipelines;
221
+ the atlas remains renderer-owned, recovery-aware, and submission-tracked.
222
+ - Add production screen-space diffuse global illumination to ordinary Forward on WebGPU/WebGL 2 and
223
+ to the WebGPU Clustered Forward+ profile. The opt-in path reuses GTAO/GPU Scene material
224
+ attributes and motion/log-depth when available, traces configurable stochastic view-space
225
+ hemisphere rays against opaque depth, transports bounded linear HDR scene radiance, applies
226
+ motion/depth/normal history rejection with YCoCg variance clipping, runs one to three
227
+ depth/normal/luminance-aware a-trous filters, performs bilateral full-resolution upsampling, and
228
+ composites before transparent, Bloom, and display. Keep per-camera history submission-aware across
229
+ cuts, resize, discarded frames and recovery; use explicit-LOD sampling so translated WGSL remains
230
+ valid in non-uniform ray/filter control flow; and keep the disabled path resource- and pass-free.
231
+ Add the dual-backend Prismatic Vespers procedural chapel with cyan, vermilion, violet, and warm
232
+ emissive architecture, same-view on/off controls, responsive editorial UI, and WebGL 2/WebGPU
233
+ render-health and GPU-validation coverage.
234
+ - Add production WebGPU high-end froxel volumetric lighting to
235
+ `ClusteredForwardPlusPipelineFactory`. The opt-in path expands the bounded local-light allocator
236
+ from surface depth ranges to the complete camera cluster volume, tiles logarithmic Z slices into a
237
+ dimension-validated `rgba16float` atlas, injects directional/point/spot radiance plus exponential
238
+ height and sphere/box local fog, cumulatively integrates each froxel column once, reconstructs
239
+ depth-bounded radiance/transmittance in constant texture-fetch cost, and performs previous-view
240
+ reprojection, depth/reactive temporal rejection, neighborhood clamping, and linear HDR
241
+ transmittance/scattering composition before TAA/TAAU, transparent fallback, Bloom, and display.
242
+ Add bounded screen-space light visibility, low/medium/high/ultra budgets, radiance/transmittance
243
+ debug views, submission-aware diagnostics, camera-cut/resize/failure/device-recovery history, and
244
+ fail-closed storage/format/texture-dimension requirements. Keep explicit shadow-atlas and
245
+ transparent-volume participation as documented future ABIs rather than silently approximating
246
+ either contract. Add Neon Reliquary around the repository-bundled Khronos Sponza with a cinematic
247
+ 40px surface grid, 0.375-scale froxel XY/20-slice volume, 0.72-scale TAAU, animated chromatic
248
+ spotlights, seven local fog fields, camera/debug controls, and a physical-WebGPU
249
+ stability/on-off/GPU-validation gate.
250
+ - Add production ground-truth ambient occlusion to ordinary Forward on WebGPU/WebGL 2 and to the
251
+ WebGPU Clustered Forward+ profile. The opt-in path records shared depth/material-attribute/motion
252
+ producers, configurable rotated horizon search, bent-normal visibility, submission-aware temporal
253
+ rejection, two edge-aware filters, and bounded depth/normal upsampling before applying the result
254
+ only to PBR ambient/IBL. Keep direct lights and emission unoccluded, reset or roll back per-camera
255
+ history across cuts, resize, discarded frames and recovery, and keep the disabled path resource-
256
+ and pass-free. Add The Silent Dragon museum study around the repository-bundled 1.2 MB Stanford
257
+ Dragon, with same-page GTAO A/B switching, responsive art direction, and real WebGPU/WebGL 2
258
+ non-black and on/off pixel coverage. Keep the deployed glTF beside its external binary payload,
259
+ and make the site link gate validate nested glTF buffer, image, and extension URIs before publish.
260
+ - Add production WebGPU high-end screen-space reflections to `ClusteredForwardPlusPipelineFactory`.
261
+ The opt-in path adds a strict built-in `material-attributes` `rgba8unorm` ABI, matching HDR GPU
262
+ Scene MRT and ordinary Forward fallback coverage, RG32F min/max Hi-Z, hierarchical coarse-to-fine
263
+ tracing, roughness radiance cones, edge/distance/roughness confidence, motion/log-depth temporal
264
+ rejection and confidence-aware depth/normal à-trous filtering before HDR composition and TAA/TAAU.
265
+ Keep the disabled path allocation- and pass-free, fail closed without Hi-Z or TemporalAA, and
266
+ reset history across camera cuts/identity changes, resize, discarded frames and device recovery.
267
+ Feed ordinary Forward opaque through a `depth-only` fallback prepass before current Hi-Z
268
+ construction so layered PBR objects are present in both the radiance source and hierarchical depth
269
+ trace. Add `rg32float` to the public compute storage-texture formats, add the repository-bundled
270
+ Khronos Car Concept to the dedicated Afterimage SSR showcase, and cover real WebGPU on/off pixels
271
+ plus GPU validation. The existing Temporal Observatory remains focused on TAA/TAAU.
272
+ - Add the `TemporalAA` Forward feature with native-resolution TAA and fixed-scale TAAU. Built-in
273
+ opaque/masked materials now expose a strict single-sample `rgba16float` motion pass containing
274
+ current-to-previous UV velocity, expected previous logarithmic view depth, and current logarithmic
275
+ view depth. Camera, model, instance, skin, morph, visibility, and failed-frame history are
276
+ submission-aware. TAA runs after opaque and before transparent/Bloom with `rgba16float` color
277
+ history, `r32float` logarithmic-depth history, conservative depth rejection, YCoCg variance
278
+ clipping, motion/luminance-reactive history weight, resolve-only sharpening,
279
+ projection-cut/resize/device-loss invalidation, and deterministic jitter rollback. Clustered
280
+ Forward+ can opt into the same resolve; GPU Scene fuses motion output into its existing depth
281
+ prepass, double-buffers visibility, and composes ordinary Forward fallback opaque before TAA and
282
+ fallback transparent afterward. Add the WebGPU Temporal Observatory example and real-pixel
283
+ convergence/camera-cut/GPU-validation coverage. `TemporalAAOptions.renderScale` accepts 0.5–1;
284
+ sub-native modes render opaque color, depth, motion, Clustered Forward+ Hi-Z, and cluster sizing
285
+ at the fixed internal scale, then reconstruct Catmull-Rom current color into output-resolution
286
+ color/depth history and a full-resolution depth attachment before transparent composition. Dynamic
287
+ resolution, authored reactive masks, and transparent history remain deferred.
288
+
289
+ - Add canonical built-in material definitions, stable material IDs and revisions, explicit
290
+ forward/depth-only/shadow-caster/picking roles, role-aware shader variants, per-slot texture/UV
291
+ transform/encoding/channel data, and deterministic coverage/transmission/compositing ownership.
292
+ Shadow rendering now requests the original material's shadow role, glTF constructs layered PBR
293
+ topology and all texture transforms before instantiation, and display conversion remains solely in
294
+ post-processing/output.
295
+ - Add the renderer-local shared GPU Material Database. Deduplicate material identities into stable
296
+ family/layout handles, coalesce revision-driven dirty record uploads, commit texture slot state
297
+ only after valid submission, retry discarded frames, and retain recovery through the
298
+ renderer-owned CPU shadow. Migrate Clustered Forward+ from its private per-bucket PBR table so GPU
299
+ Scene objects keep independent geometry-bucket and shared-material indices.
300
+ - Complete the Forward+/Clustered/Hi-Z/batching remediation audit. Preserve one global direct/batch
301
+ draw order, pack per-slot PBR texture metadata, use a single compact visible table with aligned
302
+ per-bucket storage offsets and zero indirect `firstInstance`, make overflow membership
303
+ deterministic, keep directional lights global, route AreaLight and shadow-enabled lights through
304
+ exact Forward fallback, restrict previous-frame Hi-Z to stable conservative LOD bounds, compose
305
+ fallback in linear HDR before separable Bloom/display, elide Bloom resources and passes at zero
306
+ strength, cache static batch normal matrices, and separate CPU record timing from GPU completion
307
+ in the 110k-object scale fixture.
308
+ - Add a repository-bundled Khronos Sponza Clustered Forward+ lighting lab with 202 animated local
309
+ lights, including 10 slow chromatic runners that curve through a wall-height central volume, GPU
310
+ Scene diagnostics, HDR bloom, a multi-region OrbitControls camera tour, responsive controls, and
311
+ an offline-friendly asset path with native WebGPU release coverage.
312
+ - Avoid repeated scene traversal, camera refresh, LightManager packing, and built-in semantic-block
313
+ activation while preparing resource-only compute, GPU-driven, and fullscreen passes. Their shared
314
+ buffer/texture/resource-use transaction remains submission-aware; scene passes activate semantics
315
+ only when an actual renderer list or mesh draw needs them. Clustered Forward+ now also batches all
316
+ fixed-bucket depth draws and all color draws into one native render pass each while retaining
317
+ independent indirect arguments, pipelines, bindings, and graph-declared dependencies.
318
+ - Make previous-frame Hi-Z occlusion conservative for moving and stationary cameras. Disable it for
319
+ the first frame after a view-projection or depth change, project bounds from the sphere's nearest
320
+ depth and all eight corners of its view-space bounding cube, select a mip covering the full
321
+ projected extent, and cover the full configured viewport with a specialized pyramid of up to
322
+ thirteen levels. Only transform- and bounds-stable objects consume previous history. The current
323
+ pyramid is still retained so culling resumes immediately on the next stable frame without temporal
324
+ disocclusion holes, off-axis under-bounds, or large-geometry false positives. GPU Scene frustum
325
+ culling now tests the exact view-space side-plane radius instead of underestimating large spheres
326
+ near a screen edge, and honors each mesh's `frustumTest` opt-out.
327
+ - Keep GPU Scene depth-prepass and color-pass clip-space transforms byte-identical so reversed-depth
328
+ testing remains stable while the camera moves instead of exposing stippled, checkerboard, or large
329
+ missing regions from cross-program floating-point rounding.
330
+ - Keep default Forward lighting, clear colors, transparent blending, and intermediate effects in
331
+ linear space, then apply one exact linear-to-sRGB transfer at the browser surface. Multi-camera
332
+ load/blend stays in a renderer-owned linear composition target, while already transformed Color
333
+ Uber output is presented without a second conversion. Single-camera MSAA resolves into the
334
+ persistent single-sample composition target; multi-camera stacks use one single-sample
335
+ color/depth/stencil composition contract so later cameras can load prior contents exactly.
336
+ - Keep ShaderMaterial scene output linear and make custom pipeline presentation encoding explicit.
337
+ ShaderToy now relies on the shared Forward output transfer, while the compute particle field and
338
+ crystal path tracer declare their display-referred output so their authored grading is not
339
+ transferred twice.
340
+ - Advance the RHI benchmark manifest to schema 4 and model fixed surface-output draws separately
341
+ from primary scene and post-process draws; immutable snapshots from earlier schemas remain
342
+ historical evidence and are not rewritten.
343
+ - Route opaque-composited transmission surfaces through the after-opaque forward queue so their
344
+ scene-color dependency is satisfied without conflating transmission with alpha blending. Apply
345
+ texture-slot encoding consistently to 2D, cube, and environment samples, including explicit sRGB
346
+ decoding for the LDR studio IBL. WebGPU shader lowering now retains the managed material sampler
347
+ for single-UV shaders instead of bypassing texture transforms, decoding, and channel remapping,
348
+ restoring WebGL2/WebGPU material parity.
349
+ - Add the `high-end` rendering profile, per-camera standard/reversed depth modes, finite/infinite
350
+ reversed-Z projection, depth-convention-aware surfaces, render targets, shadows, storage graphics,
351
+ and GPU picking. Add optional camera-relative GPU transforms while preserving CPU world identity,
352
+ plus submission-transactional current/previous camera, mesh, instance, skinning, and morph state.
353
+ `Node.invalidateTransformHistory()` resets discontinuous motion deterministically.
354
+ - Add the WebGPU-only `ClusteredForwardPlusPipelineFactory` high-end opaque-scene slice. Registered
355
+ ordinary Mesh buckets now use stable dirty GPU Scene records, full-viewport previous-frame Hi-Z
356
+ occlusion, projected-size LOD compaction, fixed indexed-indirect draws, depth-driven logarithmic
357
+ 3D clusters, a bounded count/prefix/write light allocator, storage GGX PBR, HDR Bloom, ACES
358
+ display, and on-demand visibility/overflow diagnostics. Add real WebGPU renderer coverage for the
359
+ compute/dispatch/indirect-draw path. Make Hi-Z conservative for both standard and reversed depth,
360
+ use the committed previous view/projection/depth convention for temporal occlusion, preserve the
361
+ depth prepass during color shading, and use inverse-transpose object normal matrices. Registered
362
+ buckets now migrate at runtime between the GPU path and a shared Forward compatibility path for
363
+ material/geometry replacement, alpha, transparency, skinning, morphing, unregistered meshes, and
364
+ object-capacity overflow; the fallback preserves normal opaque/transparent sorting, shadows, and
365
+ transmission scene-color input without double-drawing GPU-managed meshes. Device limit
366
+ requirements cover every configured geometry/cluster buffer and dispatch dimension. Add a real
367
+ WebGPU 100k-static + 10k-dynamic + 256-light scale/recovery acceptance fixture and deterministic
368
+ cluster-overflow coverage. Share metallic/roughness surface evaluation and the BRDF between
369
+ ordinary Forward and clustered storage shaders so Forward+ replaces only light-list iteration. Add
370
+ native GPU Scene base-color, metallic, roughness, combined metallic-roughness, occlusion,
371
+ emission, and normal maps with UV0/UV1, UV matrices, tangent streams, sampler mutation, runtime
372
+ texture replacement, and device-recovery coverage; incompatible alpha/layered/deformed inputs
373
+ continue to use the Forward fallback.
374
+ - Let scriptable pipeline factories create persistent renderer-owned storage buffers, stage dirty
375
+ writes before graph import, and commit or discard CPU temporal state at the actual submission
376
+ boundary through `frameSubmitted()` and `frameDiscarded()`. Pipeline-owned buffers retain normal
377
+ device-loss recipes and submission-aware destruction. Frame completion still runs when a
378
+ post-submission pipeline callback throws, so presentation, events, diagnostics, and temporal
379
+ cleanup are not skipped after GPU work has already been submitted.
380
+ - Let scriptable render graphs import engine-managed `Texture` objects as sampled persistent
381
+ resources while preserving renderer upload/recovery/submission ownership. Expose the public
382
+ per-stage sampler limit alongside the existing sampled-texture limit.
383
+
384
+ - Add modern WebGPU capability discovery for `subgroups`, adapter subgroup-size limits,
385
+ `shader-f16`, and `timestamp-query`; expose renderer feature queries for explicit f32/workgroup
386
+ fallback selection. Direct WGSL f16 now preserves the exact native artifact while completing Naga
387
+ validation through an equivalent f32 specialization. Compute buffer `minBindingSize` is derived
388
+ from WGSL store types, including the required one-element runtime-array minimum.
389
+ - Add submission-aware timestamp QuerySets, pass timestamp writes, explicit resolves, and validated
390
+ debug groups/markers to the portable RHI. Opt-in renderer diagnostics now publish Render Graph
391
+ record/compile/prepare/execute CPU timing, per-pass asynchronous GPU timing, and compiled resource
392
+ lifetime intervals through a non-blocking three-slot readback ring; the default diagnostics-off
393
+ path creates no query resources.
394
+ - Add explicit Render Graph texture views for mip, array-layer, dimension, compatible-format, and
395
+ depth/stencil-aspect access across sampled, storage, attachment, and copy paths. Add
396
+ renderer-owned double/triple-buffer history textures whose recipes survive device recovery, whose
397
+ contents invalidate on descriptor or device-generation changes, and whose current/history rotation
398
+ commits only after a successful submitted writer frame. History recipes initially accept one
399
+ single-sample 2D color mip/layer so slot validity always means complete initialization.
400
+ - Add camera-relative cascaded shadows for directional lights on the shared WebGL 2/WebGPU shadow
401
+ atlas path. `DirectionalLight.shadow` now supports one to four cascades, practical split
402
+ weighting, a maximum shadow distance, cross-cascade blending, and texel stabilization while
403
+ preserving the existing single-shadow default. Filtered directional shadow contrast is
404
+ art-directable through `shadowStrength`. Add an interactive pastel sunset geometry-garden example
405
+ with live cascade count, stabilization, orbit controls, split, blend, strength, distance, and 4×
406
+ MSAA.
407
+ - Promote `OrbitControls` from an example helper to the public `src/controls` API, add constrained
408
+ `setView()` support for scripted tours, and make maintained examples reuse the engine control
409
+ instead of carrying local camera gesture implementations.
410
+
1
411
  # 2.0.0-alpha.2 (2026-07-26)
2
412
 
3
413
  ### Breaking changes
@@ -46,6 +456,8 @@
46
456
 
47
457
  ### Fixes
48
458
 
459
+ - Preserve GLSL comparison shadow samplers during storage-graphics WGSL lowering instead of
460
+ incorrectly sending already translated depth textures through numeric-depth specialization.
49
461
  - Keep float scene-color variants linear by suppressing material-local gamma encoding and legacy
50
462
  per-material tone mapping until the final display transform. Preserve HDR Bloom energy with
51
463
  normalized Karis weights, remove the non-physical far-distance light floor, and use refracted
@@ -58,6 +470,9 @@
58
470
  storage rows, pointer input, and readback. Apply it to Bloom, Color Uber, graph present,
59
471
  transmission, ShaderToy, Life Game, the compute particle field, the compute path tracer, and
60
472
  built-in material/environment sampling so WebGL 2 and WebGPU retain the same Y orientation.
473
+ - Keep shared Shadow Atlas rectangles in positive top-left coordinates and convert light-space UVs
474
+ through the portable render-target helper. WebGL 2 no longer samples a vertically mirrored depth
475
+ atlas that made moving shadows appear to rotate opposite their casters.
61
476
  - Correct `SpriteFrame`'s top-left atlas-row offset for `flipY` textures on both backends. Full
62
477
  textures were unaffected, but subframes previously selected the vertically opposite source row,
63
478
  swapping nine-slice top/bottom pieces and requiring reversed character-direction maps. Use a
@@ -86,9 +501,10 @@
86
501
 
87
502
  ### Changes
88
503
 
89
- - Add a portable `build-hilo3d-games` Agent Skill with strict TypeScript/Vite starters for 2D, 3D,
90
- and hybrid games, stable-first `2.0.0` dependency resolution, focused public-API references, and
91
- repository checks that keep bundled examples and version-selection behavior valid.
504
+ - Add a portable `hilo3d-game` Agent Skill under `skills/` with strict TypeScript/Vite starters for
505
+ 2D, 3D, and hybrid games, stable-first `2.0.0` dependency resolution, focused public-API
506
+ references, and repository checks that keep bundled examples and version-selection behavior valid
507
+ without treating the skill as repository-scoped Codex guidance.
92
508
  - Separate the full release gate from npm's publish lifecycle: `npm run release:check` retains the
93
509
  complete validation matrix, while `prepublishOnly` performs only fast deterministic checks before
94
510
  `prepack` builds the tarball, avoiding repeated browser suites and expired publish OTPs.
@@ -149,19 +565,21 @@
149
565
  forces, boundary physics, GPU-authored indirect arguments, and three particle raster layers stay
150
566
  on the public Render Graph/RHI path. Its deterministic test mode drives real pointer input without
151
567
  reading particle state back to the CPU.
152
- - Keep first-release compute textures limited to complete 2D graph resources, with transient
153
- write-only storage textures and no persistent storage-texture or layer/mip-view API. Persistent
154
- state uses externally owned renderer `StorageBuffer` objects imported per frame; each Renderer
155
- accepts one pending storage-buffer readback. `cpu-shadow` recovery restores CPU bytes rather than
156
- later GPU mutations, and Direct WGSL `f16` remains fail-closed until the Naga validation path can
157
- validate it end to end. Storage-aware graphics retains broader Material/Scene texture reflection,
158
- while `GPUDrivenRenderPass` rejects non-2D graph texture bindings before backend execution.
568
+ - Keep storage texture writes write-only and complete for the selected single-mip view; overlapping
569
+ sampled/write feedback remains invalid. Persistent texture state uses renderer-owned history
570
+ recipes, while persistent buffer state uses externally owned renderer `StorageBuffer` objects
571
+ imported per frame; each Renderer accepts one pending storage-buffer readback. `cpu-shadow`
572
+ recovery restores CPU bytes rather than later GPU mutations, and Direct WGSL `f16` remains
573
+ fail-closed until the Naga validation path can validate it end to end. Storage-aware graphics
574
+ retains broader Material/Scene texture reflection, while `GPUDrivenRenderPass` validates explicit
575
+ graph view dimension, format, and sample type before backend execution.
159
576
  - Expose the built-in forward culling results to features, reject feature runtimes shared across
160
577
  Renderers, and preserve selected RenderTarget color/depth/stencil clear/load/store operations
161
578
  across feature-enabled scene, intermediate-color, and output passes.
162
- - Reject pre-opaque scene-color sampling and keep the built-in forward feature's `sampledDepth`
163
- option fail-closed; a custom SRP can explicitly compose depth prepass, compute culling, and a
164
- storage-aware Scene pass for Forward+.
579
+ - Reject pre-opaque scene-color sampling and support built-in Forward `sampledDepth` through
580
+ single-sample sampleable depth plus portable non-filtering fullscreen bindings. A custom SRP can
581
+ still explicitly compose depth prepass, compute culling, and a storage-aware Scene pass for
582
+ Forward+.
165
583
  - Add backend-neutral `Renderer.waitForIdle()` for application completion fences. Native WebGL 2 or
166
584
  WebGPU interoperability is opt-in through `Renderer.getExtension()` instead of public `gl` or
167
585
  `gpuDevice` fields.