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

Clarify dispersion, iridescence, and volume for zero IOR #2435

Open
lexaknyazev opened this issue Aug 20, 2024 · 3 comments
Open

Clarify dispersion, iridescence, and volume for zero IOR #2435

lexaknyazev opened this issue Aug 20, 2024 · 3 comments
Labels
extension PBR Physically Based Rendering

Comments

@lexaknyazev
Copy link
Member

lexaknyazev commented Aug 20, 2024

The KHR_materials_ior extension allows IOR value of zero to represent "infinity" IOR. The KHR_materials_dispersion, KHR_materials_iridescence, and KHR_materials_volume extensions should explicitly address this case.

/cc @emackey

@lexaknyazev lexaknyazev added extension PBR Physically Based Rendering labels Aug 20, 2024
@lexaknyazev lexaknyazev changed the title Clarify dispersion for zero IOR Clarify dispersion, iridescence, and volume for zero IOR Aug 20, 2024
@lexaknyazev
Copy link
Member Author

Let's start with the IOR extension. It uses the provided IOR value to define $f_0$:

$$f_0 = (\frac{1-\text{ior}}{1+\text{ior}})^2$$

This expression seems to assume that the outside IOR is always 1, which may be incorrect in some cases. Leaving that aside for now, let's plot it:

image

We can observe that:

  • $f_0$ is equal to 1 when IOR is equal to 0.
  • $f_0$ approaches 1 when IOR approaches $\infty$.
  • For an IOR value between 0 and 1, $f_0$ is equal to the $f_0$ of the inverse IOR value. For example, $f_0(0.5)=f_0(2)$. The proof is left as an exercise for the reader. Note that the spec disallows these values.

Implementations can replace zero with a very large number (around $2^{55}$ for doubles) to exploit floating-point precision limits and reliably get $f_0=1$ without supporting a literal zero value in the pipeline.

An interesting question here is how to handle animated IOR values. For example, keyframe 0 may have ior=0 and keyframe 1 may have ior=1. If the animation uses a non-STEP interpolation, intermediate values would be technically invalid (but the derived $f_0$ values would be fine).


Dispersion

The dispersion extension effectively defines per-wavelength IOR values. So when the base IOR is zero, i.e., infinity, all of the derived IOR values must also be zero, i.e., infinity, and therefore the dispersion should have no effect. Exact math is irrelevant here and the extension spec should just mention this case.

Iridescence

The iridescence extension uses base IOR to derive base $f_0$ and the phase shift, therefore zero IOR should be handled as a very large value.

Volume

The volume extension uses base IOR directly, therefore zero IOR should be handled as a very large value.

@bsdorra
Copy link
Contributor

bsdorra commented Sep 4, 2024

Interesting, there's no rule that disallows generation of invalid parameter values via animation? ior=0 is really just a convenience toggle to enable specular-glossiness workflow. If people are using it as part of an animation then probably not intentionally.

I noticed that there's a note in the specular extension that states that the specular-glossiness conversion via ior=0 is incompatible with the volume extension. This is technically true, as treating IOR as a very high value effectively disables transmission and therefore volume (and dispersion). But we may want to adapt the wording depending on whatever we end up adding to KHR_materials_volume.

@lexaknyazev
Copy link
Member Author

I think the zero IOR incompatibility with volume is just a physical result of using a large IOR value, rather than a spec-defined limitation, so it's not normative.

there's no rule that disallows generation of invalid parameter values via animation?

There is such a rule but in the aforementioned case it's a bit tricky because both keyframes are technically valid and whether an invalid IOR is actually reachable at runtime depends on the interpolation mode and exact time values. For example, if the time difference between the keyframes is 1 ULP, the animation won't have invalid values at runtime even with linear interpolation. One potential fix here would be to replace zeros with a very large value on load to guarantee that interpolated values are always technically valid.

To avoid updating all current and future specs that may be incompatible with the zero IOR value, we should exhaustively address this in the KHR_materials_ior spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension PBR Physically Based Rendering
Projects
None yet
Development

No branches or pull requests

2 participants