Closed calvin-godfrey closed 3 years ago
The BRDF for perfect specular reflection has a 1/cos theta_i term in it: http://www.pbr-book.org/3ed-2018/Reflection_Models/Specular_Reflection_and_Transmission.html#SpecularReflection. Note that it gets cancelled out later when the cos theta_i factor is incorporated from the reflection equation.
Some renderers return BRDF * cosTheta from their BRDF evaluation methods, which gets rid of this nit.. (So either way's fine, so long as you're consistent..)
Okay, thanks for the explanation, that makes sense!
I've been working on my own implementation based on pbrt in Rust, and for the most part, it's been smooth (if slow) sailing. But I don't understand any geometric intuition for division by
AbsCosTheta(*wi)
in the following code:To check this, I made a glass dragon with
urough=vrough=0
and an index of 1 so that its compute scattering functions would add a specularfresnel to its bsdf. I also hardcoded it so that it would only take the specular transmission path, never specular reflection. As far as I'm aware, those parameters should make the glass model completely invisible, but it ended up looking like this, where the glass was much darker than expected and I got those bight pixels even significantly far away from the model.On the other hand, if I run the exact same code, but simply have
return ft
at the bottom of the specular transmission branch, the model is invisible, as expected.To run a more 'normal' render, I changed the index to 1.5 and made it so that specular transmission and reflection were computed, and as far as I can tell, it looks (more or less) exactly as it should:
.
Now, it's certainly possible that there's something else wrong in my implementation, but it seems like the root cause is that factor, and I couldn't find anything else. Is there a geometric explanation for why that is there, or something else that I am misunderstanding?