Move MaterialX sheen BSDF into BSDL#2084
Move MaterialX sheen BSDF into BSDL#2084aconty merged 1 commit intoAcademySoftwareFoundation:mainfrom
Conversation
6758c6b to
f70a628
Compare
|
I would vote against modifying the Zeltner lobe. The model is already in use in a bunch of places (including OpenPBR) with the default implementation straight from the paper. Its meant to represent a thin layer of fuzz with unit mfp - its expected that it does not reach an albedo of 1. |
| static constexpr bool FITTED_LTC = false; | ||
|
|
||
| // LTC sampling is weak at low roughness, gains energy, so we clamp it. | ||
| static constexpr float MIN_ROUGHNESS = LTC_SAMPLING ? 0.1f : 0.0f; |
There was a problem hiding this comment.
I'm curious how you found the limit of 0.1 - in another implementation I wrote I had a limit of 0.02 which seems to work fine with LTC sampling.
There was a problem hiding this comment.
By trial and error with the furnace test. Below that you can see some energy gain. It doesn't happen with uniform sampling though. Maybe your LTC sampling is more numerically stable.
So I went back to how the SPI code and the github paper repo works. I recovered the numerical stability and is less error prone now. Was able lo lower the min roughness to your chosen 0.02.
f293f3b to
fb7dbb0
Compare
| // mapping including the normalization. | ||
| // See the original paper [Heitz et al. 2016] for details about the LTC | ||
| // itself. | ||
| const float length = wi_orig.length(); |
There was a problem hiding this comment.
You can skip the normalization and use
SQR(a_inv / len^2)
| const float a_inv = ltc.x; | ||
| const float b_inv = ltc.y; | ||
| Imath::V3f wi_orig = sample_cos_hemisphere(randu, randv); | ||
| const Imath::V3f wi = { wi_orig.x / a_inv - wi_orig.z * b_inv / a_inv, |
There was a problem hiding this comment.
You can scale everything by a_inv to avoid the divides.
Consolidate sheen implementation from testrender and SPI into a single BSDL-backed MaterialX lobe (`mtx::SheenLobe`), so sheen behavior is defined in one place and reused consistently across paths. - Move sheen logic into BSDL/MTX and wire it through the BSDL closure path - Replace ad-hoc testrender-side handling with the new BSDL implementation - Keep Conty/Zeltner mode selection inside the unified sheen lobe - Update sheen tests and references to validate the new path - Turn the furnace sheen test into a true energy-conservation check (sheen layered over white diffuse should converge to flat gray) AI Disclaimer: AI has been used to code review and bug hunt, but all the code and fixes have been written by huomans. Signed-off-by: Alejandro Conty <aconty@imageworks.com>
|
Is this safe to backport to release branches? Or is it a link or API compatibility break for renderers that might be using BSDL? |
|
No API change. If somebody is using testrender they may get a look change. Regarding BSDL just the sheen addition. |
Consolidate sheen implementation from testrender and SPI into a single BSDL-backed MaterialX lobe (`mtx::SheenLobe`), so sheen behavior is defined in one place and reused consistently across paths. - Move sheen logic into BSDL/MTX and wire it through the BSDL closure path - Replace ad-hoc testrender-side handling with the new BSDL implementation - Keep Conty/Zeltner mode selection inside the unified sheen lobe - Update sheen tests and references to validate the new path - Turn the furnace sheen test into a true energy-conservation check (sheen layered over white diffuse should converge to flat gray) AI Disclaimer: AI has been used to code review and bug hunt, but all the code and fixes have been written by huomans. Signed-off-by: Alejandro Conty <aconty@imageworks.com>


Description
Consolidate sheen implementation from testrender and SPI into a single BSDL-backed MaterialX lobe (
mtx::SheenLobe), so sheen behavior is defined in one place and reused consistently across paths.Proposal
At imageworks we scale up the Zeltner LTC sheen by 1 / max(albedo) = 0.74973. So a ~1.33 scale to match the other sheen maximum brightness of 1.0. This is very useful for artists not to perceive an energy loss from model to model. I suggest we do this at the MaterialX level too.
If people don't disagree I'll modify this PR to apply that scale.
Tests
Everything looking good. I moved the alpha = sqrt(roughness) mapping under the hood so you don't need special treatment for mode == 1. But I understand (more or less) if you don't like this and want me to revert that.
Checklist:
already run clang-format v17 before submitting, I definitely will look at
the CI test that runs clang-format and fix anything that it highlights as
being nonconforming.