Closed portsmouth closed 2 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:
Here's an algorithmic description of the new proposed approach itself:
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.
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.
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.
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):
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.