playcanvas/engine
 Watch   
 Star   
 Fork   
1 days ago
engine

v2.23.2

Fixes

  • Stream gsplat LOD levels coarsest first across the whole view by @mvaligursky in #9694
  • Keep the Node worker_threads require out of bundled worker code by @mvaligursky in #9656
  • Keep the canvas resolution when its client size is zero by @mvaligursky in #9671
  • Skip the MiniStats draw when it has nothing to render by @mvaligursky in #9672

Full Changelog: https://github.com/playcanvas/engine/compare/v2.23.1...v2.23.2

3 days ago
engine

v2.23.1

Fixes

  • Fix apps not being announced to the devtools hook from every build by @mvaligursky in #9646
  • Keep MiniStats sized to the canvas when it resizes without a resizecanvas event by @slimbuck in #9661
  • Do not fire tween events that have no name by @mvaligursky in #9650
  • Resolve the inspector's engine peer to the linked engine by @mvaligursky in #9641

Full Changelog: https://github.com/playcanvas/engine/compare/v2.23.0...v2.23.1

9 days ago
engine

v2.23.0

Changes

  • Add distanceSq by @AlexAPPi in #9313
  • Add useFog/useTonemap to ParticleSystemComponent, deprecate noFog by @mvaligursky in #9340
  • Load audio assets regardless of the URL's file extension by @mvaligursky in #9365
  • Poll gamepads every frame without allocating by @willeastcott in #9470
  • Run the engine headless in Node.js without jsdom by @willeastcott in #9504
  • Replace batch.origMeshInstances[0] with sourceMeshInstance variable by @AlexAPPi in #9454

Rendering

  • Store mesh instance matrices in a persistent storage buffer on WebGPU by @mvaligursky in #9614
  • Add a bloom threshold to CameraFrame by @mvaligursky in #9455
  • Add per-attachment clear colors to the camera for multiple render targets by @mvaligursky in #9333
  • Support stencil clears inside a render pass on WebGPU by @mvaligursky in #9612
  • Allow camera viewports extending past the render target on WebGPU by @mvaligursky in #9516
  • Add partial vertex and index buffer uploads by @mvaligursky in #9401
  • Add screen_size to forward view uniforms and deprecate uScreenSize by @mvaligursky in #9331
  • Pack forward view uniforms to reduce alignment padding by @mvaligursky in #9332
  • Move per-pass uniforms into the view uniform buffer by @mvaligursky in #9582
  • Move textureBias into the view uniform buffer by @mvaligursky in #9484
  • Supply per-pass textures through the WebGPU view bind group by @mvaligursky in #9521
  • Publish the scene environment textures under their own uniforms by @mvaligursky in #9364
  • Add an opt-in std140 packing order to UniformBufferFormat by @mvaligursky in #9400
  • Stop creating typed array views for every dynamic uniform buffer update by @mvaligursky in #9418
  • Retain WebGPU render pipelines between draws by @mvaligursky in #9380
  • Look the WebGPU render pipeline up only when its state changes by @mvaligursky in #9492
  • Write WebGPU buffer data directly from its storage by @mvaligursky in #9379
  • Pass WebGPU bind group dynamic offsets as a typed array by @mvaligursky in #9487
  • Skip WebGPU vertex and index buffer binds the render pass already has by @mvaligursky in #9496
  • Keep the backing store of the device vertex buffer list across draws by @mvaligursky in #9498
  • Assign bind group slots by index during the update by @mvaligursky in #9425
  • Split the bind group update into a scope path and an owner path by @mvaligursky in #9429
  • Leave a texture out of the mesh bind group when a supplied group has it by @mvaligursky in #9436
  • Let the graphics device own the built-in textures by @mvaligursky in #9438
  • Rebuild layer mesh arrays lazily after removals by @mvaligursky in #9378
  • Pack the mesh instance light mask into 8 bits, for 24 shader define flags by @mvaligursky in #9617
  • Rename supportsUniformBuffers to usesMeshBindGroups by @mvaligursky in #9383
  • Split WebGPU device creation from device initialization by @mvaligursky in #9483
  • Ignore MeshInstance#setIndirect where indirect draw is not supported by @mvaligursky in #9462
  • Remove obsolete immediate mesh rendering by @mvaligursky in #9385
  • Remove the shader dump and precompile workflow by @mvaligursky in #9477
  • Remove obsolete Mac Chrome blitFramebuffer workaround by @mvaligursky in #9318
  • Remove obsolete Safari texture unit workaround by @mvaligursky in #9319

