I'm getting some strange results with the layered material which I think are coming from my sampleF() function. Here's the current code :
- Code: Select all
bool LayeredBSDF::SampleF(const SpectrumWavelengths &sw, const Vector &known, Vector *sampled,
float u1, float u2, float u3, SWCSpectrum *const f_, float *pdf,
BxDFType flags, BxDFType *sampledType, float *pdfBack,
bool reverse) const
{
// Currently this checks to see if there is an interaction with the layers based on the opacity settings
// If there is no interaction - let the ray pass through and return a specular
// Otherwise returns a glossy (regardless of underlying layer types)
// Have two possible types to return - glossy or specular - see if either/both have been requested
bool glossy= (flags & BSDF_GLOSSY) ? true : false;
bool specular= (flags & BSDF_SPECULAR) ? true : false;
bool reflect= (flags & BSDF_REFLECTION) ? true : false;
bool transmit= (flags & BSDF_TRANSMISSION) ? true : false;
if (!reflect && !transmit) { // new convention
reflect=true;
transmit=true;
}
*pdf = 1.0f;
if (pdfBack) {
*pdfBack = 1.0f;
}
if (glossy&&specular) { // then choose one
if (u1<prob_sample_spec) {
glossy=false; // just do specular
*pdf *= prob_sample_spec;
}
else {
specular=false; // just do glossy
*pdf *= (1.0f-prob_sample_spec);
}
}
if (reflect&&transmit) { // choose one
RandomGenerator rng(getRandSeed());
if (rng.floatValue()<0.5) {
reflect=false;}
else {
transmit=false;
}
*pdf *=0.5;
}
SWCSpectrum F(0.f);
float fwdpdf=1.0f;
float backpdf=1.0f;
if (glossy) { // then random sample hemisphere and return F() value
Sample_F_glossy(sw, known, sampled, &F, &fwdpdf, sampledType, &backpdf,
reverse,transmit,u2,u3);
}
if (specular) { // then random sample a specular path and return it
Sample_F_specular(sw, known, sampled, &F, &fwdpdf, sampledType, &backpdf,
reverse,transmit);
}
*f_=F / *pdf;
if (pdfBack) {
*pdfBack *= *pdf * backpdf;
}
*pdf *= fwdpdf;
return true;
}
Sample_F_specular returns the F() for a randomly chosen path that has only specular interactions.
Sample_F_glossy returns the F() for every other type of path - but won't include purely specular paths. I'm calling any path that involves at least one diffuse or glossy interaction a glossy.
If both glossy and specular samples are valid then I choose one (based on prob_sample_spec) and adjust the pdfs . If I choose a specular then I sample a random specular path and return that. If I choose a glossy I just sample the hemisphere (uniform for now but might change to cos) and call F().
If I set prob_sample_spec=1.0f then I never sample the glossy component - so sampleF() will only return specular paths. The problem is that the diffuse still shows up - at about 50% of it's strength - presumably through a call to F().
I'm wondering if when I sample a specular I should also add in the F() for the glossy (if that's what was requested)? Ie, something like
- Code: Select all
if (specular && !glossy) : sample specular
if (!specular && glossy) : sample hemisphere and call F()
if (specular && glossy) : choose specular or hemisphere to sample. if choose specular include glossy component for that direction
This doesn't seem to be how MultiBSDF works?
