Now, this may (probably) be just silly, but my initial idea regarding the SampleF was that if wo is near the horizon, it's likely we're in a grazing angle situation and we want to sample the coating. Thus we can use wo to calculate the fresnel factor and adjust the sampling ratio based on this. Something like
- Code: Select all
const float u = fabsf(wo.z);
const float S = SchlickFresnel(u).Filter(sw);
const float w_diff = 0.5f * (1.f - S);
if (u3 < w_diff) {
// Cosine-sample the hemisphere, flipping the direction if necessary
*wi = CosineSampleHemisphere(u1, u2);
... etc ...
} else {
u2 *= 4.f;
const float cos2theta = u1 / (roughness * (1 - u1) + u1);
const float costheta = sqrtf(cos2theta);
const float sintheta = sqrtf(1.f - cos2theta);
const float p = 1.f - fabsf(anisotropy);
... etc ...
}
...
const float specPdf = SchlickZ(H.z) * SchlickA(H) / (4.f * M_PI);
*pdf = w_diff * fabsf(wi->z) * INV_PI + (1.f - w_diff) * specPdf / fabsf(wo.z);
...
Thus as one approaches grazing angles the probability for sampling the diffuse layer drops quickly, while at near normal angles, the probability is the old 50% (which seems to work well).
As you probably noticed I had to add u3, for testing I used the one from SingleBSDF (which is unused there), but if we go for this we'd have to add another random number to SampleF proper (this would be needed if we ever implement a proper layered material anyway).
Anyway, with similar changes to Pdf() I'm getting less noise here on my testing scene, and at high spp there's virtually no change so I believe it's not that far from behaving correct. However I'm really not sure about pdfBack, which may be more tricky than I hoped. Currently I recompute the fresnel factor using the sampled wi:
- Code: Select all
if (pdfBack) {
const float u_back = fabsf(wi->z);
const float S_back = SchlickFresnel(u_back).Filter(sw);
const float w_diff_back = 0.5f * (1.f - S);
*pdfBack = w_diff_back * fabsf(wo.z) * INV_PI + (1.f - w_diff_back) * specPdf / fabsf(wi->z);
}
Surely it can't be this simple?

May contain traces of nuts.