Lighting & Shadows

  • Move light uniforms into the view uniform buffer, uploaded once per pass by @mvaligursky in #9482
  • Give every light an absolute slot, shared by all light masks by @mvaligursky in #9475
  • Dispatch the lights of a pass once, not per light mask by @mvaligursky in #9479
  • Consolidate light slots into a LightList shared by renderer, shaders and lightmapper by @mvaligursky in #9481
  • Make world-cluster allocation request/execute based by @mvaligursky in #9473
  • Fade directional shadows at the far distance by @mvaligursky in #9417
  • Skip shadow sampling beyond the far distance by @mvaligursky in #9419
  • Request directional shadow culling from scheduled render passes by @mvaligursky in #9423
  • Request local shadow culling from scheduled render passes by @mvaligursky in #9428
  • Cull only requested directional shadow cascades by @mvaligursky in #9437
  • Skip spot VSM blur when the shadow pass does not execute by @mvaligursky in #9440
  • Set shadow caster material state once per material run by @mvaligursky in #9524
  • Derive the normal matrix of shader materials in the shadow pass by @mvaligursky in #9585
  • Give a mesh instance lightmap its own texture slot by @mvaligursky in #9415
  • Bind only the lightmap slots a bake writes by @mvaligursky in #9420
  • Fix shadow shader selection when changing cascade count by @mvaligursky in #9343
  • Reset clustered shadow lights before preparing each frame by @mvaligursky in #9414
  • Fix WebGPU shadow shader compile error for PCSS spot lights by @mvaligursky in #9545
  • Pass an empty LightList, not 0, to the shadow pass shaders by @willeastcott in #9556
  • Hidden mesh instances with culling disabled no longer cast shadows by @mvaligursky in #9606

Materials

  • Add a material bind group slot and cached shader processing keys by @mvaligursky in #9370
  • Hold the textures of a material in its own bind group by @mvaligursky in #9457
  • Bind the material bind group at a material switch instead of at every draw by @mvaligursky in #9413
  • Store StandardMaterial diffuse in a material-owned uniform buffer by @mvaligursky in #9381
  • Store emissive color and intensity in the material uniform buffer by @mvaligursky in #9392
  • Store the remaining StandardMaterial colors and numbers in the material uniform buffer by @mvaligursky in #9398
  • Store the derived StandardMaterial uniforms in the material uniform buffer by @mvaligursky in #9402
  • Store the texture map transforms in the material uniform buffer by @mvaligursky in #9405
  • Store the cube map projection box in the material uniform buffer by @mvaligursky in #9406
  • Copy the cube map projection box into the material instead of keeping a reference by @mvaligursky in #9411
  • Support mesh instance overrides of material uniform buffer values by @mvaligursky in #9386
  • Let a mesh instance override a texture of the material bind group by @mvaligursky in #9445
  • Restore global scope values after mesh instance parameter overrides by @mvaligursky in #9588
  • Warn in debug builds when a mesh instance override array changes in place by @mvaligursky in #9395
  • Warn about material and mesh instance parameters of view uniforms by @mvaligursky in #9619
  • Add support for all eight UV sets in StandardMaterial by @mvaligursky in #9376
  • Make alphaTest an accessor of Material and retire the generic float property helper by @mvaligursky in #9408
  • Separate sprite color from material uniforms by @mvaligursky in #9337
  • Separate UI element colors from material uniforms by @mvaligursky in #9338
  • Pass the model scale to dynamic refraction from the vertex shader by @mvaligursky in #9616
  • Fix LitMaterial ambient by making the ambient tint a lit argument by @mvaligursky in #9538
  • Fix StandardMaterial shader invalidation for environment textures and 0/1 number changes by @mvaligursky in #9359
  • Fix StandardMaterial shader invalidation for refraction thresholds by @mvaligursky in #9363
  • Make StandardMaterial texture map iteration ignore prototype properties by @mvaligursky in #9368
  • Stop placeholder textures from forcing shader recompiles by @mvaligursky in #9592

