Cleanup: remove redundant fresnel_dielectric()

We already have two other functions doing very much the same thing.
`bsdf_microfacet_sample()` seems to be the only place where this
function was used; there we always sample visible normals, so the extra
`inside` check is not needed.
This commit is contained in:
Weizhen Huang
2023-09-07 18:55:48 +02:00
parent 21ca47d81f
commit f96b9db610
2 changed files with 15 additions and 56 deletions
+12 -14
View File
@@ -590,6 +590,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
}
const float m_eta = bsdf->ior;
const float m_inv_eta = 1.0f / bsdf->ior;
const bool m_refraction = CLOSURE_IS_REFRACTION(bsdf->type);
const bool m_glass = CLOSURE_IS_GLASS(bsdf->type);
const float alpha_x = bsdf->alpha_x;
@@ -624,14 +625,14 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
H = X * local_H.x + Y * local_H.y + N * local_H.z;
}
const float cos_HI = dot(H, wi);
bool valid;
/* The angle between the half vector and the refracted ray. Not used when sampling reflection. */
float cos_HO;
bool do_refract;
float lobe_pdf;
if (m_refraction || m_glass) {
bool inside;
float fresnel = fresnel_dielectric(m_eta, H, wi, wo, &inside);
valid = !inside;
float fresnel = fresnel_dielectric(cos_HI, m_eta, &cos_HO);
/* For glass closures, we decide between reflection and refraction here. */
if (m_glass) {
@@ -640,32 +641,30 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
}
else {
/* For pure refractive closures, refraction is the only option. */
if (fresnel == 1.0f) {
return LABEL_NONE;
}
do_refract = true;
lobe_pdf = 1.0f;
valid = valid && (fresnel != 1.0f);
}
}
else {
/* Pure reflective closure, reflection is the only option. */
valid = true;
lobe_pdf = 1.0f;
do_refract = false;
}
const float cos_HI = dot(H, wi);
if (do_refract) {
/* wo was already set to the refracted direction by fresnel_dielectric. */
// valid = valid && (dot(Ng, *wo) < 0);
*wo = refract_angle(wi, H, cos_HO, m_inv_eta);
/* If the IOR is close enough to 1.0, just treat the interaction as specular. */
m_singular = m_singular || (fabsf(m_eta - 1.0f) < 1e-4f);
}
else {
/* Eq. 39 - compute actual reflected direction */
*wo = 2 * cos_HI * H - wi;
valid = valid && (dot(Ng, *wo) > 0);
}
if (!valid) {
if ((dot(Ng, *wo) < 0) != do_refract) {
return LABEL_NONE;
}
@@ -706,9 +705,8 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
lambdaI = bsdf_aniso_lambda<m_type>(alpha_x, alpha_y, local_I);
}
const float cos_HO = dot(H, *wo);
const float common = D / cos_NI *
(do_refract ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) :
(do_refract ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI * m_inv_eta) :
0.25f);
*pdf = common * lobe_pdf / (1.0f + lambdaI);
@@ -718,7 +716,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
}
*sampled_roughness = make_float2(alpha_x, alpha_y);
*eta = do_refract ? 1.0f / m_eta : m_eta;
*eta = do_refract ? m_inv_eta : m_eta;
return (do_refract ? LABEL_TRANSMIT : LABEL_REFLECT) |
(m_singular ? LABEL_SINGULAR : LABEL_GLOSSY);
+3 -42
View File
@@ -17,15 +17,15 @@ ccl_device float fresnel_dielectric(float cos_theta_i, float eta, ccl_private fl
/* Using Snell's law, calculate the squared cosine of the angle between the surface normal and
* the transmitted ray. */
const float cos_theta_t_sq = 1.0f - (1.0f - sqr(cos_theta_i)) / sqr(eta);
if (cos_theta_t_sq <= 0) {
const float eta_cos_theta_t_sq = sqr(eta) - (1.0f - sqr(cos_theta_i));
if (eta_cos_theta_t_sq <= 0) {
/* Total internal reflection. */
return 1.0f;
}
cos_theta_i = fabsf(cos_theta_i);
/* Relative to the surface normal. */
const float cos_theta_t = -safe_sqrtf(cos_theta_t_sq);
const float cos_theta_t = -safe_sqrtf(eta_cos_theta_t_sq) / eta;
if (r_cos_theta_t) {
*r_cos_theta_t = cos_theta_t;
@@ -48,45 +48,6 @@ ccl_device_inline float3 refract_angle(const float3 incident,
return (inv_eta * dot(normal, incident) + cos_theta_t) * normal - inv_eta * incident;
}
ccl_device float fresnel_dielectric(
float eta, const float3 N, const float3 I, ccl_private float3 *T, ccl_private bool *is_inside)
{
float cos = dot(N, I), neta;
float3 Nn;
// check which side of the surface we are on
if (cos > 0) {
// we are on the outside of the surface, going in
neta = 1 / eta;
Nn = N;
*is_inside = false;
}
else {
// we are inside the surface
cos = -cos;
neta = eta;
Nn = -N;
*is_inside = true;
}
float arg = 1 - (neta * neta * (1 - (cos * cos)));
if (arg < 0) {
*T = make_float3(0.0f, 0.0f, 0.0f);
return 1; // total internal reflection
}
else {
float dnp = max(sqrtf(arg), 1e-7f);
float nK = (neta * cos) - dnp;
*T = -(neta * I) + (nK * Nn);
// compute Fresnel terms
float cosTheta1 = cos; // N.R
float cosTheta2 = -dot(Nn, *T);
float pPara = (cosTheta1 - eta * cosTheta2) / (cosTheta1 + eta * cosTheta2);
float pPerp = (eta * cosTheta1 - cosTheta2) / (eta * cosTheta1 + cosTheta2);
return 0.5f * (pPara * pPara + pPerp * pPerp);
}
}
ccl_device float fresnel_dielectric_cos(float cosi, float eta)
{
// compute fresnel reflectance without explicitly computing