playcanvas/engine
 Watch   
 Star   
 Fork   
2026-04-28 17:46:21
engine

v2.18.1

Fixes

  • Split batches by castShadow and shadowCascadeMask by @mvaligursky in #8650
  • Use unsigned 32-bit depth bits when reconstructing pick depth from RGBA8 by @slimbuck in #8651
  • Defer WebGPU buffer destruction until after pending command buffers are submitted by @slimbuck in #8652

Contributors

  • @mvaligursky
  • @slimbuck

Full Changelog: https://github.com/playcanvas/engine/compare/v2.18.0...v2.18.1

2026-04-17 19:44:19
engine

v2.18.0

Changes

  • Remove per-resource instance vertex buffer from GSplat rendering by @mvaligursky in #8513
  • Expose GSplat rendering properties on GSplatParams by @mvaligursky in #8518
  • Add HTML-in-Canvas support with texElementImage2D and interactive hit testing by @mvaligursky in #8519
  • Refactor GSplatRenderer into base class with GSplatQuadRenderer derived class by @mvaligursky in #8520
  • Refine GSplatRenderer API: rename methods for clarity by @mvaligursky in #8522
  • Extract FramePass base class from RenderPass by @mvaligursky in #8523
  • Add WebGPU subgroup operations support by @mvaligursky in #8528
  • Optimize GPU radix sort with bitmask ranking and multi-element processing by @mvaligursky in #8529
  • Add compute-based tiled GSplat renderer (WebGPU) by @mvaligursky in #8531
  • Add local compute GSplat renderer and dynamic buffer sizing (WebGPU) by @mvaligursky in #8536
  • Replace full-screen quad composite with tile-based indirect draw in local compute GSplat renderer by @mvaligursky in #8544
  • Add orthographic camera support to compute GSplat renderers by @mvaligursky in #8545
  • Improve compute GSplat rendering and add tonemapping support by @mvaligursky in #8546
  • Support dynamic work buffer formats in compute GSplat renderers by @mvaligursky in #8547
  • Remove redundant shader includes from ShaderUtils.createShader callers by @slimbuck in #8551
  • Add WebGPU Bare device type for testing without optional features by @mvaligursky in #8555
  • Add picking support and fix color pipeline in local compute GSplat renderer by @mvaligursky in #8556
  • Remove global compute GSplat renderer by @mvaligursky in #8558
  • Remove per-splat GPU compaction for CPU sort path by @mvaligursky in #8559
  • Extract GSplatFrustumCuller from GSplatWorkBuffer by @mvaligursky in #8560
  • Merge frustum culling into compute, convert to storage buffers, fix >16M splat dispatch by @mvaligursky in #8561
  • Make frustum culling always-on and remove dead pcNodeIndex pipeline by @mvaligursky in #8562
  • Reduce register pressure in compute GSplat TileCount projection by @mvaligursky in #8563
  • Store conic form in projection cache to avoid per-tile conversion by @mvaligursky in #8565
  • Add GSplatParams.renderer enum for runtime renderer selection by @mvaligursky in #8567
  • Remove centers array dependency from GSplatInfo interval check by @mvaligursky in #8568
  • Add minContribution property for compute GSplat contribution culling by @mvaligursky in #8571
  • Increase default minContribution from 2 to 3 by @mvaligursky in #8575
  • Add fisheye projection for Gaussian splats by @mvaligursky in #8576
  • Add fisheye projection support for skybox by @mvaligursky in #8577
  • Refactor rasterize variant management and beforePasses scheduling by @mvaligursky in #8579
  • Add depth testing for compute GSplat renderer when CameraFrame depth prepass is enabled by @mvaligursky in #8581
  • Simplify Camera.beforePasses to a plain FramePass array by @mvaligursky in #8582
  • Add fog support for Gaussian splat rendering by @mvaligursky in #8583
  • Replace atomic scatter with pair-buffer tile binning and cooperative large-splat processing by @mvaligursky in #8586
  • Split viewDepth into separate depthBuffer for sort cache locality by @mvaligursky in #8587
  • Move FisheyeProjection to scene/graphics for shared use by @mvaligursky in #8588
  • Modernize README and improve npm discoverability by @willeastcott in #8591
  • Remove Bundlephobia badge from READMEs by @willeastcott in #8592
  • Per-node granular SH color updates with angle-based threshold by @mvaligursky in #8593
  • Optimize tile-count pass with multi-splat threads and extract dispatch prep shaders by @mvaligursky in #8594
  • Remove workgroup-level early-out atomics from rasterize pass by @mvaligursky in #8596
  • Vectorize Gaussian evaluation across 2x2 pixel quad in rasterize pass by @mvaligursky in #8597
  • Unify GSplat debug rendering into a single enum-based API by @mvaligursky in #8598
  • Add heatmap debug mode for compute GSplat rasterizer by @mvaligursky in #8599
  • Revert tile-count pass to single-splat-per-thread by @mvaligursky in #8603
  • Decouple compute GSplat renderer from work buffer via setDataSource by @mvaligursky in #8605
  • Add shader defines for prepass to support alpha test and dithered opacity by @slimbuck in #8606
  • Improve GSplat compute renderer cold-start buffer capacities by @mvaligursky in #8610

