Skip to content

Roughening improvements#261

Draft
portsmouth wants to merge 5 commits intoAcademySoftwareFoundation:dev_1.2from
portsmouth:roughening_suggestion_improvements
Draft

Roughening improvements#261
portsmouth wants to merge 5 commits intoAcademySoftwareFoundation:dev_1.2from
portsmouth:roughening_suggestion_improvements

Conversation

@portsmouth
Copy link
Copy Markdown
Contributor

@portsmouth portsmouth commented Jun 24, 2025

According to the discussion in #239 (and on Slack), we need to provide a less obviously wrong suggestion for the coat roughening effect.


Based on Monte Carlo sims, the latest recommendation is as follows:

image

For the fuzz, the sims shows that no roughening is appropriate, if using the Zeltner model.

image

The MaterialX implementation has been updated accordingly.

@portsmouth portsmouth changed the base branch from main to dev_1.2 June 24, 2025 02:30
@portsmouth portsmouth changed the base branch from dev_1.2 to dev_1.1.1 June 24, 2025 02:30
@portsmouth portsmouth changed the base branch from dev_1.1.1 to dev_1.2 June 24, 2025 02:31
@portsmouth
Copy link
Copy Markdown
Contributor Author

portsmouth commented Jun 24, 2025

I think we need to think a bit about what the effect of the fuzz tint color should be.

With the roughening heuristic above, I get the following results when the fuzz color is varied from light to dark.

light fuzz dark fuzz
new_r1 0 new_colored_r1 0

When the fuzz is dark, our heuristic reduces the roughening, so we see a sharp highlight.
However, I think we were assuming that dark fuzz (with high weight and roughness), should produce dark fuzzy patches, not just look transparent. This doesn't happen though, because the color only modulates the fuzz reflection, it does not alter the throughput/transmittance to the base.

I find that a bit unconvincing as if the fuzz is same density in the left and right image, you would expect the highlight to be much more dimmed on the right. In reality, more absorbing dust should reduce the transmittance as well as the reflection. It may be inherent in the Zeltner model though, that this more realistic volumetric absorption isn't really captured.

Comment thread index.html Outdated
The effect of the coat roughening can then be modeled as the convolution of these Gaussian NDFs, which corresponds to adding the variances (double counting the coat variance since the reflection passes through the coat boundary twice). The IOR ratio of the coat and ambient medium $\eta_\mathrm{ca}$ also needs to be accounted for, since as $\eta_\mathrm{ca} \rightarrow 1$ the roughening due to the coat goes to zero.
This leads to the following suggested approximate formula for the modified roughness $r'_\mathrm{B}$ of the base due to the coat:
\begin{equation} \label{coat_roughening_heuristic}
r'_\mathrm{B} = \mathrm{min} \bigl(1, r^4_\mathrm{B} + 2 x_C r^4_\mathrm{C} \bigr)^\frac{1}{4} \quad \textrm{with } x_C = 1 - \mathrm{min}(\eta_\mathrm{ca}, 1/\eta_\mathrm{ca})
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.

Does "x" mean something or is it just an arbitrary available variable name?

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.

Just a variable name. It accounts for the IOR, so not sure what symbol to use. Putting the min inside the brackets looked worse.

@peterkutz
Copy link
Copy Markdown
Contributor

Regarding the effect of dark fuzz in the images, I think the

I find that a bit unconvincing as if the fuzz is same density in the left and right image, you would expect the highlight to be much more dimmed on the right. In reality, more absorbing dust should reduce the transmittance as well as the reflection. It may be inherent in the Zeltner model though, that this more realistic volumetric absorption isn't really captured.

True. The Zeltner model is based on non-absorbing microflakes and it doesn't make a distinction between scattered and unscattered transmission. So some of the transmitted light is actually scattered light that should be eliminated if the single-scattering albedo of the microflakes is zero. So I agree that the dark fuzz should technically darken the base surface more. That said, in your renders it's hard to see how much the dark fuzz is actually darkening the base because the specular highlight is overexposed and the background is black.