Gaussian Splatting

  • Make gsplat LOD distance-only, with target or limit splat budgets by @mvaligursky in #9584
  • Only judge oversized gsplat LOD nodes by their middle by @mvaligursky in #9586
  • Gsplat LOD: empty level for nodes without coarse data; distance default by @mvaligursky in #9326
  • Load streamed gsplat LOD files nearest the camera first by @mvaligursky in #9520
  • Update StreamedGSplat presets to use LOD falloff by @mvaligursky in #9369
  • Stochastic alpha rendering for the GPU-sort gsplat renderer by @slimbuck in #9443
  • Flat per-splat gsplat varyings and fix ComputeRadixSort reallocation on growth by @slimbuck in #9372
  • Allow either provoking vertex for WGSL splat varyings by @mvaligursky in #9374
  • Prefer first provoking vertex on WebGL by @mvaligursky in #9375
  • Use a per-axis focal length for the gsplat footprint by @dfattal in #9486
  • Skip compute work for cached Gaussian splat shadows by @mvaligursky in #9416
  • Make Gaussian splatting GLB support tree-shakeable by @mvaligursky in #9327
  • Make GSplat scene parameters tree-shakeable by @mvaligursky in #9328
  • Avoid retaining GSplat work buffer shaders in container bundles by @mvaligursky in #9322
  • Apply withCredentials to the gsplat loaders that stream with fetch by @mvaligursky in #9458
  • Warn when gaussian splats render into a multisampled target by @mvaligursky in #9532
  • Fix gsplat GPU sort flicker from sort key precision loss by @mvaligursky in #9493
  • Fix mirrored gsplat footprints in flipped render targets by @mvaligursky in #9490
  • Fix fisheye gsplats and sky in flipped render targets by @mvaligursky in #9495
  • Correct gsplat spherical harmonics with orthographic cameras by @mvaligursky in #9531
  • Fix NVIDIA GPU hangs during gsplat depth picking by @slimbuck in #9572
  • Prevent gsplat crash after destroying a splat entity by @mvaligursky in #9522
  • Prevent gsplat streaming crash after destroying a camera by @mvaligursky in #9533
  • Render gsplats again after a camera re-adds their layer by @mvaligursky in #9535
  • Keep gsplat placement changes made in frame:ready handlers by @mvaligursky in #9536
  • Stop a gsplat from blanking for a frame when its asset is replaced by @willeastcott in #9610

Physics

  • Add RigidBodyComponent#gravityScale by @willeastcott in #9465
  • Add a hitBackFaces raycast option to skip mesh collider back faces by @willeastcott in #9506
  • Tighten the public surface of the physics API by @willeastcott in #9519
  • Harden physics raycasts and forward the Application physicsWorld option by @willeastcott in #9517
  • Ship an Ammo build whose heap starts at 16MB and grows on demand by @willeastcott in #9488
  • Route the Ammo internal tick callback through one dispatcher per module by @willeastcott in #9463
  • Apply gravity to the physics backend on install and when it changes by @willeastcott in #9439
  • Refresh Ammo broadphase bounds when a body is teleported by @willeastcott in #9489
  • Mirror mesh colliders with negative scale factors by @willeastcott in #9499
  • Keep the orientation of mirrored dynamic bodies across physics steps by @willeastcott in #9500
  • Fix mesh colliders sharing a mesh at different scales and rebuild them on scale changes by @willeastcott in #9311
  • Sync compound children from their own transforms, not the root's dirty flag by @willeastcott in #9456
  • Rebuild a collision component as a trigger when its rigid body is removed by @willeastcott in #9464
  • Give both entities of a contact the normal of the other surface by @willeastcott in #9450

XR

  • Stop a double XR start from leaving a broken session by @willeastcott in #9599
  • Stop the app freezing when an XR session ends by @willeastcott in #9600
  • Stop XR culling from using the previous frame's head pose by @willeastcott in #9601
  • Remove XR event listeners that outlive their owners by @willeastcott in #9623
  • Apply camera clip plane changes to a running XR session by @willeastcott in #9624
  • Correct XR input source rays and velocities by @willeastcott in #9625
  • Start XrSession sessions facing the way the camera looks by @willeastcott in #9626
  • Keep removed XR planes and meshes readable, and harden hit testing by @willeastcott in #9627
  • Keep XrControllers models loaded while input sources share them by @willeastcott in #9631
  • Hide XrControllers models while their pose is not tracked by @willeastcott in #9635
  • Stop XrNavigation teleporting on system menu gestures by @willeastcott in #9636
  • Document the XR select events of ElementComponent by @willeastcott in #9633