Fixes

  • Reset render pass merge flags each frame in FrameGraph.compile() by @mvaligursky in #8516
  • Fix TAA ghosting artifacts on WebGPU by @mvaligursky in #8517
  • Prevent division by zero in CAS sharpening shader by @slimbuck in #8532
  • Preserve blend state in drawQuadWithShader / RenderPassQuad by @mvaligursky in #8535
  • Fix double decrement of octree file ref counts on entity disable by @mvaligursky in #8537
  • Use y-first approach in Compute.calcDispatchSize to minimize wasted workgroups by @mvaligursky in #8538
  • Round up compressed texture dimensions to block size on WebGPU by @mvaligursky in #8540
  • Replace StopThePop tile intersection with exact FlashGS method in compute GSplat by @mvaligursky in #8548
  • Smooth Gaussian falloff for capped splat radii in compute renderer by @mvaligursky in #8549
  • Avoid workgroupUniformLoad on atomic type for iOS WGSL compatibility by @mvaligursky in #8552
  • Use unfilterable-float sample type for RGBA32F textures in node culling shader by @mvaligursky in #8553
  • Use unfilterable-float sample type for RGBA32F GSplat textures on WebGPU by @mvaligursky in #8554
  • Pass alphaClip to scatter pass instead of hardcoding 1/255 by @mvaligursky in #8564
  • Match quad renderer near-plane behavior in compute GSplat renderer by @mvaligursky in #8566
  • Match raster minPixelSize culling threshold in compute GSplat renderer by @mvaligursky in #8569
  • Use logarithmic depth quantization in compute GSplat bitonic sort by @mvaligursky in #8570
  • Match raster Gaussian radius cap in compute GSplat renderer by @mvaligursky in #8573
  • Improve compute GSplat tile entry buffer scaling to reduce overflow artifacts by @mvaligursky in #8574
  • Preserve layerPlacementsDirty flag when octree placements are removed by @mvaligursky in #8584
  • Include fresnelSchlick chunk when refraction is enabled without specular by @willeastcott in #8595
  • Suppress frame:ready until full LOD update after param changes by @mvaligursky in #8602

Examples

  • Fix FOV slider default value in LOD streaming example by @mvaligursky in #8510
  • Hide test two-sided lighting example thumbnails by @mvaligursky in #8511
  • Add radial sorting toggle to LodStreaming example by @mvaligursky in #8515
  • Add clear button to examples sidebar filter input by @mvaligursky in #8541
  • Limit examples sidebar to left half of screen on mobile by @mvaligursky in #8542
  • Use consistent XR session check for viewport sizing and add stereo GSplat test example by @mvaligursky in #8557
  • Add URL input and orientation controls to LOD streaming example by @mvaligursky in #8572
  • Add procedural weather particle system example using Gaussian splats by @mvaligursky in #8580
  • Add renderer selection UI to all Gaussian splat examples by @mvaligursky in #8585
  • Add environment map and metallic reflections to html-texture example by @mvaligursky in #8589
  • Add URL parameter support to LOD streaming example by @mvaligursky in #8590
  • Add GPU compute benchmark and GSplat benchmark example by @mvaligursky in #8600
  • Add cloud shadows shader chunk override example by @mvaligursky in #8604
  • Replace share buttons with save buttons in GSplat benchmark example by @mvaligursky in #8608

Engine Dependencies

  • Update rollup to v4.59.0 (security) in #8483

Contributors

  • @mvaligursky
  • @slimbuck
  • @willeastcott

Full Changelog: https://github.com/playcanvas/engine/compare/v2.17.2...v2.18.0

2026-03-19 23:25:52
engine

v2.17.2

Fixes

  • Preserve blend state in drawQuadWithShader / RenderPassQuad by @mvaligursky in #8535
  • Fix double decrement of octree file ref counts on entity disable by @mvaligursky in #8537
  • Use y-first approach in Compute.calcDispatchSize to minimize wasted workgroups by @mvaligursky in #8538

Contributors

  • @mvaligursky

Full Changelog: https://github.com/playcanvas/engine/compare/v2.17.1...v2.17.2

2026-03-16 23:54:11
engine

v2.17.1

Fixes

  • Correct TAA temporal reprojection on WebGPU by @mvaligursky in #8517
  • Reset render pass merge flags each frame in FrameGraph.compile() by @mvaligursky in #8516
  • Prevent division by zero in CAS sharpening shader by @slimbuck in #8532

Examples

  • LodStreaming example has Radial sorting toggle by @mvaligursky in #8515

Contributors

  • @mvaligursky
  • @slimbuck

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

2026-03-07 00:18:01
engine

v2.17.0

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

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

2026-02-24 20:45:23
engine

v2.16.2

Fixes

  • Fix GsplatResourceBase.getTexture to be public by @mvaligursky in #8442
  • Inline WGSL resolveCodebook to fix Firefox naga compatibility by @mvaligursky in #8450
  • Move clustered packed values out of light struct for Samsung WebGL precision/corruption issues by @mvaligursky in #8461
  • Only emit written color outputs in WGSL FragmentOutput struct by @slimbuck in #8465
  • Fix annotation hotspot sizing by @slimbuck in #8463
  • Fix WebGL readTextureAsync allocating too much memory for output data by @slimbuck in #8472
  • Exclude skinned and morphed mesh instances from batching by @mvaligursky in #8477

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

2026-02-04 17:51:30
engine

v2.16.1

Fixes

  • Fix chromatic fringing shader undefined behavior with negative values by @mvaligursky in #8438

Full Changelog: https://github.com/playcanvas/engine/compare/v2.16.0...v2.16.1

2026-02-03 22:16:54
engine

v2.16.0

Changes

Fixes

Examples

Full Changelog: https://github.com/playcanvas/engine/compare/v2.15.3...v2.16.0

2026-01-28 23:29:19
engine

v2.15.3

Fixes

  • Revert Fix ElementComponent ‘mousemove’ event firing outside element by @willeastcott in #8413

Full Changelog: https://github.com/playcanvas/engine/compare/v2.15.2...v2.15.3

2026-01-26 22:56:51
engine

v2.15.2

Fixes

  • Fix XrInputSource crash when grip unavailable by @willeastcott in #8389
  • Fix controller models in XR movement example by @willeastcott in #8390
  • Fix XrInputSource JSDoc errors and redundant code by @willeastcott in #8391
  • Fix duplicate XrViews instance and clean up handler in XrManager by @willeastcott in #8392
  • Fix WebXR stereo frustum culling by @willeastcott in #8393
  • Add XrMenu script and example for WebXR hand/controller menus by @willeastcott in #8407
  • Fix account for camera local offset in XrNavigation teleport by @willeastcott in #8409
  • Improve XrControllers script robustness and documentation by @willeastcott in #8410
  • Correct vertex format mismatch when decoding Draco meshes by @willeastcott in #8394

Full Changelog: https://github.com/playcanvas/engine/compare/v2.15.1...v2.15.2