Coincidentally I was looking at the problem of layers in the last few days trying to improve clear coating. It's possible to account exactly the amount of light reflected by the bottom layer if you assume that the light will hit the same microfacet always, just like you can do with a thin glass material. It's a simple geometric series and I came up with the following formula:
r is the fresnel reflectance from the light exiting the top layer, bottomColor is the reflected color by the bottom layer. prtselect is a function that select the first argument is the 3th argument is true or the 2th if false for each individual components.
Code: Select all
inline Color dualLayerRefl(const Color &r, const Color &bottomColor)
{
const auto t = White - r;
const auto bt = bottomColor * t;
return bt +
pow2(bt) * (
r + r * bottomColor * (prtselect(t.reciprocal(), White, t > 0) - White)
);
}
// Then you use it like this: F is the fresnel reflectance from the light entering the top layer
colorReflected = dualLayerRefl(r, bottomColor) * (White - F);
*EDIT* I adjusted my function which didn't handle bottomColor value higher than 1.