UI

  • Warn when image materials have no opaque render pass by @mvaligursky in #9346
  • Keep an element's position when it is added to an entity under a screen by @willeastcott in #9525
  • Let ElementDragHelper drag an element that is a direct child of a screen by @willeastcott in #9551
  • Update a scrollbar's handle when its track is resized by @willeastcott in #9573
  • Fix layout group subscriptions when components change by @mvaligursky in #9399
  • Build text meshes without a pass over empty arrays by @willeastcott in #9562
  • Skip drawing text with an empty render range by @willeastcott in #9567
  • Draw CanvasFont glyph cells fully transparent by @willeastcott in #9568
  • Fix a markup parser crash when a tag name shadows hasOwnProperty by @willeastcott in #9468
  • Correct UI component docs, the Spanish locale fallback and button examples by @willeastcott in #9552

Device Recovery

  • Restore WebGPU rendering resources after device loss by @mvaligursky in #9355
  • Restore WebGPU profiling after device loss by @mvaligursky in #9357
  • Fix WebGPU recovery for compute, readback and generated data by @mvaligursky in #9358
  • Cancel WebGPU recovery when the device is destroyed by @mvaligursky in #9397
  • Fix WebGPU resource cleanup on device destruction by @mvaligursky in #9394
  • Restore the WebGL backbuffer before recovery callbacks by @mvaligursky in #9347
  • Recover SOG streaming across WebGL context loss by @mvaligursky in #9350
  • Restore procedural sky lighting after device recovery by @mvaligursky in #9351
  • Add cross-backend debug device loss testing by @mvaligursky in #9353
  • Restore generated HDR environments in examples after device loss by @mvaligursky in #9345
  • Redraw the on-demand splat example after device recovery by @mvaligursky in #9348
  • Rebake example lightmaps after device recovery by @mvaligursky in #9352

Profiling & Debugging

  • Redesign MiniStats with compact and grouped profiling views by @mvaligursky in #9307
  • Add collapsible MiniStats sections by @mvaligursky in #9361
  • Add tracked resource counts to MiniStats by @mvaligursky in #9366
  • Expose application performance statistics through AppStats by @mvaligursky in #9308
  • Add user counters to AppStats by @mvaligursky in #9341
  • Correct MiniStats timing and build availability documentation by @mvaligursky in #9310
  • Add TextureRenderer for debug texture previews by @mvaligursky in #9382
  • Add per-camera culling and display fixes to TextureRenderer by @mvaligursky in #9387
  • Add a debug-engine draw limit for stepping through a render pass by @mvaligursky in #9501
  • Add descriptive GPU profiling names for quad passes by @mvaligursky in #9329
  • Track shaders on every graphics device by @mvaligursky in #9466
  • Add a bare WebGL 2 device type for testing on constrained devices by @mvaligursky in #9471
  • Announce apps to a devtools hook by @mvaligursky in #9618
  • Add AppOptions#devtools to opt out of the devtools hook by @mvaligursky in #9637

