playcanvas / playcanvas/engine

feat(graphics): adopt WGSL uniform_buffer_standard_layout for tighter uniform-buffer packing

Open
#8,791 0 comments 1 reaction 1 assignee View on GitHub

@mvaligursky is already working on this.

Since May 27, 2026.

Dominant language
JavaScript
Stars
16.8k
Forks
2k
Avg merge
4h 32m
Merged PRs (30d)
222

Description

Background

Chrome 144 added the WGSL uniform_buffer_standard_layout language feature. When enabled via requires uniform_buffer_standard_layout;, uniform buffers may use the same memory layout constraints as storage buffers — in particular, the 16-byte alignment requirement on array elements is lifted. This matches GLSL's std430 semantics.

Why this matters

The engine packs uniform data into uniform buffers automatically (via the uniform buffer / dynamic buffer paths). Today, arrays like array<f32, N> or array<vec3<f32>, N> get padded out to 16-byte stride, wasting bandwidth and complicating layouts shared between uniform and storage buffers.

With this feature, the engine could:

  • Pack array<f32, N> and array<vec3<f32>, N> at natural stride
  • Share data structure layouts between uniform and storage buffers without padding hacks
  • Reduce uniform buffer bandwidth for the affected types

Why this is more work than a typical WGSL feature cap

Unlike the other WGSL feature caps (which just emit a requires directive and let shaders opt-in conditionally), the engine's uniform buffer packing code in JS (e.g. UniformBuffer, UniformBufferFormat, the dynamic buffer system) currently encodes the std140-style alignment rules. To benefit from uniform_buffer_standard_layout, the packing logic itself has to branch on the cap and apply std430-style stride when supported.

This means:

  • JS-side packing layout needs to be cap-aware (per-device, since Firefox/Safari may not support it)
  • Shader-side struct layouts may need conditional padding for portability
  • Existing uniform buffer formats / layouts may need versioning to avoid breaking pre-built shaders

Suggested approach

  1. Add the WGSL feature cap infrastructure (supportsUniformBufferStandardLayout, CAPS_UNIFORM_BUFFER_STANDARD_LAYOUT, requires uniform_buffer_standard_layout;) — trivial, follows the existing pattern (#8785, #8786, #8787, #TBD).
  2. Audit the JS uniform-buffer packing code paths to identify where the std140 alignment is applied and what would need to change.
  3. Decide on a portability strategy: do shaders always use the tighter layout where supported and fall back where not, or is this opt-in per uniform buffer?
  4. Implement and validate across the WebGPU paths.

References

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.