-
Notifications
You must be signed in to change notification settings - Fork 18
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
Update behavior of specular_weight, specular_ior_level, coat_ior_level #157
Update behavior of specular_weight, specular_ior_level, coat_ior_level #157
Conversation
Corresponding changes will be needed in the MaterialX graph (and our native implementations). I'll leave those for a separate PR though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice.
With this new parametrisation, I believe we need to remove specular_weight
from the metal section.
We could do, as it functions currently (for the metal) only as a multiplier of the This means we would remove the instances of |
…ular_weight. Disallow specular_weight > 1.
In bffd9e1 I changed as follows:
A more physical scheme would amount to somehow lowering the IOR of the metal to 1, as in the dielectric case, producing a narrowing of the Fresnel highlight rather than a suppression, but this is not doable in the standard Schlick representation, so the linear scaling with the weight seems likely the best approach. (Though note that the |
…_color_changes # Conflicts: # index.html
…penPBR into specular_weight_and_color_changes # Conflicts: # index.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it is a good change overall, there are two propositions I'm not comfortable with:
specular_weight
affecting the metal lobe, as I strongly suspect it will yield inconsistent behaviour.specular_weight
limited to 1, thus preventing from locally increasing specular reflection. I think a use case would be gemstones on a character outfit. There is also the problem of converting existing assets, given that a modulation up to 2 has been common in several major tools for about a decade.
\end{equation} | ||
This formulation has the useful property that it reduces to the regular Schlick reflectivity at the default values of $\mathtt{specular\_weight}$ and $\mathtt{specular\_color}$. Note that the edge cannot be brighter than the standard Schlick term, but this is generally true in real metals. We consider this a benefit of this parametrization, as it makes it impossible to produce physically implausible metals with excessively bright edges. | ||
The final metallic Fresnel term we employ is then given by an overall multiplication by **`specular_weight`**, ensuring that entire metallic lobe is suppressed as the weight goes to zero: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about the implications of this description.
Suppose an artist makes a material with a combination of dielectric and metal. Then after the fact, they want to tune the specular reflection with a uniform specular_weight
. They are not going to observe the same behaviour on the dielectric and metal parts, which I think could be questionable.
I should also note, given the recent discussions on the metal-rough model, that there is a bit of inconsistency in how the metal layer is parametrised: other layers have a weight that acts as a coverage parameter. One could argue metalness
is conceptually close to that role.
More discussion is needed here, both short and longer term.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suppose an artist makes a material with a combination of dielectric and metal. Then after the fact, they way to tune the specular reflection with a uniform specular_weight. They are not going to observe the same behaviour on the dielectric and metal parts, which I think could be questionable.
I think actually it's more sensible now than it was before, since now the specular_weight
directly dials the normal-incidence reflectance (i.e. F0) of both the dielectric and the metal.
Before, we had it only affecting the F82-tint color of the metal, but not the F0. I found that more inconsistent, since the F0 is the dominant effect. (Also, it didn't allow the metal lobe to be zeroed, as you noticed, so we have to have the weight multiply the entire lobe instead, which is more consistent with the dielectric F0 anyway).
The specular_weight
multiplies the metallic lobe though, rather than operating via the IOR, so the effect is of course slightly different (suppression at grazing angles, rather than "tightening of the white highlight"). But we don't have an IOR control for the metal, so it's not possible to make them match to that extent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should also note, given the recent discussions on the metal-rough model, that there is a bit of inconsistency in how the metal layer is parametrised: other layers have a weight that acts as a coverage parameter. One could argue metalness is conceptually close to that role.
No, the metal is a component of the base, mixed with the "non-metallic base", according to the base_metalness
. So base_metalness
operates as a mix weight, not a coverage weight. Similarly for transmission_weight
and subsurface_weight
.
A coverage weight only makes sense for a layer which can optionally "cover" another, i.e. the coat and fuzz layers.
Note that we also decided against trying to interpret specular_weight
as the coverage weight of the diffuse base with dielectric (since the dielectric is not really functioning as a layer, it is really the base substrate in which the scattering media of the transmission/subsurface/glossy-diffuse slabs are embedded). Instead, specular_weight
operates by modulating the IOR of the unified base dielectric.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then after the fact, they way to tune the specular reflection with a uniform specular_weight. They are not going to observe the same behaviour on the dielectric and metal parts, which I think could be questionable.
I see what you mean though, if they have a textured metalness, then the single specular_weight
affects both the metal and dielectric parts (now in roughly the same way -- by multiplying the F0), which maybe they don't want. They'd have to modulate the weight by the metalness map.
This goes back to our discussions (on Slack and in #140) about having a separate optional parametrization for metal. If you really want this use case of e.g. metal and non-metal bits on the same object, you have to deal with blending of various maps to get that look, and then get issues in the transition regions because you are trying to represent a 50/50 mix of metal and dielectric with blended maps driving both the metal and dielectric BRDFs, instead of independent maps for the two BRDFs.
A solution is something like the proposed additional metal params in #140 (comment). But that adds a fair bit of complexity to our model. My compromise approach is to accept that these issues are real, but treat this as a limitation of our model that we traded off for ease of use and simplicity. I would even propose to say something in the spec about textured metalness being problematic, and that we really intended metalness to be more like a binary selector over the entire surface, or very smoothly varying, and not something which is allowed to have harsh transitions (though I know that in reality, people certainly use metalness to represent areas of metal/dielectric "coat" or "substrate" living in a background of dielectric/metal).
For better quality results, people can always do more elaborate things like use MaterialX to add layers of dielectric stuff on top of OpenPBR metal, say. (To model rust more correctly for example, physically it should be a layer of semi-opaque rust on top of a substrate metal -- which is just not representable in OpenPBR since our only layers are an absorbing dielectric coat and fuzz).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree this is an improvement over the previous proposition, and I don't see a better alternative.
My concern is whether this could become a subject of complain, and if it does, can we still make a better proposal in a future without being locked by this decision.
That being said, if in the future we decide to go toward separate metal parameters, then this one parameter would likely be overridden for metal anyway, so I guess we're safe.
Co-authored-by: Julien Guertault <9511025+virtualzavie@users.noreply.github.com> Signed-off-by: Jamie Portsmouth <jamports@mac.com>
We've discussed this a fair bit before. I think it would be fine to allow I find the proposed use-cases a bit unconvincing though, as if you're doing gemstones on a costume you could just set the IOR to that of the gemstones, and lower the Also, above I noted:
Which is true, e.g. if at |
Once we're happy with these proposed changes to the specification, I'd recommend that we include the matching updates to the reference implementation in this same pull request. This should allow us to validate the new user controls before merging, and will also insure that our specification and reference implementation remain in sync as we approach a 1.0 release. |
index.html
Outdated
|
||
The Fresnel factor $F(\omega_i, h)$ is determined by the index of refraction of the reflecting material, and its form differs depending on whether the material is a dielectric or conductor [#Walter2007]. Its parametrization in each case is described in the Dielectric base section and Metal section. The _masking-shadowing function_ $G(\omega_i, \omega_o)$ accounts for the probability that the input and output directions are occluded by the microsurface. It is usually derived using the Smith model which determines $G$ given the NDF, and for the GGX NDF equation [GGX] the masking-shadowing function then has a well-known form [#Heitz2014b]. | ||
The Fresnel factor $F(\omega_i, h)$ is determined by the complex index of refraction of the reflecting material of each microfacet, and its form differs depending on whether the material is a dielectric or conductor [#Walter2007]. Its parametrization in each case is described in the Dielectric base section and Metal section. The _masking-shadowing function_ $G(\omega_i, \omega_o)$ accounts for the probability that the input and output directions are occluded by the microsurface. It is usually derived using the Smith model which determines $G$ given the NDF, and for the GGX NDF equation [GGX] the masking-shadowing function then has a well-known form [#Heitz2014b]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is "masking-shadowing function" emphasized, but the other factors are not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed up in e6a15d3
index.html
Outdated
|
||
The Fresnel factor $F(\omega_i, h)$ is determined by the index of refraction of the reflecting material, and its form differs depending on whether the material is a dielectric or conductor [#Walter2007]. Its parametrization in each case is described in the Dielectric base section and Metal section. The _masking-shadowing function_ $G(\omega_i, \omega_o)$ accounts for the probability that the input and output directions are occluded by the microsurface. It is usually derived using the Smith model which determines $G$ given the NDF, and for the GGX NDF equation [GGX] the masking-shadowing function then has a well-known form [#Heitz2014b]. | ||
The Fresnel factor $F(\omega_i, h)$ is determined by the complex index of refraction of the reflecting material of each microfacet, and its form differs depending on whether the material is a dielectric or conductor [#Walter2007]. Its parametrization in each case is described in the Dielectric base section and Metal section. The _masking-shadowing function_ $G(\omega_i, \omega_o)$ accounts for the probability that the input and output directions are occluded by the microsurface. It is usually derived using the Smith model which determines $G$ given the NDF, and for the GGX NDF equation [GGX] the masking-shadowing function then has a well-known form [#Heitz2014b]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: have F, G and D in 3 separate paragraphs.
The Fresnel factor $F(\omega_i, h)$ is determined by the complex index of refraction of the reflecting material of each microfacet, and its form differs depending on whether the material is a dielectric or conductor [#Walter2007]. Its parametrization in each case is described in the Dielectric base section and Metal section. The _masking-shadowing function_ $G(\omega_i, \omega_o)$ accounts for the probability that the input and output directions are occluded by the microsurface. It is usually derived using the Smith model which determines $G$ given the NDF, and for the GGX NDF equation [GGX] the masking-shadowing function then has a well-known form [#Heitz2014b]. | |
The Fresnel factor $F(\omega_i, h)$ is determined by the complex index of refraction of the reflecting material of each microfacet, and its form differs depending on whether the material is a dielectric or conductor [#Walter2007]. Its parametrization in each case is described in the Dielectric base section and Metal section. | |
The _masking-shadowing function_ $G(\omega_i, \omega_o)$ accounts for the probability that the input and output directions are occluded by the microsurface. It is usually derived using the Smith model which determines $G$ given the NDF, and for the GGX NDF equation [GGX] the masking-shadowing function then has a well-known form [#Heitz2014b]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in ec47ee0.
index.html
Outdated
|
||
- The specular lobe shape is controlled by the roughness properties of the surface, parametrized by **`specular_roughness`**, **`specular_anisotropy`**, and **`specular_rotation`** (see the section on the [Microfacet model](index.html#model/microfacetmodel) NDF). | ||
- The **`specular_ior`** parameter controls the index of refraction (IOR) of the dielectric. The **`specular_weight`** parameter provides a convenient, texturable linear $[0, 1]$ multiplier of the dielectric reflectivity at normal incidence via modulation of this reference IOR. When **`specular_weight`** is $0$, the specular reflection disappears entirely, as the IOR of the dielectric is then equal to that of the surrounding medium. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to ourselves: this is where we want to briefly define the behaviour above 1 (how we prevent non sensical values would probably be better explained with equation modulated_ior
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thank you.
index.html
Outdated
**`specular_weight`** | Weight | `float` | $ [0, 1] $ | | $ 1 $ | Scalar multiplier to the dielectric Fresnel factor | ||
**`specular_weight`** | Weight | `float` | $ [0, 1] $ | | $ 1 $ | Modulates the dielectric reflectivity at normal incidence | ||
**`specular_color`** | Color | `color3` | $ [0, 1]^3 $ | | $ (1, 1, 1) $ | Tints the dielectric Fresnel factor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit of nitpicking: there's an inconsistency in that specular_weight
and specular_color
are described by verbs when other parameters are described by nouns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't find it a problem personally.. They are just descriptions, with slightly different phrasing (it's a scalar multiplier, versus it modulates.. etc. Both work).
index.html
Outdated
where the range of $\xi_c$ is clamped according to $\xi_c \in [0, \mathrm{min}(1, 1/(2 F_c)]$. Inserting this modulated IOR ratio $\eta^\prime_c$ in the coat Fresnel factor then produces the desired reflectivity modulation. | ||
|
||
If there is a fractional $\mathtt{coat\_weight}$ $\mathtt{C}$, then the surrounding IOR of the base dielectric or metal varies statistically across the surface depending on whether the coat is locally present (the fuzz layer can be assumed to have the ambient IOR $n_\mathrm{ambient}$). A reasonable approximation of this is to take the surrounding effective coat IOR to be a linear blend [^lerp] between the ambient and modulated coat IORs according to the coat weight: | ||
The IOR of the coat medium $V_\mathrm{coat}$, controlled by the **`coat_ior`** parameter, will alter the Fresnel factor of both the coat top interface and the underlying metal or dielectric. If there is a fractional $\mathtt{coat\_weight}$ $\mathtt{C}$, then the surrounding IOR of the base dielectric or metal varies statistically across the surface depending on whether the coat is locally present (the fuzz layer can be assumed to have the ambient IOR $n_\mathrm{ambient}$). A reasonable approximation of this is to take the surrounding effective coat IOR to be a linear blend [^lerp] between the ambient and coat IORs according to the coat weight: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking: do we know how far the proposed approximation is from ground truth? I'm wondering if "reasonable approximation" is a fair description, or if we might want to use a different adjective like "acceptable".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the stated approximation is very bad indeed.. Thanks for drawing attention to this.
For example, consider if the ambient IOR is 1, the coat_ior = 2
, and specular_ior = 1.5
. Then coat weight = 0.5
would (according to this approximation) lead to no base specular reflection (since the "effective" coat IOR is 1.5, same as the base dielectric), i.e.
Really the integrator should statistically mix between the coated and uncoated configurations. While still approximate, a clearly better formulation is to take:
This produces
I've added that in a1c4d90:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current state of the PR looks good to me.
…m/portsmouth/OpenPBR into specular_weight_and_color_changes
In 0e9560a I updated the MaterialX graph to remove I verified that this compiles in the MaterialX viewer, and seems to work correctly. |
This looks great, thanks @portsmouth, and my only suggestion is to double-check that @AntonPalmqvist's example materials render correctly using this new parameterization. |
@portsmouth I've looked at each of the example materials, and the only unusual result I see is that |
0f3eea8
into
AcademySoftwareFoundation:main
This implements the changes proposed in
which we agreed to go ahead with in the recent meetings.
The
specular_ior_level
param is removed, and replaced byspecular_weight
which works in the same way. I incorporated the facility to increase thespecular_weight
to values >1, though with a soft-max at 1 -- retaining the facility we had before, though actually more flexible since it doesn't get capped at an arbitrary maximum value of 2 (it just gets capped by the requirement that the Fresnel factor cannot exceed 1). This seems reasonable and potentially convenient (though we may want to verify that it behaves OK in practice).The
specular_weight
is now no longer involved in the Fresnel factor multiplier, onlyspecular_color
. We state that this is applied only to one specific scattering mode (the initial Fresnel reflection from above), and call it out explicitly as an unphysical convenience.The
coat_ior_level
param is also removed, simplifying the coat discussion: