Skip to content

Add alphaDither property for independent dither strength#8782

Merged
mvaligursky merged 2 commits into
mainfrom
mv-alpha-dither
May 26, 2026
Merged

Add alphaDither property for independent dither strength#8782
mvaligursky merged 2 commits into
mainfrom
mv-alpha-dither

Conversation

@mvaligursky
Copy link
Copy Markdown
Contributor

Add a new alphaDither property on StandardMaterial so alpha blending and opacity dithering can be active at the same time with independent strengths. Resolves #8764.

Previously, when opacityDither was enabled the dither threshold was driven by the same opacity scalar as alpha blending, so a material was effectively either alpha-blended or dithered — never both at meaningful strengths. The new alphaDither property feeds the dither path with its own alpha, decoupled from blend.

Changes:

  • New alphaDither property on StandardMaterial (range [0, 1])
  • New shader uniform material_alphaDitherScale (JS computes alphaDither / opacity and the GLSL/WGSL dither call site multiplies it into dAlpha)
  • BC preserved via a getter fallback: a material that has never had alphaDither assigned reads back as opacity, so the dither pass uses the same alpha as before (scale = 1, bit-identical output)
  • copy() patched to preserve the implicit-fallback state across material.clone()

API Changes:

  • Added: StandardMaterial.alphaDithernumber in [0, 1]. Set to 1.0 to disable dither without recompiling the shader, 0.0 to fully discard via dither. Reads back as opacity until explicitly assigned.

Examples:

  • examples/graphics/dithered-transparency: rebuilt as a side-by-side comparison — left table never assigns alphaDither (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.

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
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 to opacity until 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-transparency example to demonstrate legacy (implicit) vs new (explicit) alphaDither behavior 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.

Comment thread src/scene/materials/standard-material.js Outdated
Comment thread src/scene/materials/standard-material.js
@mvaligursky mvaligursky merged commit ec7d4d1 into main May 26, 2026
8 checks passed
@mvaligursky mvaligursky deleted the mv-alpha-dither branch May 26, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Independent intensities for alpha blending and dithered transparency

2 participants