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

Define the glossy-diffuse albedo to explicitly correct for darkening #165

Conversation

portsmouth
Copy link
Contributor

@portsmouth portsmouth commented Feb 23, 2024

Addresses issue #141.

We need to explain that, although physically the glossy-diffuse slab (as described) should exhibit darkening/saturation due to the same physics as the coat darkening (i.e. multiple bounces inside the gloss layer losing energy as they hit the colored base), we want to prevent this so that the user sees -- to the extent possible -- the base color she selected.

But she can't see the exact base color she selected, because the Fresnel of the gloss is superimposed on the diffuse base lobe. So we make the required color be a blend of the Fresnel and unsaturated base color (i.e. essentially the albedo-scaling formula). This is the same mechanism we used to define how the coat "un-darkening" works. Thus albedo-scaling automatically does the right thing (but if the implementation does something different, e.g. more physically correct, it is still well-defined what the goal albedo needs to be so the appearance won't break).

Note this won't make any difference to implementations that already use the albedo-scaling approximation (e.g. Arnold, MaterialX).

This will need to be tweaked once we get the coat darkening PR #162 in, as it should reference that discussion.

image

@portsmouth
Copy link
Contributor Author

portsmouth commented Apr 2, 2024

This need to be refactored slightly to match the refactored discussion of the subsurface remapping (#171), as it involves basically the same idea. Done.

@portsmouth portsmouth marked this pull request as ready for review April 9, 2024 21:30
to make it clear that we do not define the albedo of the Oren-Nayar lobe directly,
we instead define the specified "observed base color at normal incidence" C according to an equation,
which would then constrain the albedo of the lobe to satisfy that.

In albedo-scaling approx., it just reduces to requiring albedo=C.

The resulting BRDF of the glossy-diffuse slab is the combination of a "glossy" specular lobe provided by reflection from the dielectric interface, and a diffuse lobe provided by bounces off the substrate. This models for example the reflection from shiny, totally opaque surfaces such as dense plastic, rock, and concrete. This form of BRDF model is classic in computer graphics and typically termed the Ashikhmin-Shirley or Kelemen model ([#Ashikhmin2000], [#Kelemen2001], [#Kulla2017], [#Kutz2021]).
Physically there will be darkening and saturation of the observed color due to multiple inter-reflections (scattering) within the gloss layer, as described in the coat darkening section. However in this case, we wish to automatically compensate for this effect by adjusting the albedo of $f_\mathrm{diffuse}$ in order to make the observed color match the input color $\mathbf{C} =$ **`base_weight`** * **`base_color`** (in a similar spirit to the albedo remapping described in the Subsurface section).
Copy link
Contributor

@peterkutz peterkutz Apr 12, 2024

Choose a reason for hiding this comment

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

I'm assuming the "coat darkening section" is not something that can be linked to? (No link is produced for this section reference.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will be linked to eventually, just it's still in review. The method we use to define the coloring of:

  • coat
  • glossy-diffuse
  • subsurface

are all using the same basic formulation, so we should make sure to connect the discussions.

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense and sounds good.



Glossy-diffuse params | Label | Type | Range | Default | Description
----------------------|-----------|----------|:----------------:|:-------------------:|----------------------------------------------
**`base_weight`** | Weight | `float` | $ [0, 1] $ | $ 1 $ | Scalar multiplier to **`base_color`**
**`base_color`** | Color | `color3` | $ [0, 1]^3 $ | $ (0.8, 0.8, 0.8) $ | Reflection albedo color of $f_\mathrm{diffuse}$
**`base_color`** | Color | `color3` | $ [0, 1]^3 $ | $ (0.8, 0.8, 0.8) $ | Base reflection albedo color according to equation [glossy_diffuse_albedo_constraint].
**`base_roughness`** | Roughness | `float` | $ [0, 1] $ | $ 0 $ | Roughness of the diffuse lobe $f_\mathrm{diffuse}$
Copy link
Contributor

Choose a reason for hiding this comment

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

Tangential, but I feel like the behavior would clearer if "base roughness" were instead called "diffuse roughness".

Copy link
Contributor

Choose a reason for hiding this comment

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

Jamie suggested base_diffuse_roughness on Slack, which would eliminate the ambiguity while keeping the "base" concept intact.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can raise this at the meeting, if we have time. In any case, that change would be for a different PR.

index.html Outdated
\begin{eqnarray} \label{glossy_diffuse_albedo_constraint}
\mathbf{E}_\textrm{diffuse} = \bigl( 1 - \mathbf{E}_\textrm{spec} \bigr) \mathbf{C} \ .
\end{eqnarray}
In other words, the selected color $\mathbf{C}$ parametrizes the fraction of the energy transmitted into the dielectric layer that is subsequently transmitted back out due to reflection from the base interface. Thus since $0 \le \mathbf{C} \le 1$, $\mathbf{E}_\textrm{glossy-diffuse} \le 1$ so energy is always conserved, and if $\mathbf{C}=1$ then $\mathbf{E}_\textrm{glossy-diffuse}=1$ which guarantees that a white $\mathbf{C}$ passes the furnace test. According to this definition, $\mathbf{C}$ is the observed reflection color (viewed at normal incidence under uniform illumination) in areas where the Fresnel reflection is negligible, and otherwise the observed color is a blend of $\mathbf{C}$ with the gray Fresnel reflection that conserves total reflected energy.
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to clarify, in this version of the text, the base color behaves similarly to the subsurface color in that it represents the observed color. However, as discussed on Slack, we would like to modify this such that the base color instead represents the single-scattering microfacet albedo, implying that the observed diffuse color will be darker / more saturated than the specified color (when it's not white). This will be consistent with our current description of the metal component.

Copy link
Contributor Author

@portsmouth portsmouth Apr 15, 2024

Choose a reason for hiding this comment

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

I don't think that scheme (i.e. saying we "only take single-scattering into account" in $\mathbf{E}_\textrm{diffuse}$) works, since e.g. if the "observed" color $\mathbf{C}$ is white, there is no way for single-scattering to achieve that without violating energy conservation (since even with a white base albedo, single-scattering loses energy).

The way we set this up we demanded that if the selected/desired color $\mathbf{C}$ is white, the base must preserve energy, so cannot just omit the multiple scattering. (Also technically, Oren-Nayar doesn't cleanly split into single and multiple scattering terms like a GGX microfacet model, so it's not really clear what "single-scattering Oren-Nayar" model means).

I think the right way to say it is to say that the formulas define what the Oren-Nayar albedo has to be in the zero roughness case (i.e. assuming a Lambertian base). Assuming albedo-scaling, this simply implies that the Oren-Nayar albedo equals $\mathbf{C}$. Then given that albedo, the actual roughness is used when evaluating the BRDF. The albedo cannot increase just by increasing the roughness, since all that does is add more energy dissipation, it can only darken/saturate.

Copy link
Contributor Author

@portsmouth portsmouth Apr 15, 2024

Choose a reason for hiding this comment

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

I think it makes sense to add this change for now, even though it doesn't seem to affect anything
(189e2f8):

image

This will be more important though in a subsequent PR where I give the specific form of the Oren-Nayar lobe, including the energy compensation, which exhibits the darkening/saturation due to roughening. Then it will be more obvious that this form of the definition is required.

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense. That looks like a good clarification for future proofing.

Copy link
Contributor

@peterkutz peterkutz left a comment

Choose a reason for hiding this comment

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

These changes look good to me. It seems like this area might need another pass once the rough diffuse model is finalized, but it seems fine to merge this PR for now.

@portsmouth
Copy link
Contributor Author

Ready to merge.

@AdrienHerubel AdrienHerubel self-requested a review April 16, 2024 14:12
Copy link
Contributor

@AdrienHerubel AdrienHerubel left a comment

Choose a reason for hiding this comment

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

This PR adds a principled description of the current behavior for the glossy/diffuse lobe energy preservation.

@jstone-lucasfilm jstone-lucasfilm changed the title Define the glossy-diffuse albedo to explicitly correct for darkening. Define the glossy-diffuse albedo to explicitly correct for darkening Apr 16, 2024
@jstone-lucasfilm jstone-lucasfilm merged commit 10695cc into AcademySoftwareFoundation:main Apr 16, 2024
1 check passed
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.

None yet

4 participants