### Question about microfacet reverse pdf and SmallVCM

Posted:

**Tue Nov 01, 2016 6:23 pm**Recently I decided to implement a simple dielectric microfacet Bsdf in SmallVCM in order to be able to validate something in my own renderer. The microfacet Bsdf I'm implementing is very simple; just a Phong normal distribution for now to keep things simple and the rest based off of Walter's "Microfacet Models for Refraction through Rough Surfaces" paper, without the 2014 Eugene d'Eon visible normal important sampling extension.

I'm having some trouble with the reverse pdf for refraction. I thought I understood the reverse pdf, but apparently not since my VCM and pathtraced images using microfacet refraction aren't converging to the same thing. My understanding was that the reverse pdf is literally what the name says; it's effectively what you'd get if you ran the bsdf backwards with the input and output directions switched. I implemented the forward pdf as:

float mPdf = microfacet.calculateD(halfVectorLocal) * halfVectorLocal.z;

float eta = inputDotNormal > 0.0f ? m_eta : 1.0f / m_eta;

float bottom = (eta * inputDotHalf) + outputDotHalf;

float bottom2 = bottom * bottom;

float directPdfW = mPdf * (1.0f - fresnelTerm) * (eta * eta) * glm::abs(outputDotHalf) / (bottom2);

...as such, I thought that the reverse pdf should just be:

(ignoring the Walter trick for adjusting the roughness for importance sampling...)

float rEta = outputDotNormal > 0.0f ? m_eta : 1.0f / m_eta;

float rBottom = (rEta * outputDotHalf) + inputDotHalf;

float rBottom2 = rBottom * rBottom;

float reversePdfW = mPdf * (1.0f - fresnelTerm) * (rEta * rEta) * glm::abs(inputDotHalf) / (rBottom2);

This doesn't seem to work. Does anyone have any thoughts or hints?

Also, in SmallVCM's bsdf sampling function, the bsdf result seems to be implicitly multiplied by the PDF and divided by outCosTheta before being returned. How should this work for a microfacet brdf that doesn't have symmetrical sampling? If fromLight is true, should the sample result be multiplied by the reverse pdf instead of the forward pdf?

Any help in clearing up these questions would be greatly appreciated. Thanks!

I'm having some trouble with the reverse pdf for refraction. I thought I understood the reverse pdf, but apparently not since my VCM and pathtraced images using microfacet refraction aren't converging to the same thing. My understanding was that the reverse pdf is literally what the name says; it's effectively what you'd get if you ran the bsdf backwards with the input and output directions switched. I implemented the forward pdf as:

float mPdf = microfacet.calculateD(halfVectorLocal) * halfVectorLocal.z;

float eta = inputDotNormal > 0.0f ? m_eta : 1.0f / m_eta;

float bottom = (eta * inputDotHalf) + outputDotHalf;

float bottom2 = bottom * bottom;

float directPdfW = mPdf * (1.0f - fresnelTerm) * (eta * eta) * glm::abs(outputDotHalf) / (bottom2);

...as such, I thought that the reverse pdf should just be:

(ignoring the Walter trick for adjusting the roughness for importance sampling...)

float rEta = outputDotNormal > 0.0f ? m_eta : 1.0f / m_eta;

float rBottom = (rEta * outputDotHalf) + inputDotHalf;

float rBottom2 = rBottom * rBottom;

float reversePdfW = mPdf * (1.0f - fresnelTerm) * (rEta * rEta) * glm::abs(inputDotHalf) / (rBottom2);

This doesn't seem to work. Does anyone have any thoughts or hints?

Also, in SmallVCM's bsdf sampling function, the bsdf result seems to be implicitly multiplied by the PDF and divided by outCosTheta before being returned. How should this work for a microfacet brdf that doesn't have symmetrical sampling? If fromLight is true, should the sample result be multiplied by the reverse pdf instead of the forward pdf?

Any help in clearing up these questions would be greatly appreciated. Thanks!