Comment thread index.html
\mu_i \, f_\mathrm{fuzz}(\omega_i, \omega_o) = \mathbf{F} \, E_\mathrm{fuzz}(\mu_o, r_F) \, D(\mu_i | \mu_o, r_F)
\end{equation}
where $\mathbf{F}$ = **`fuzz_color`**, $E_\mathrm{fuzz}(\mu_o, \alpha)$ (termed $R$ in [#Zeltner2022]) is the reflectance at angle cosine $\mu_o$ given roughness $\alpha$ = **`fuzz_roughness`** $\in [0,1]$, and $D(\mu_i | \mu_o, \alpha)$ is a lobe defined by linear transformations of a cosine lobe (LTCs), where the transformation matrices (and $E_\mathrm{fuzz}$) are tabulated in a grid in the $(\mu_o, \alpha)$ plane, with values fitted to a simulation of the scattering in the volumetric fuzz microflake layer. Since the LTC lobe $D$ is a normalized PDF over the hemisphere, the resulting albedo of $f_\mathrm{fuzz}$ is $\mathbf{F} \, E_\mathrm{fuzz}(\mu_o, \alpha)$.
where $\mathbf{F}$ = **`fuzz_color`**, $E_\mathrm{fuzz}(\mu_o, r_F)$ (termed $R$ in [#Zeltner2022]) is the reflectance at angle cosine $\mu_o$ given roughness $r_F$ = **`fuzz_roughness`** $\in [0,1]$ (termed $\alpha$ in [#Zeltner2022]), and $D(\mu_i | \mu_o, r_F)$ is a lobe defined by linear transformations of a cosine lobe (LTCs), where the transformation matrices (and $E_\mathrm{fuzz}$) are tabulated in a grid in the $(\mu_o, r_F)$ plane, with values fitted to a simulation of the scattering in the volumetric fuzz microflake layer. Since the LTC lobe $D$ is a normalized PDF over the hemisphere, the resulting albedo of $f_\mathrm{fuzz}$ is $\mathbf{F} \, E_\mathrm{fuzz}(\mu_o, r_F)$.
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 assume you're using different variables than the Zeltner paper to be consistent with other formulas in the OpenPBR spec. Is that right?

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.

Yes, since $\alpha$ means roughness squared in the microfacet case, so it could be a bit confusing to use the same symbol here.

Comment thread index.html Outdated
The scattering within the fuzz layer will have the effect of roughening the appearance of the substrate beneath it.
A simple suggested approximation for this can be adapted from the formula used to model the coat roughening, in equation [coat_roughening_heuristic]. If we consider the fuzz layer to generate roughening by scattering, we can approximate its effective roughness as being proportional to the albedo of the layer, as well as to the tint color (since darker fuzz will physically scatter less and absorb more). This leads to the following heuristic for the modified roughness $r'_\mathrm{B}$ of the substrate lobe:
\begin{equation} \label{fuzz_roughening_heuristic}
r'_\mathrm{B} = \mathrm{min} \bigl(1, r^4_\mathrm{B} + 2 R^4_\mathrm{F} \bigr)^\frac{1}{4} \quad \textrm{with $R_F = \mathrm{lum}(\mathbf{F} E_\mathrm{fuzz})$}
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.

The inclusion of E_fuzz here means that the roughening will be more intense at grazing angles where the optical density is higher, correct?

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.

The fuzz doesn't use a GGX distribution like the coat, so I wonder whether these fourth powers are still justifiable.

Based on my own empirical testing, I had to tone down the fuzz roughening quite a bit (compared to coat roughening) to get it to look plausible.

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.

Also, the E_fuzz functions almost like a coverage weight, since it's essentially the opacity of the fuzz layer, so intuitively it seems like the blending based on E_fuzz (and maybe the color F too) should be a simple lerp on the final roughness (unaffected by the powers and roots).

Copy link
Copy Markdown
Contributor Author

@portsmouth portsmouth Jul 6, 2025

Choose a reason for hiding this comment

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

The inclusion of E_fuzz here means that the roughening will be more intense at grazing angles where the optical density is higher, correct?

Yes true.

The fuzz doesn't use a GGX distribution like the coat, so I wonder whether these fourth powers are still justifiable.

The $E_\mathrm{fuzz}$ term is the albedo of the fuzz layer (in the Zeltner sims), i.e. (presumably) what fraction of the light is reflected back as opposed to transmitted through.

So I am just loosely assuming that this albedo can be a sort of proxy of the "amount of scattering", and thus the amount of roughening captured in a roughness scalar $R_F$.

If the roughening is some (angular) Gaussian blurring with the angular blur varying with $R_F$ in the same way as the GGX blurring, then the combination with the base roughness (with the fourth powers) is a reasonable guess. Though agreed there's no very good rationale for that assumption, currently. There could easily be some multiplicative factor required to compare the "fuzz roughening" to the GGX roughness, or possibly the effect is totally different to the proposed formula even with such an adjusted factor.

We'll need to do some simulations to check how it compares to reality, and fix it up accordingly.

E_fuzz functions almost like a coverage weight, since it's essentially the opacity of the fuzz layer

Not sure I agree, since as noted it's really the albedo (varying with input direction). The coverage (and opacity) is constant in the Zeltner model, i.e. unit optical depth of fuzz.

Obviously we also have the fuzz weight, functioning as an actual coverage weight, which should affect the roughening.

@peterkutz
Copy link
Copy Markdown
Contributor

Great to have the IOR officially included in the spec's coat roughening formula and a mention of fuzz roughening.

Conceptually, the form of the fuzz roughening is questionable compared to coat roughening. The coat has a refractive interface, so all light passing through it is scattered. But the fuzz is effectively a volume without an interface, so only some of the transmitted light is scattered. The fuzz should ideally produce a mixture of roughened and un-roughened base lobes. Plus the scattering distribution should ideally be different due to the anisotropic scattering of the fuzz.

So, I wonder if a stochastic selection of roughened and un-roughened base roughness (based on a rough estimate of the scattered/unscattered transmission of the fuzz) would produce better results. (The proposed specular haze could potentially be leveraged to roughen only a fraction of the light, but the haze might already be in use.)

@portsmouth
Copy link
Copy Markdown
Contributor Author

Totally agree that we need to do more work on both of these formulas to produce the best approximation we can offer. For this we are going to need a combination of theory and simulation. I’m hoping we can work on this in the coming weeks as part of the preparation for the siggraph presentation. Even if it doesn’t make it into the presentation, we probably have enough time (say till the end of the year) to come up with a more physically based model for the 1.2 release.

@AdrienHerubel AdrienHerubel marked this pull request as draft September 30, 2025 15:36
@AdrienHerubel AdrienHerubel removed the 1.2 label Dec 9, 2025
@AdrienHerubel
Copy link
Copy Markdown
Contributor

I am removing the roughening from the 1.2 scope as discussed in the meeting. We currently don't have a consensus for a good approximation of the roughening effect and having a built in approximation that is not satisfactory and can't be dialed down could be detrimental. We could acknowledge in the spec that roughening should happen but that the literature does not provide a suitable approximation at the moment.

@portsmouth
Copy link
Copy Markdown
Contributor Author

The write-up should probably be clearer about how this works when anisotropy is present (i.e. it just remaps the roughness, and doesn't alter the base anisotropy. Which hopefully is a reasonable approximation if the coat is anisotropic, though probably not if the coat itself is anisotropic).

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.

3 participants