AcademySoftwareFoundation / OpenPBR

Specification and reference implementation for the OpenPBR Surface shading model
Apache License 2.0
407 stars 18 forks source link

Coat/specular IOR defaults, and TIR issue if coat IOR > spec IOR #142

Closed portsmouth closed 2 months ago

portsmouth commented 8 months ago

I think coat and specular IOR should be more different now, as the coat masks the specular if the IORs are the same. Current defaults are coat=1.6, spec=1.5.

The coat IOR should probably be lower than specular by default, to further boost the spec and prevent the TIR issue (e.g. coat=1.3, spec=1.6).

Also note that if the coat IOR is higher than the spec IOR, then TIR will occur in the specular reflection lobe. This looks weird if you don't account for the fact that the coat is sitting on top which bends the rays thus preventing the TIR, e.g. see the result boxed in red below. (NB, the current Arnold and MaterialX implementations do this):

image

Adobe proposes to avoid this by inverting the IOR of the base surface, though that seems to mess with the Fresnel physics which it would be best to avoid. (Though as a workaround in an implementation, maybe it's reasonable). We may want to note this problem and suggest some approaches, as otherwise a naive implementation could produce what looks like an artifact.

peterkutz commented 7 months ago

Adobe proposes to avoid this by inverting the IOR of the base surface, though that seems to mess with the Fresnel physics which it would be best to avoid.

The IOR inversion trick is physically inspired but not fully baked. I believe we can extend the trick of inverting the IOR to produce correct reflection coefficients regardless of the layer IORs. Here's a line of reasoning that leads to a new proposed approach:

  1. Given a path consisting of a ray on one side of a surface and a refracted ray on the other side of the surface, the corresponding reflection coefficient at the surface is the same regardless of the direction of light flow along this path.
  2. The reflection coefficient corresponding to a refraction event can be calculated on either side of the surface.
  3. Only one of the two rays involved in the refraction event need to be known to correctly calculate the reflection coefficient.
  4. The final angle of the light transmitted through a stack of layers only depends on the first and last IORs, not the IORs of the layers in between.
  5. In the case of a coat medium sandwiched between an ambient medium and a base medium, the ray directions in the ambient and base media are fully specified by the ambient and base IORs (regardless of the coat medium IOR).
  6. The reflection coefficient for the scattering event at the outside of the base surface (the bottom of the coat layer) can be determined from the final refraction direction and the relative IOR of the coat and base media without ever calculating the correct direction of the light traveling within the coat.

Here's an algorithmic description of the new proposed approach itself:

  1. Ray coming from ambient medium hits outside of coat.
  2. Ray reflects correctly according the relative IOR of coat and ambient media.
  3. Ray passes straight through surface.
  4. Ray reaches back of coat / top of base surface.
  5. Ray refracts as if coat doesn't exist based on base IOR and ambient IOR.
  6. Final path is considered in reverse to calculate the reflection coefficient on the bottom of the base surface based on the final refraction direction and the relative IOR of the coat and base media.
  7. That reflection coefficient is used as the reflection coefficient at the top of the base surface, producing the correct amount of reflection from the base surface.

In summary, this approach would let us calculate correct reflection coefficients at every interface without having to deal with directional refraction by the coat and its implications on direct light sampling. It could be used unconditionally as it would work correctly regardless of whether the coat IOR is higher or lower than the others.

I'd be happy to post example numbers and/or diagrams if the description above isn't clear or intuitive.

portsmouth commented 7 months ago

I assume you're restricting to the case of perfectly smooth dielectric boundaries (so a smooth coat, on top of a smooth dielectric base). In that case it's interesting that, like you said, the refracted direction into the base dielectric can be calculated without calculating the direction of the ray in the coat.

Assuming smooth boundaries, and IOR ratios $\eta_c = n_c/n_a$ (coat/ambient) and $\eta_b = n_b/n_c$ (base/coat), the Fresnel factor for reflection from the base is say $F_R(\mu_c, \eta_b)$, where:

$$ \mu_c = \sqrt{1 - \frac{1-\mu_i^2}{\eta_c^2}} $$

is the angle cosine of the ray refracted into the coat from incident external direction $\mu_i$. TIR from the base/coat boundary (of rays incident from above, reflecting upwards) can occur if $\eta_b < 1$ (i.e. the coat IOR is higher than the base IOR), but only if this reflection is erroneously computed by using $\mu_i$ rather than $\mu_c$ (as we currently do e.g. in Arnold).

If I interpret it correctly, what you're suggesting is to rewrite this Fresnel factor in terms of the corresponding transmission out of the base:

$$F_R(\mu_c, \eta_b) = 1 - F_T(\mu_c, \eta_b) \ . $$

And then by time-reversal we can write

$$F_T(\mu_c, \eta_b) = F_T(\mu_b, 1/\eta_b)$$

and we know $\mu_b$ from your observation "the final angle of the light transmitted through a stack of layers only depends on the first and last IOR" (which follows from applying Snell's law at every interface), i.e.

$$ \mu_b = \sqrt{1 - (1-\mu_i^2)(\frac{n_a}{n_b})^2} \ .$$

So that's pretty clever since it gives the correct Fresnel factor (for reflection from the base into the upper layers) in terms only of the properties of the base (and the ambient medium), fixing the TIR artifact (inside the BRDF of the base without needing to query the surrounding coat). I agree that this would be a reasonable way to get the correct Fresnel factor without messing with the refraction direction directly. It would be easy to try out in Arnold (though I'm not entirely sure how it plays out since obviously the actual BRDF of the base dielectric is a microfacet model, not a smooth interface).

Maybe it's worth noting though that in general, this is kind of an implementation detail specific to a certain level of approximation. In reality in the smooth case there will also be Fresnel factors for the two transmissions through the coat. That is if the incident ray from above has angle cosine $\mu_i$, then the actual reflection from the base should have some Fresnel factors like

$$ F_T^2(\mu_i, \eta_c) F_R(\mu_c, \eta_b) $$

Also there will be higher order bounce modes than this "TRT" mode, i.e. all the other "TR...RT" internal reflection modes. In theory we could account for those effects also. (Obviously this is required to model the "coat darkening" effect as well).

Though of course the boundaries aren't smooth, and to account for that you probably have to resort to a full Monte Carlo simulation of the light path bouncing layer to layer (as is done in the latest PBRT for example).

So all this discussion of individual lobes representing each interface is still a slightly crude approximation, though hopefully not terribly far from the ground truth. In the spec we don't specialize to a particular approximation of course, but as noted we might want to write something about this issue as most implementations may well want to do something like your proposal to avoid the TIR artifact.

peterkutz commented 7 months ago

Nice analysis and formalization of my description.

Good point that this is still an approximation that applies to a particular idealized case could get increasingly complex if generalized.

Since (as you mentioned) we don't need to enforce a particular approximation, I wonder if it would be sufficient to mention the problem (as you originally suggested) and then provide some of these concepts as building blocks for the implementor.

Avoiding visible artifacts is probably higher priority than fully accurate light transport within the layers, so pointing out the potential problem seems like a good initial step.