Fixes

  • Add missing TEXTURE_2D_ARRAY entry to targetToSlot by @mvaligursky in #9321
  • Fix sprite tint color space conversion by @mvaligursky in #9334
  • Clear keyboard and mouse states on detach and focus loss by @mvaligursky in #9344
  • Reset stale mouse movement deltas by @mvaligursky in #9349
  • Fix WebGPU texture-formats-tier feature names and rename their flags by @mvaligursky in #9390
  • Fix skydome depth of field with scene-pass depth by @mvaligursky in #9391
  • Wait for container meshes before marking render assets ready by @mvaligursky in #9404
  • Fix Picker readback rectangle in the top-left to bottom-left flip by @mvaligursky in #9441
  • Reconstruct the picked world position at the pixel center by @mvaligursky in #9446
  • Call super.frameUpdate() from RenderPassCompose by @mvaligursky in #9449
  • Copy the render style onto a batched mesh instance by @mvaligursky in #9448
  • Fix CameraComponent#setShaderPass() throwing when resetting the pass by @mvaligursky in #9451
  • Resolve glb model resources against the directory of the glb by @mvaligursky in #9453
  • Stop leaking a DrawCommands set per indirect draw per frame by @mvaligursky in #9459
  • Fix bundle asset load retrying and error-response handling by @mvaligursky in #9460
  • Fix the WebGL multi-draw fallback submitting no draws by @mvaligursky in #9461
  • Treat every 2xx HTTP status as success by @willeastcott in #9507
  • Accept status 0 responses from non-http schemes by @willeastcott in #9508
  • Fix Curve.closest outside unit range by @humairaambreen in #9543
  • Return the first key from Curve#closest for times before the curve by @willeastcott in #9544
  • Accept mesh instances without a material in Layer#addMeshInstances by @mvaligursky in #9579
  • Skip disabled entities in OutlineRenderer by @mvaligursky in #9452
  • Fix OutlineRenderer shader errors when clustered lighting is disabled by @mvaligursky in #9590
  • Fix OutlineRenderer material cleanup and frameUpdate listener leak by @mvaligursky in #9589
  • Fix OutlineRenderer outlines missing with some CameraFrame settings by @mvaligursky in #9594
  • Blur the TAA output in the camera frame's bloom and depth of field by @willeastcott in #9591
  • Fix calculateNormals returning NaN for vertices with no triangle area by @mvaligursky in #9596
  • Fix FloatPacking.float2Half corrupting values too large for a half float by @mvaligursky in #9595
  • Clean up pole and tip triangles in sphere, capsule and cone geometry by @mvaligursky in #9597
  • Keep screen-space particles square on any canvas aspect by @willeastcott in #9570
  • Export skinned meshes to USDZ where their bones place them by @willeastcott in #9546
  • Use the WGSL built-in saturate, fixing lightVertexColor on WebGPU by @mvaligursky in #9598
  • Flip the vertex normal of back faces for two sided lighting by @willeastcott in #9559
  • Initialize GraphicsDevice renderPassIndex to 0 by @mvaligursky in #9605
  • Load cubemap faces given as URLs as sRGB color, not RGBP by @mvaligursky in #9607
  • Fix Texture#lock on cubemap faces and mip levels by @mvaligursky in #9608
  • Fix WebGPU stencil read mask, reuse pipelines across stencil refs by @mvaligursky in #9611
  • Make createGraphicsDevice reject instead of hanging when no device can be created by @willeastcott in #9603
  • Depth state fixes (depthTest, WebGPU depth bias, layer reset) by @mvaligursky in #9615
  • Fix BlendState#setAttachment reviving overrides cleared by copy by @mvaligursky in #9620

Examples

  • Restyle the examples browser by @mvaligursky in #9629
  • Slim the collapsed code pane and hide the code minimap by @mvaligursky in #9632
  • Open the PlayCanvas Inspector in the examples browser by @mvaligursky in #9621
  • Serve the inspector loader as is in the dev server by @mvaligursky in #9638
  • Link a whole examples category by URL by @mvaligursky in #9303
  • Add category sharing and expand-all controls by @mvaligursky in #9356
  • Reveal current example when clearing search by @mvaligursky in #9354
  • Rebuild the UI button, panel, masking and custom shader examples by @willeastcott in #9565
  • Rebuild the UI text examples by @willeastcott in #9566
  • Rebuild the UI layout, image and world examples by @willeastcott in #9569
  • Add the UI input, common widgets and drag and drop examples by @willeastcott in #9571
  • Add a hidden test example for UI element states by @mvaligursky in #9580
  • Add rendering without entities example by @mvaligursky in #9377
  • Add environment sources test example by @mvaligursky in #9360
  • Give the render to image example a knight of its own by @willeastcott in #9583
  • Refresh the MiniStats example scene by @mvaligursky in #9309
  • Migrate examples to TextureRenderer by @mvaligursky in #9384
  • Load the VAT character data as a binary asset in the vat-characters example by @mvaligursky in #9518
  • Render gaussian splat crop and depth-of-field examples without MSAA by @mvaligursky in #9634
  • Restore the depth prepass in the gaussian splat depth-of-field example by @mvaligursky in #9639
  • Apply area-picker example material changes via update() by @mvaligursky in #9497
  • Remove no-op bloom.enabled writes from examples by @mvaligursky in #9476
  • Replace the Arial and Courier fonts of the examples and tests with Roboto by @willeastcott in #9577
  • Ship the Roboto ExtraLight license with the XR examples' font by @willeastcott in #9576

