Skip to content

Specular aa#24427

Open
altunenes wants to merge 8 commits into
bevyengine:mainfrom
altunenes:specular-aa
Open

Specular aa#24427
altunenes wants to merge 8 commits into
bevyengine:mainfrom
altunenes:specular-aa

Conversation

@altunenes
Copy link
Copy Markdown

Objective

try to fix: #24288

Solution

Adds geometric specular anti aliasing as an opt-in toggle on StandardMaterial. When enabled, the PBR fragment shader widens the squared GGX alpha based on dpdx/dpdy of the shading normal:

  let variance = sigma * sigma * (dot(dpdx(N), dpdx(N)) + dot(dpdy(N), dpdy(N)));
  let kernel = min(variance, kappa);
  alpha_squared = saturate(alpha_squared + kernel);

from Tokuyoshi and Kaplanyan, "Improved Geometric Specular Antialiasing" (I3D 2019)

3 new fields on StandardMaterial:

  • specular_anti_aliasing: bool — opt in. Defaults to false so existing materials are unchanged.
  • specular_anti_aliasing_screen_space_variance: f32 — strength σ. Default 0.5
  • specular_anti_aliasing_threshold: f32 — clamp κ. Default 0.18
    note that deafults are from paper.

The clearcoat normal is filtered separately when the clearcoat layer is active. The block is skipped in the meshlet pass since its software rasterizer doesn't provide pixel-quad derivatives...

note that On extremely high freq normal maps without mip chains, the kernel can over widen at sharp texture features. A natural follow up/todo is normal map mipmap gen paired with a Toksvig/LEAN factor folded into the same kernel addition, but that touches asset loading and is meaningfully bigger than this shader change, so I left it as future work...

Testing

Tested on macOS / Apple M3 (Metal) 16gb.
I built an interactive playground locally (kept out of this PR to keep the diff focused) where I could toggle the flag and live tweak σ/κ (variance and threshold values) while a normal mapped object spun under an orbiting light. The visible signature in motion is what you'd expect: with AA off the highlight shimmers as the light sweeps across the normal map detail, with AA on it stays stable. the visible benefit is mostly temporal stability, which is hard to capture in a still I tried to record a video below :/


Showcase

diff between on and off:

Screen.Recording.2026-05-25.at.00_compressed.32.27.mov

More context: In my game, I was seeing "glitters/luminescences" in exactly this texture (btw texture from: https://freestylized.com/material/ground_stones_01/ ), which I didn't want. Applying this made the "glitter" disappear without using TAA :-) .

@github-actions
Copy link
Copy Markdown
Contributor

Welcome, new contributor!

Please make sure you've read our contributing guide, as well as our policy regarding AI usage, and we look forward to reviewing your pull request shortly ✨

@laundmo laundmo added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen D-Shaders This code uses GPU shader languages labels May 25, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Rendering May 25, 2026
@laundmo
Copy link
Copy Markdown
Member

laundmo commented May 25, 2026

I think it might be nice to have an example for this, if you're willing to port your playground over, either as part of this PR or a follow-up

@altunenes
Copy link
Copy Markdown
Author

I think it might be nice to have an example for this, if you're willing to port your playground over, either as part of this PR or a follow-up

hmm I think I --probably-- could reproduce this with a procedual ways via voronoi normal on the cpu...
similar texture that make specular aliasing more obvious like video I sent above without assets.
The reason I didn't add example was mainly to avoid making the PR too big...🙂

@github-actions
Copy link
Copy Markdown
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@alice-i-cecile alice-i-cecile added D-Complex Quite challenging from either a design or technical perspective. Ask for help! M-Release-Note Work that should be called out in the blog due to impact X-Contentious There are nontrivial implications that should be thought through S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note.

Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes.

@alice-i-cecile
Copy link
Copy Markdown
Member

Yeah, we need an example of some sort here so we can demonstrate and test this :)

@altunenes
Copy link
Copy Markdown
Author

Yeah, we need an example of some sort here so we can demonstrate and test this :)

here it is 🙂
6e7f79c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! D-Shaders This code uses GPU shader languages M-Release-Note Work that should be called out in the blog due to impact S-Needs-Review Needs reviewer attention (from anyone!) to move forward X-Contentious There are nontrivial implications that should be thought through

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

Specular Anti-Aliasing

3 participants