Eta param order could be wrong when calculating half vector
bing007 opened this issue · comments
Hi, I couldn't wrap my head around about the order of eta arguments being passed to computeNormalizedRefractionHalfVector
in BsdfTransmissionCookTorrance.cc
// Compute microfacet / half vector, pointing towards the surface side
// with the lowest ior
Vec3f m;
if (!computeNormalizedRefractionHalfVector(mEtaI,
slice.getWo(),
etaT,
wi,
m)) {
return sBlack;
}
but the method is expecting the order etaT, wo, etaI, wi, m
as shown below as well as in the paper:
// H is always pointing towards medium with lowest IOR, but only if wo and wi
// are pointing on opposite side of the surface (wrt. N).
finline bool
computeNormalizedRefractionHalfVector(const float iorWo, const scene_rdl2::math::Vec3f &wo,
const float iorWi, const scene_rdl2::math::Vec3f &wi, scene_rdl2::math::Vec3f &H)
{
static const float halfVectorLengthMinSqr = 0.001f * 0.001f;
H = -(iorWo * wo + iorWi * wi);
float lengthHSqr = lengthSqr(H);
if (lengthHSqr > halfVectorLengthMinSqr) {
H *= scene_rdl2::math::rsqrt(lengthHSqr);
return true;
} else {
return false;
}
}
![image](https://private-user-images.githubusercontent.com/15345041/265291101-54b1fce9-4828-4692-81e5-b64f3423cae8.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjI0NTc2NTYsIm5iZiI6MTcyMjQ1NzM1NiwicGF0aCI6Ii8xNTM0NTA0MS8yNjUyOTExMDEtNTRiMWZjZTktNDgyOC00NjkyLTgxZTUtYjY0ZjM0MjNjYWU4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MzElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzMxVDIwMjIzNlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTE4OTczNjZkMDYwMjJlNGM1ZDg1YzM5MzcxN2JjNWE0MjRhYzZkOTI1ZDVlOTliNTM0NjJjYjhlZDkyNDAyZjUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0._ClYyzsMSZo0Bc-gtkxgRIjrbtminTt-60lw6wwDcH8)
Thanks,
If we search the usage of these ETAs, there appear to be other usages with similar issues.
eval
does not produce any result as it always returns at this check:
// Exclude cases where microfacet m is pointing to the opposite side of
// the surface (wrt. N). This corresponds to the X+(m.n) term of the normal
// distribution function D(m); see eq. (25), (30) or (33)
const float cosThetaM = dot(m, mFrame.getN());
if (cosThetaM <= sEpsilon) return sBlack;