Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Higher quality lightmap sampling #16740

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

JMS55
Copy link
Contributor

@JMS55 JMS55 commented Dec 10, 2024

Objective

Solution

  • Implement fast 4-sample bicubic filtering based on this shader toy https://www.shadertoy.com/view/4df3Dn, with a small speedup from a ghost of tushima presentation.
  • I decided not to waste a pipeline key on making this toggle-able. Users can write custom materials fairly easily if they really need a cheaper method.

Testing

  • Did you test these changes? If so, how?
    • Ran on lightmapped example. Practically no difference in that scene.
  • Are there any parts that need more testing?
    • Lightmapping a better scene.

Changelog

  • Lightmaps now use a higher quality sampling method. Ensure that your light map Image's sampler is set to linear.

@JMS55 JMS55 added the A-Rendering Drawing game state to the screen label Dec 10, 2024
@JMS55 JMS55 requested a review from pcwalton December 10, 2024 05:48
@JMS55 JMS55 added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Dec 10, 2024
@DGriffin91
Copy link
Contributor

imo this should be optional (with at least linear being the other option). Try with a low res light map to see the effect.

Copy link
Contributor

@pcwalton pcwalton left a comment

Choose a reason for hiding this comment

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

Looks good modulo a little inaccuracy.

I could go either way on exposing an option for bilinear, and I won't block the PR on that. A quote from the Bakery author's blog post: https://ndotl.wordpress.com/2018/08/29/baking-artifact-free-lightmaps/

Bicubic interpolation. If you are not shipping on mobile, there are exactly 0 reasons to not use bicubic interpolation for lightmaps. Many UE3 games in the past did that, and it is a great trick. But some engines (Unity, I’m looking at you) still think they can get away with a single bilinear tap in 2018. Bicubic hides low resolution and makes jagged lines appear smooth. Sometimes I see people fixing jagged sharp shadows by super-sampling during bake, but it feels like a waste of lightmapping time to me.

See the post for a screenshot comparison.

The "if you are not shipping on mobile" comment is 6 years old, so it may well just be time to say bicubic everywhere.

let p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - 0.5) * texel_size;
let p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - 0.5) * texel_size;
let p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - 0.5) * texel_size;
let p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - 0.5) * texel_size;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Odd indentation here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy+pasted tabs :/. Fixed.

}

fn h1_approx(a: f32) -> f32 {
return 1.0 + a * (0.24 * a - 0.04);
Copy link
Contributor

Choose a reason for hiding this comment

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

I saw that comment, but the rounding on the coefficients for h1_approx leads to some serious error:
BadApprox

I calculated out the real coefficients here:
GoodApprox

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return 1.0 + a * (0.24 * a - 0.04);
return 1.00158 + a * (0.230963 * a - 0.0353001);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I plugged it into desmos. Both yours and my h1 approx have inaccuracies. The difference is whether it occurs before or after the midpoint.

https://www.desmos.com/calculator/588bmvpwp9

Copy link
Contributor

Choose a reason for hiding this comment

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

Oops, I replaced the - with a +! Sign error. Ignore my comment, your code is fine the way it is

}

fn h0_approx(a: f32) -> f32 {
return 0.2 + a * (0.24 * a - 0.44);
Copy link
Contributor

Choose a reason for hiding this comment

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

For comparison with the code below, this is a fine approximation.

OkApprox

@DGriffin91
Copy link
Contributor

DGriffin91 commented Dec 11, 2024

Based on these images from @pcwalton I don't think bicubic is correct: https://discord.com/channels/691052431525675048/743663924229963868/1316259592308527134

image

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 S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

Use bicubic filtering in lightmaps
3 participants