Documentation & Types

  • Type Entity#addComponent options and result by component name by @willeastcott in #9320
  • Type Asset#resource by asset type (Asset, AssetMap, AssetType) by @willeastcott in #9403
  • Type the script lookup APIs against Script and return the class you pass in by @willeastcott in #9472
  • Type element input events with the browser objects they carry by @willeastcott in #9527
  • Add alpha option to createGraphicsDevice typings by @willeastcott in #9317
  • Fix JSDoc types that disagree with runtime values, salvaged from #5817 by @willeastcott in #9469
  • Fix Debug.assert and Texture levels JSDoc types by @willeastcott in #9491
  • Clear all API reference build warnings and treat warnings as errors by @willeastcott in #9412
  • Add a Framework category and home the uncategorised public classes by @willeastcott in #9421
  • Rewrite Asset-related class overviews and document every resource handler by @willeastcott in #9409
  • Rewrite the Math category class overviews by @willeastcott in #9410
  • Rewrite the scene graph and render pipeline class overviews by @willeastcott in #9422
  • Rewrite the material class overviews by @willeastcott in #9424
  • Make the modern input system the Input category and describe its classes by @willeastcott in #9427
  • Describe the modern animation classes and mark the legacy ones by @willeastcott in #9430
  • Describe the sound classes and template the thin component system pages by @willeastcott in #9432
  • Describe the Gizmo and TransformGizmo base classes by @willeastcott in #9433
  • Use American spelling in the Material and LitShaderOptions overviews by @willeastcott in #9431
  • Document which asset types fire the progress event by @willeastcott in #9474
  • Correct RigidBodyComponent group/mask defaults and raycastAll sort order by @willeastcott in #9305
  • Fix physics docs for impulse points, kinematic velocity and contact results by @willeastcott in #9515
  • Improve OutlineRenderer API documentation by @mvaligursky in #9587
  • Correct typos and British spellings across the engine source by @willeastcott in #9547
  • Correct typos and British spellings in examples, scripts and tests by @willeastcott in #9550
  • Add a context7.json so Context7 indexes usage docs and agent rules by @willeastcott in #9478
  • Point the Context7 rules at the llms.txt indexes by @willeastcott in #9503

Engine Dependencies

  • Update dependency sharp to v0.35.4 [SECURITY] in #9330
  • Update all npm dependencies in #9434
  • Update dependency mocha to v12 in #9435

Contributors

  • @AlexAPPi
  • @dfattal
  • @humairaambreen
  • @mvaligursky
  • @slimbuck
  • @willeastcott

New Contributors

  • @dfattal made their first contribution in #9486
  • @humairaambreen made their first contribution in #9543

Full Changelog: https://github.com/playcanvas/engine/compare/v2.22.6...v2.23.0

12 days ago
engine

v2.22.6

Fixes

  • Fix acceptance of mesh instances without a material in Layer#addMeshInstances by @mvaligursky in #9579

Full Changelog: https://github.com/playcanvas/engine/compare/v2.22.5...v2.22.6

12 days ago
engine

v2.22.5

Fixes

  • Fix element position when added to an entity under a screen by @willeastcott in #9525
  • Prevent NVIDIA GPU hangs during gsplat depth picking by @mvaligursky in #9575

Full Changelog: https://github.com/playcanvas/engine/compare/v2.22.4...v2.22.5

17 days ago
engine

v2.22.4

Fixes

Full Changelog: https://github.com/playcanvas/engine/compare/v2.22.3...v2.22.4

19 days ago
engine

v2.22.3

Fixes

  • Fix skydome depth of field with scene-pass depth by @mvaligursky in #9391
  • Fix WebGPU resource cleanup and recovery cancellation on application destroy by @mvaligursky in #9396
  • Fix reset of clustered shadow lights before frame preparation by @mvaligursky in #9414

Full Changelog: https://github.com/playcanvas/engine/compare/v2.22.2...v2.22.3

29 days ago
engine

v2.22.2

Fixes

  • Fix selection of correct shadow shader when changing cascade count by @mvaligursky in #9343
  • Fix StandardMaterial texture map iteration ignoring prototype properties by @mvaligursky in #9368

Full Changelog: https://github.com/playcanvas/engine/compare/v2.22.1...v2.22.2

2026-09-08 20:55:53
engine

v2.22.1

