Web: StandardMaterial can exceed maxSamplersPerShaderStage when enabling multiple glTF/PBR texture features
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## What problem does this solve or what need does it fill?
When targeting the Web with WebGPU, enabling several glTF/PBR material texture features can make `StandardMaterial` quickly exceed the per-stage sampler limit exposed by browsers/devices.
In a Wasm/WebGPU build, this can crash rendering with the following error:
```text
Caught rendering error: The number of samplers (19) in the Fragment stage exceeds the maximum per-stage limit (16).
```
This is easy to hit because `maxSampledTexturesPerShaderStage` may be much higher while `maxSamplersPerShaderStage` remains 16. For example, a [WebGPU report](https://webgpureport.org/) may show:
```text
maxSampledTexturesPerShaderStage: 48
maxSamplersPerShaderStage: 16
```
So the issue is not the number of sampled textures, but the number of distinct sampler bindings used by the fragment shader.
There is a related issue here: https://github.com/bevyengine/bevy/issues/13974
## What solution would you like?
Add an option to reduce sampler usage for `StandardMaterial`, especially for WebGPU/Web targets.
One possible implementation is a feature-gated shared sampler mode for PBR materials:
- keep the base color texture sampler binding;
- sample metallic-roughness, normal, occlusion, emissive, transmission, specular, anisotropy, and similar PBR maps using the same base color sampler;
- enable this through a feature or render setting, for example `pbr_single_texture_sampler`.
In practice, it can reduce the PBR material sampler count from many bindings down to one material sampler, avoiding the WebGPU `maxSamplersPerShaderStage` crash.
The tradeoff is that per-texture sampler settings are ignored for those PBR maps while the option is enabled, but this is often acceptable as a WebGPU compatibility mode.
## What alternative(s) have you considered?
A more advanced solution could use a sampler cache/deduplication system, so identical sampler descriptors are only bound once instead of creating duplicate sampler bindings. This seems like a more flexible long-term solution, but it also looks significantly more complicated to implement than a shared sampler compatibility mode.
Contributor guide
Research direction
No file or test is named. Start by locating StandardMaterial's PBR shader and sampler-binding entry points, then compare the behavior with related issue #13974. Define how the opt-in shared-sampler setting should work and verify that enabling the relevant glTF/PBR features stays within WebGPU's per-stage sampler limit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, wasm
- Domain
- computer-graphics, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100