Add alphaDither property for independent dither strength#8782
Merged
Conversation
Adds a new alphaDither property on StandardMaterial so alpha blending and opacity dithering can be active at the same time with independent strengths. Previously, when opacityDither was enabled the dither threshold was driven by the same opacity scalar as alpha blending, making it an either/or choice. The shader is wired via a new material_alphaDitherScale uniform; JS computes alphaDither / opacity and the dither call site multiplies it into dAlpha. A getter fallback returns opacity when alphaDither has never been assigned, keeping the scale at 1.0 and producing bit-identical output for existing materials. copy() is patched to preserve the implicit-fallback state across clone. Closes #8764
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces an alphaDither property on StandardMaterial to decouple opacity dithering strength from alpha blending (opacity), enabling both techniques to be used simultaneously with independent intensities (resolving #8764).
Changes:
- Added
StandardMaterial.alphaDither(with implicit fallback toopacityuntil explicitly assigned) and clone/copy support for the implicit state. - Added a new shader uniform (
material_alphaDitherScale) and applied it at the dither call site in both GLSL and WGSL standard fragment frontends. - Updated the
dithered-transparencyexample to demonstrate legacy (implicit) vs new (explicit)alphaDitherbehavior side-by-side, including a new UI slider.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/scene/shader-lib/wgsl/chunks/standard/frag/stdFrontEnd.js | Multiplies dither alpha by uniform.material_alphaDitherScale in WGSL standard frontend. |
| src/scene/shader-lib/wgsl/chunks/standard/frag/opacity.js | Declares WGSL uniform material_alphaDitherScale. |
| src/scene/shader-lib/glsl/chunks/standard/frag/stdFrontEnd.js | Multiplies dither alpha by material_alphaDitherScale in GLSL standard frontend. |
| src/scene/shader-lib/glsl/chunks/standard/frag/opacity.js | Declares GLSL uniform material_alphaDitherScale. |
| src/scene/materials/standard-material.js | Adds alphaDither property (implicit fallback), copies implicit state during copy(), and sets material_alphaDitherScale parameter when dithering is enabled. |
| examples/src/examples/graphics/dithered-transparency.example.mjs | Reworks the example into left/right tables to demonstrate implicit vs explicit alphaDither behavior. |
| examples/src/examples/graphics/dithered-transparency.controls.mjs | Adds an “Alpha Dither” slider bound to data.alphaDither. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a new
alphaDitherproperty onStandardMaterialso alpha blending and opacity dithering can be active at the same time with independent strengths. Resolves #8764.Previously, when
opacityDitherwas enabled the dither threshold was driven by the sameopacityscalar as alpha blending, so a material was effectively either alpha-blended or dithered — never both at meaningful strengths. The newalphaDitherproperty feeds the dither path with its own alpha, decoupled from blend.Changes:
alphaDitherproperty onStandardMaterial(range [0, 1])material_alphaDitherScale(JS computesalphaDither / opacityand the GLSL/WGSL dither call site multiplies it intodAlpha)alphaDitherassigned reads back asopacity, so the dither pass uses the same alpha as before (scale = 1, bit-identical output)copy()patched to preserve the implicit-fallback state acrossmaterial.clone()API Changes:
StandardMaterial.alphaDither—numberin [0, 1]. Set to1.0to disable dither without recompiling the shader,0.0to fully discard via dither. Reads back asopacityuntil explicitly assigned.Examples:
examples/graphics/dithered-transparency: rebuilt as a side-by-side comparison — left table never assignsalphaDither(legacy "opacity drives dither" behavior), right table is driven by an Alpha Dither slider (new independent control). Demonstrates both BC and the new feature in one view.