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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user