Fixes

  • Gsplat LOD: empty level for nodes without coarse data; distance default by @mvaligursky in [#9326]
  • Correct RigidBodyComponent group/mask defaults and raycastAll sort order docs by @willeastcott in [#9305]

Full Changelog: https://github.com/playcanvas/engine/compare/v2.22.0...v2.22.1

2026-09-04 19:15:28
engine

v2.22.0

Breaking Changes

  • [BREAKING] Store frustum planes in a typed array by @mvaligursky in #9196
  • [BREAKING] Remove wire drawing methods from AppBase by @mvaligursky in #9289

Changes

  • Remove Scene#forcePassThroughSpecular compatibility flag by @mvaligursky in #9250
  • Remove passive event listener detection and platform.passiveEvents by @willeastcott in #9252
  • Remove unused BatchManager#clone method by @mvaligursky in #9106
  • Add dual-source blending support by @mvaligursky in #9096
  • Add Camera.projectionOffset for off-center (shift lens) projection by @mvaligursky in #9098
  • Add RenderTarget origin option, deprecate flipY by @mvaligursky in #9101
  • Expose Bayer 2/4 dither modes and add Bayer 16 dither mode by @mvaligursky in #9117
  • Add shadow pass support for ShaderMaterial using #include by @mvaligursky in #9116
  • Cull omni shadow casters against all six faces in a single pass by @mvaligursky in #9194
  • Cull mesh instances by their bounding box instead of bounding sphere by @mvaligursky in #9197
  • Add flat shading support by @mvaligursky in #9191
  • Flat shade glTF primitives without vertex normals by @mvaligursky in #9193
  • Add shadowCascadeMask to the render component by @mvaligursky in #9195
  • Add shadowCascadeMask in batch by @AlexAPPi in #9104
  • Configurable maximum number of clustered lights by @mvaligursky in #9188
  • Add volumetric fog support for clustered omni and spot lights by @mvaligursky in #9137
  • Support refraction without the metalness workflow by @mvaligursky in #9147
  • Add independent blending for multiple render targets by @mvaligursky in #9140
  • Add per-attachment clear colors for multiple render targets by @mvaligursky in #9142
  • Add clear support for integer format color attachments by @mvaligursky in #9143
  • Render the scene depth from the scene pass, replacing the depth prepass where possible by @mvaligursky in #9174
  • Support writing the scene textures from the forward pass by @mvaligursky in #9166
  • Add SceneDepthReader for reading a camera's scene depth to the CPU by @mvaligursky in #9274
  • Add a scene depth mode to CameraFrame debug rendering by @mvaligursky in #9182
  • Wire alphaToCoverage into the WebGPU render pipeline state by @mvaligursky in #9208
  • Add sample_mask builtin support to WGSL fragment shaders by @mvaligursky in #9222
  • Add samples option to Texture for multisampled textures on WebGPU by @mvaligursky in #9217
  • Support multisampled texture bindings in WGSL reflection and bind groups by @SashaRX in #9167
  • Support multisampled color buffers and custom resolves on RenderTarget by @mvaligursky in #9221
  • Support multisampled depth buffers and depth resolve targets on RenderTarget by @mvaligursky in #9230
  • Add RenderTarget.depthResolveMode controlling multisampled depth resolve by @mvaligursky in #9226
  • Support blendable and R/RG float formats in getRenderableHdrFormat by @mvaligursky in #9164
  • Expose textureFloatBlendable capability on all devices by @mvaligursky in #9160
  • Support the RG32F texture format on WebGL by @mvaligursky in #9218
  • Add readonly detection for the WebGPU subgroup-size-control feature by @mvaligursky in #9158
  • Fix parallax mapping correctness and promote to public by @mvaligursky in #9207
  • Add parallax occlusion mapping as an opt-in parallax mode by @mvaligursky in #9213
  • Add soft self shadowing to parallax occlusion mapping by @mvaligursky in #9225
  • Add heightMapBase to unify the parallax zero level across modes by @mvaligursky in #9245
  • Add WireRenderer for wireframe debug shapes and a debug examples category by @mvaligursky in #9288
  • Add AppOptions.physicsWorld for explicit physics backend selection by @willeastcott in #9266
  • Add timeScale and public step() to RigidBodyComponentSystem by @willeastcott in #9300
  • Wake constrained bodies when a joint constraint is created or destroyed by @willeastcott in #9177
  • Add justified text support to text elements by @mvaligursky in #9185
  • Allow typed arrays in geometry and mesh data APIs by @mvaligursky in #9121
  • Add support for transform feedback separate buffer mode by @AlexAPPi in #9109
  • Support multiple transform feedback buffers by @mvaligursky in #9131
  • Add rotation attribute to the ProceduralSky script by @mvaligursky in #9150
  • Detach element component graph nodes on destroy by @mvaligursky in #9183
  • Release application references on destroy by @mvaligursky in #9190
  • Destroy the asset registry with the application by @mvaligursky in #9189
  • Relocate deprecated API shims so the ESM engine tree-shakes by @willeastcott in #9251
  • Remove WebGL1-era POT checks from texture mipmap upload and gpuSize by @willeastcott in #9262
  • Use Geometry#calculateTangents in procedural geometry subclasses by @willeastcott in #9253
  • Stop the Shader constructor modifying the supplied definition by @willeastcott in #9281

Gaussian Splatting

  • Error-driven GSplat LOD selection with a derived fallback by @mvaligursky in #9233
  • Add a LOD mode and per-splat detail falloff for streamed GSplats by @mvaligursky in #9267
  • Gaussian splats write the scene depth by @mvaligursky in #9175
  • Add scene.gsplat.useTonemap to opt GSplats out of tonemapping and exposure by @mvaligursky in #9229
  • Use shadowCasterPS chunk for gsplat shadow output by @mvaligursky in #9119
  • Fix unified CPU splat sort for non-uniformly scaled splats by @AriaLian in #9268
  • Fix stale gsplat projector pipeline after a dataFormat swap by @mvaligursky in #9269
  • Fix gsplat rendering on Firefox/Windows WebGPU by @mvaligursky in #9148
  • Fix SOG parsers throwing when a load completes after app teardown by @mvaligursky in #9232
  • Fix radix sort value buffer rotation with initial values by @slimbuck in #9276
  • Fix blending disabled when generating SOG centers into an integer render target by @slimbuck in #9224

Fixes

  • Fix inverted normal mapping on WebGPU (derivative TBN) by @mvaligursky in #9099
  • Fix MSDF coverage ramp exceeding field range at small sizes by @willeastcott in #9100
  • Fix reported WebGPU sampled texture limit by @mvaligursky in #9103
  • Discard out of range depth in VSM shadow casters by @mvaligursky in #9124
  • Fix textureBias redefinition in tiled nine-slice shaders by @mvaligursky in #9129
  • Fix the bright outline around MSDF text glyphs by @mvaligursky in #9139
  • Fix vertex array object cache key collisions by @mvaligursky in #9127
  • Fix instancing/draw-commands mismatch skipping indirect draws by @mvaligursky in #9159
  • Fix phantom sampler binding for a trailing texture in WGSL reflection by @mvaligursky in #9198
  • Fix ScriptComponent clone dropping scripts awaiting their script type by @mvaligursky in #9200 #9201 #9202 #9203 #9204
  • Fix AnimationComponent leaking asset event handlers by @mvaligursky in #9141
  • Fix component event leak when removing an enabled component by @mvaligursky in #9145
  • Fix layer event leak when the scene layer composition is replaced by @mvaligursky in #9146
  • Fix XrMenu rendering outside of XR sessions by @willeastcott in #9155
  • Fix looping sounds that specify a start time and duration by @willeastcott in #9231
  • Correct sound duration and playback timing by @mvaligursky in #9249
  • Fix inverted entity name guard in AnimComponentBinder by @willeastcott in #9187
  • Fix volumetric fog missing for one frame after a canvas resize by @mvaligursky in #9283
  • Fix 'set:outline' event reporting the text color by @willeastcott in #9260
  • Handle mapAsync rejection when the WebGPU device is lost by @mvaligursky in #9115
  • Fix ComponentSystemRegistry.remove leaving the system in the list by @willeastcott in #9280
  • Settle the WebGL texture read when the device is destroyed by @mvaligursky in #9275
  • Recalculate particle local bounds when the spawn volume changes by @mvaligursky in #9192
  • Anchor the AppleWebKit 15.4 antialias workaround UA match by @willeastcott in #9265

Examples

  • Add VAT character crowd rendering scripts and example by @mvaligursky in #9123
  • Add catapult siege demo example by @mvaligursky in #9130
  • Add a parallax terrain example by @mvaligursky in #9223
  • Support multiple transform feedback buffers and add a visual example by @mvaligursky in #9131
  • Point the downtown example at a single full-scene streamed SOG bundle by @mvaligursky in #9290
  • Make the examples MiniStats toggle drive example-owned instances by @mvaligursky in #9292
  • Fix painter example render target orientation across APIs by @mvaligursky in #9108

Engine Dependencies

  • Update all npm dependencies (major) by @renovate[bot] in #9056

Contributors

  • @AlexAPPi
  • @AriaLian
  • @kpal81xd
  • @mvaligursky
  • @SashaRX
  • @slimbuck
  • @willeastcott

New Contributors

  • @SashaRX made their first contribution in #9167
  • @AriaLian made their first contribution in #9268

Full Changelog: https://github.com/playcanvas/engine/compare/v2.21.4...v2.22.0