Skip to content

Use a LUT for F_AB#23737

Open
dylansechet wants to merge 4 commits intobevyengine:mainfrom
dylansechet:f_ab_lut
Open

Use a LUT for F_AB#23737
dylansechet wants to merge 4 commits intobevyengine:mainfrom
dylansechet:f_ab_lut

Conversation

@dylansechet
Copy link
Copy Markdown
Contributor

@dylansechet dylansechet commented Apr 9, 2026

Objective

F_AB currently uses a polynomial approximation. This replaces it it with a more precise LUT.

Solution

Add a LUT computed using Monte-Carlo sampling.

The minimum value was clipped to 1e-6, which modifies 0.4% of the values that were below that but should help prevent bugs like #22833.

Open questions:

  • Do we want to feature-gate this with the polynomial version as a fallback?

Testing


Showcase

F_AB tables

Current PR uses the Monte-Carlo based LUT, bevy currently uses the polynomial approximation.

f_ab_monte_carlo f_ab_polynomial_approx mae

Solari white furnace

This new approximation significantly improves the solari white furnace.

Main:
solari_wf_main

With this PR:
solari_wf_fablut

LUT size vs error

I ended up going with 64x64.
size_error

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke!
You can review it at https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D?filter=PR-23737

If it's expected, please add the M-Deliberate-Rendering-Change label.

If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it.

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke!
You can review it at https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D?filter=PR-23737

If it's expected, please add the M-Deliberate-Rendering-Change label.

If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it.

@kfc35 kfc35 added A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward C-Refinement Improves output quality, without fixing a clear bug or adding new functionality. labels Apr 9, 2026
@github-project-automation github-project-automation bot moved this to Needs SME Triage in Rendering Apr 9, 2026
if !has_fab_lut {
let mut images = app.world_mut().resource_mut::<Assets<Image>>();
let texture = images.add(
Image::from_buffer(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't we need to gate this behind the ktx2 feature?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should feature gate this in general. Including these bytes here will increase the size of the binary so it should be opt in.

I explored this BRDF lut approach earlier for the PR from a month ago (clamp FAB)

https://github.com/mate-h/bevy/tree/m/brdf-lut

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll go with @mate-h's suggestion to feature-gate the LUT so ktx2 can just be enabled when we need it.
The LTC LUTs have the same problem, I'll open an issue.

@JMS55
Copy link
Copy Markdown
Contributor

JMS55 commented Apr 10, 2026

Should we maybe have the LUT indexed via roughness instead of perceptual_roughness?

@github-actions
Copy link
Copy Markdown
Contributor

Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke!
You can review it at https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D?filter=PR-23737

If it's expected, please add the M-Deliberate-Rendering-Change label.

If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it.

Copy link
Copy Markdown
Contributor

@mate-h mate-h left a comment

Choose a reason for hiding this comment

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

Nice work but I have a few questions and comments. I also worked on something similar as a test but never posted a PR for it. I think having that extra KTX asset bundled into your binary might be something users will want to opt into rather than default feature.

// F_AB
entries = entries.extend_with_indices((
(
40,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I hope we're not close to hitting binding limits on this 😬 if we are might consider reusing a linear sampler

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We are, hitting max_sampled_textures_per_shader_stage on webgl -_-
I think I'll just make LTC reuse the same sampler for both of its LUTs to free up a slot.

// Keep F_ab positive to avoid divide-by-zero in downstream BRDF terms.
let f_ab_epsilon = 0.00005;
return max(vec2<f32>(-1.04, 1.04) * a004 + r.zw, vec2<f32>(f_ab_epsilon));
return textureSampleLevel(view_bindings::f_ab_lut, view_bindings::f_ab_lut_sampler, vec2<f32>(NdotV, perceptual_roughness), 0.0).rg;
Copy link
Copy Markdown
Contributor

@mate-h mate-h Apr 10, 2026

Choose a reason for hiding this comment

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

I wouldn't completely replace the polynomial approximation with the lut lets keep both. Add a shader def and enable the LUT with a feature flag. We should discuss whether this should be opt in or on by default.

@mate-h
Copy link
Copy Markdown
Contributor

mate-h commented Apr 10, 2026

Oh and the graphs you attached to the PR description are amazing very helpful in seeing the difference

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-Refinement Improves output quality, without fixing a clear bug or adding new functionality. S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

4 participants