Breaking changes
- [BREAKING] Move gsplat lodRangeMin/lodRangeMax to GSplatComponent by @mvaligursky in #8908
Changes
- Drop "unified" framing now that it's the default by @mvaligursky in #8805
- Support GSPLAT_AA in the hybrid gsplat renderer by @mvaligursky in #8807
- Support HTML-in-Canvas textures via copyElementImageToTexture (WebGPU) by @mvaligursky in #8810
- Replace opaque any/* types with real types in API reference by @willeastcott in #8811
- Elevate the Entity class reference to peak quality by @willeastcott in #8814
- Support transient (memoryless) attachments (WebGPU) by @mvaligursky in #8816
- [BREAKING] World-space PCSS penumbra, plus gsplat & cascade fixes by @mvaligursky in #8818
- Automatic bind-group reflection for compute shaders (WebGPU) by @mvaligursky in #8821
- Apply render-stage modify hooks in the hybrid gsplat renderer by @mvaligursky in #8822
- Move test fixture server off port 3000 and use relative asset URLs by @mvaligursky in #8823
- Add post-build tests for ESM/UMD bundles and API surface gate by @kpal81xd in #8845
- Comment the public API diff on PRs (informative) by @kpal81xd in #8848
- Add MeshInstance.shaderPassMask to control shader pass participation by @mvaligursky in #8852
- Add stereo XR support to hybrid GPU-sort gsplat renderer by @mvaligursky in #8861
- Reduce API report comment noise by @kpal81xd in #8863
- Warn and fail GLB loading when Draco decoder is unavailable by @mvaligursky in #8868
- Add foveated contribution culling to the GPU-sort gsplat renderer by @mvaligursky in #8869
- Align ButtonComponent with CameraComponent architecture by @willeastcott in #8870
- Align CollisionComponent with CameraComponent architecture by @willeastcott in #8871
- Add gsplatModifyPS hook for gsplat fragment color customization by @mvaligursky in #8872
- Align ParticleSystemComponent with CameraComponent architecture by @willeastcott in #8873
- Eliminate ComponentData classes and engine schema usage by @willeastcott in #8876
- Share camera property list between init and clone by @willeastcott in #8878
- Drive cloneComponent from shared _properties lists by @willeastcott in #8879
- Hoist property lists in model, sound and rigid-body components by @willeastcott in #8880
- Share animation property list between init and clone by @willeastcott in #8881
- Standardize beforeremove handler naming by @willeastcott in #8882
- Drop shape from shared collision properties, modernize initialize/clone by @willeastcott in #8883
- Remove dead falsy guards in collision shape implementations by @willeastcott in #8884
- Standardize component teardown method to onBeforeRemove by @willeastcott in #8885
- Deduplicate rigid body / trigger rebuild in collision by @willeastcott in #8886
- Add user varying streams to gsplat shader customization by @mvaligursky in #8887
- Correct JSDoc visibility tags on internal collision methods by @willeastcott in #8888
- Promote JointComponent to public API with typed joints by @willeastcott in #8891
- Split rigid-body data classes into separate modules by @willeastcott in #8897
- Cover reparenting an element after its screen is destroyed by @willeastcott in #8899
- Remove dead and broken GamePads previous getter by @willeastcott in #8900
- Source geometry from work buffer for SOG spherical harmonics updates by @mvaligursky in #8902
- Move XR per-view data from the XR manager to the Camera (RenderView) by @mvaligursky in #8907
- Apply gsplat scene settings in applySceneSettings by @mvaligursky in #8909
- Allow ArrayBuffer in StorageBuffer.write data type by @mvaligursky in #8911
- Update @webgpu/types to 0.1.70 and migrate deprecated type names by @mvaligursky in #8912
- Extract GSplatWorld from GSplatManager by @mvaligursky in #8916
- Document transient attachment validation invariants by @mvaligursky in #8918
- Decouple gsplat streaming from rendering for autoRender=false by @mvaligursky in #8919
- Remove unused JSDoc @import lines from sound and rigid-body components by @mmjinglin163 in #8920
- Remove the gsplat compute renderer by @mvaligursky in #8921
- Report minified bundle size changes on PRs by @mvaligursky in #8922
- Move GPU sort/cull pipeline into the hybrid gsplat renderer by @mvaligursky in #8924
- Use lossless RGBA32U fallback instead of pack8 for particles by @mvaligursky in #8926
- Drop redundant particle material reset on camera change by @mvaligursky in #8928
- Throttle concurrent asset requests by @mvaligursky in #8929
- Support dynamic cookie textures with clustered lighting by @mvaligursky in #8930
- Cast directional shadows from the hybrid gsplat renderer by @mvaligursky in #8933
- Apply vertex-modify to hybrid cast shadows by @mvaligursky in #8937
- Remove highQualitySH option, always use high-quality per-splat SH by @mvaligursky in #8938
- Scalable per-splat culling for hybrid gsplat shadows by @mvaligursky in #8939
- Remove compute-renderer leftovers by @mvaligursky in #8940
- Auto-select GPU sort on WebGPU and promote it to stable by @mvaligursky in #8941
- Procedural sky ESM script with day/night cycle and dynamic IBL by @mvaligursky in #8943
- Backend-aware WebXR support detection (isDeviceSupported) by @mvaligursky in #8948
- Remove fragile WebGL mipmap-based radix sort by @mvaligursky in #8949
- Support Draco mesh decoding in Node via worker_threads by @mvaligursky in #8951
- Make app.assets available immediately after AppBase construction by @mvaligursky in #8952
Fixes
- Sort worker ReferenceError after esbuild migration by @mvaligursky in #8808
- Null particle module-scope vars after construction to prevent memory leak by @Skullheadx in #8809
- Fix @param names/types that contradict the function signatures by @willeastcott in #8813
- Expose mesh-level shader defines to the fragment shader by @mvaligursky in #8817
- Update HTML-in-Canvas texture upload to new copyElementImageToTexture/texElementImage2D API by @mvaligursky in #8828
- Apply gsplat material changes made in frame:ready the same frame by @mvaligursky in #8830
- Fix ESM script registration by name and subclass name collision by @mvaligursky in #8831
- Ensure DoF effect is resolution independent (#8833) by @MAG-AdrianMeredith in #8834
- Use a Map for the script registry and guard reserved names in add() by @mvaligursky in #8835
- Preserve live bindings of mutable UMD exports (pc.app) by @mvaligursky in #8837
- Keep UMD exports overridable while preserving live bindings by @mvaligursky in #8839
- Tile gsplat interval-scatter dispatch over workgroup limit by @mvaligursky in #8841
- Register nameless scripts under their verbatim class name by @mvaligursky in #8844
- Remove inline {@link} from camera-frame LUT attribute description by @mvaligursky in #8849
- Fix XrNavigation NaN rig corruption on gamepads without thumbstick axes by @mvaligursky in #8850
- Select scene depth decode via CAPS_TEXTURE_FLOAT_RENDERABLE by @mvaligursky in #8856
- Temporarily disable WebGPU on Imagination PowerVR GPUs (Pixel 10) by @mvaligursky in #8875
- Fix XR over-culling: correct combined frustum and per-eye gsplat visibility by @mvaligursky in #8889
- Reset active WebGL texture unit on device init for reused contexts by @willeastcott in #8894
- Clear cached collisions when a collision component is removed by @willeastcott in #8898
- Report particles isPlaying() in sync with particle lifetime by @willeastcott in #8901
- Fix overestimated WebGPU GPU frame timing in profiler by @mvaligursky in #8903
- Rebuild bind group when its dynamic uniform buffer is re-allocated mid-frame by @mvaligursky in #8906
- Align WebGPU backbuffer format with WebXR projection-layer format by @mvaligursky in #8914
- Keep physics interpolation in sync on teleport for high refresh rates by @willeastcott in #8915
- Don't render previous locale's text with the new font (#3043) by @willeastcott in #8927
- Use mesh UVs when texturing mesh particles (#7858) by @mvaligursky in #8931
- Cull screen-space text by content bounds by @willeastcott in #8934
- Render MSDF text at the true glyph edge by @willeastcott in #8935
- Correct and clarify ElementComponent JSDoc and types by @willeastcott in #8936
- Don't apply hardware depth bias to PCSS shadows by @mvaligursky in #8942
- Upload CPU vertex buffer on rebuild/reset so paused emitters don't render garbage by @willeastcott in #8945
- Support non-interleaved meshes as particle meshes by @willeastcott in #8946
- Support cloning anim components with dynamically-added layers by @willeastcott in #8947
- Fix camera.screenToWorld returning NaN when called in initialize by @mvaligursky in #8950
Examples
- Share dialog with state-encoded URLs by @kpal81xd in #8796
- Author controls as JSX components by @kpal81xd in #8819
- Download example as a standalone Vite project by @kpal81xd in #8825
- Resolve code editor autocomplete, go-to-definition and peek by @kpal81xd in #8826
- Support category: and example: tags in sidebar filter by @kpal81xd in #8829
- Add a GSplat streaming test example, PREFERRED_DEVICE flag, and numSplats accessor by @mvaligursky in #8847
- Add Gaussian Splatting Depth of Field example by @mvaligursky in #8853
- Tune the Depth of Field example (splat budget + WebGPU) by @mvaligursky in #8854
- Add SpAItial AI attribution to the Depth of Field example by @mvaligursky in #8855
- Remove alphabetical import-order requirement from examples lint by @mvaligursky in #8862
- Improve vr-lod XR example and fix XR menu/navigation on hand-tracking devices by @mvaligursky in #8864
- Add Gaussian Splat downtown streaming example by @mvaligursky in #8866
- Serve gsplat example data over the CDN by @mvaligursky in #8867
- Add gsplat shader rings example using the gsplatModifyPS hook by @mvaligursky in #8877
- Add noise-based dissolve shader effect for gaussian splats by @mvaligursky in #8890
- Restore MiniStats panel after hot reload by @willeastcott in #8896
- Add UI element masking example by @mvaligursky in #8923
- Show resolved gsplat renderer in dropdown at startup by @mvaligursky in #8953
- Make gsplat VR LOD example visible in Gaussian Splatting section by @mvaligursky in #8954
Engine Dependencies
- Update actions/github-script action to v9 in #8857
- Update dependency esbuild to v0.28.1 [security] in #8892
- Update dependency vite to v8.0.16 [security] in #8913
- Update actions/checkout action to v7 in #8925
- Update all npm dependencies in #8944
Contributors
New Contributors
- @Skullheadx made their first contribution in #8809
- @mmjinglin163 made their first contribution in #8920
Full Changelog: v2.19.7...v2.20.0