v2.17.0

playcanvas/enginev2.17.0Mar 6, 2026by mvaligursky

AI Summary

Feature release with major GSplat improvements including GPU-driven sorting, half-precision support, global splat budget management, and new Color Enhance post-processing effect.

Key Highlights

  • Add Color Enhance post-processing effect with midtones control
  • Implement GPU-driven sorting and frustum culling for GSplat on WebGPU
  • Add global splat budget for scene-wide GSplat LOD management
  • Add half-precision (f16) type aliases for WGSL shaders
  • Add BlockAllocator for 1D block memory management

New Features

  • Color Enhance post-processing effect
  • Global splat budget for GSplat LOD management
  • GPU-driven sorting and frustum culling pipeline
  • Half-precision (f16) support in WGSL shaders
  • Interval-based GPU compaction for GSplat
  • Per-node block allocation for GSplats
  • FrontFace support in render pipeline
  • Exposed dracoDecode for decoder reuse

Full Release Notes

## Changes

* Half-precision (f16) type aliases for WGSL shaders by @mvaligursky in #8439
* Gaussian Splatting: Use half-precision for spherical harmonics evaluation on WebGPU by @mvaligursky in #8441
* Add Color Enhance post-processing effect by @mvaligursky in #8443
* Improve scene texture error messages to mention CameraFrame by @mvaligursky in #8446
* Global splat budget for scene-wide GSplat LOD management by @mvaligursky in #8444
* Material.meshInstances change to Set for faster MeshInstance removal by @Maksims in #8451
* GSplat: GPU-driven sorting and frustum culling pipeline on WebGPU by @mvaligursky in #8453
* Replace interval texture binary search with instanced quad rendering for GSplat work buffer copy by @mvaligursky in #8456
* Refactor data texture creation using internal Texture helper by @mvaligursky in #8457
* Add midtones control to Color Enhance post-effect by @mvaligursky in #8458
* Improve MiniStats VRAM reporting and graph grouping by @mvaligursky in #8460
* Only emit written color outputs in WGSL FragmentOutput struct by @slimbuck in #8465
* Expose WebGPU texture format tier capabilities by @mvaligursky in #8459
* Use half-precision (f16) in gsplat WGSL shaders by @slimbuck in #8466
* Skip padding pixels during GSplat sorting and rendering by @mvaligursky in #8471
* Exclude skinned and morphed mesh instances from batching by @mvaligursky in #8477
* Interval-based GPU compaction for GSplat rendering by @mvaligursky in #8476
* Remove double indirection from GSplat rendering by @mvaligursky in #8478
* Improved error reporting when a bind group value is missing by @mvaligursky in #8479
* Compact GSplat work buffer format by @mvaligursky in #8480
* Add BlockAllocator for 1D block memory management by @mvaligursky in #8481
* Extract NumericIds from PickerId for reusable ID generation by @mvaligursky in #8482
* Switch gsplat work buffer from row-aligned to pixel-offset layout by @mvaligursky in #8484
* Use UploadStream for GSplat sort order uploads by @slimbuck in #8487
* Remove STORAGE_ORDER shader define by @slimbuck in #8488
* Cache validated FBO configurations in debug builds by @mvaligursky in #8491
* Per-node block allocation and partial work buffer updates for GSplats by @mvaligursky in #8490
* Skip pcNodeIndex work buffer stream when GPU sorting is active by @mvaligursky in #8492
* Optimize GSplat work buffer rebuilds and block allocator fragmentation by @mvaligursky in #8493
* Add MiniStats stat presets for gsplat stats by @mvaligursky in #8495
* Expose `dracoDecode` for decoder reuse by @koteelok in #8470
* Add frontFace support to render pipeline by @AlexAPPi in #8448
* Add debug assert for texture upload inside render pass on WebGPU by @mvaligursky in #8504
* FrontFace follow-up: fix double-flip, remove twoSidedLightingNegScaleFactor, add setDrawStates by @mvaligursky in #8503
* Estimate total size for unreported assets in SOG progress tracking by @slimbuck in #8502
* Use half-precision types in bloom downsample/upsample WGSL shaders by @mvaligursky in #8508
* Improve GSplat LOD system with geometric progression, FOV compensation, and budget balancing fixes by @mvaligursky in #8506
* Skip CAS HDR conversions for LDR input and use half-precision in WGSL by @mvaligursky in #8509

## Fixes

* Fix chromatic fringing shader undefined behavior with negative values by @mvaligursky in #8438
* GsplatResourceBase.getTexture needs to be public by @mvaligursky in #8442
* Inline WGSL resolveCodebook to fix Firefox naga compatibility by @mvaligursky in #8450
* Refresh texture state when toggling mipmaps by @willeastcott in #8455
* Fix clustered lighting packed decode stability on Samsung WebGL by @mvaligursky in #8461
* Fix annotation hotspot sizing by @slimbuck in #8463
* Fix WebGL readTextureAsync allocating too much memory for outputData by @slimbuck in #8472
* Prevent setLayout from corrupting interval compaction data by @mvaligursky in #8485
* Fix frame-rate dependent camera rotation and zoom in CameraControls by @slimbuck in #8494
* Fix GSplat LOD re-evaluation when params change via frame:ready event by @mvaligursky in #8498
* Fix WebGPU staging buffer error in non-unified GSplat sorter by @mvaligursky in #8499
* Fire GSplatSorter 'updated' event immediately for renderNextFrame support by @mvaligursky in #8500
* Fix MiniStats VRAM subcategories not hiding on collapse by @mvaligursky in #8507

## Examples

* Fix flipbook example playback speed by @mvaligursky in #8505

## Engine Dependencies
* Update all npm dependencies in #8467
* Update all npm dependencies (major) in #8468
* Update dependency sinon to v21.0.1 in #8469
* Update github artifact actions (major) in #8486

### Contributors

* @AlexAPPi
* @koteelok
* @Maksims
* @mvaligursky
* @slimbuck
* @willeastcott

## New Contributors
* @koteelok made their first contribution in #8470
* @AlexAPPi made their first contribution in #8448

**Full Changelog**: https://github.com/playcanvas/engine/compare/v2.16.2...v2.17.0