diff --git a/intern/cycles/kernel/closure/bsdf_principled_hair_chiang.h b/intern/cycles/kernel/closure/bsdf_principled_hair_chiang.h index a7bfa8a0320..e31ed134bca 100644 --- a/intern/cycles/kernel/closure/bsdf_principled_hair_chiang.h +++ b/intern/cycles/kernel/closure/bsdf_principled_hair_chiang.h @@ -142,11 +142,13 @@ ccl_device_inline float longitudinal_scattering( if (v <= 0.1f) { float i0 = log_bessel_I0(cos_arg); float val = expf(i0 - sin_arg - inv_v + 0.6931f + logf(0.5f * inv_v)); + kernel_assert(isfinite_safe(val)); return val; } else { float i0 = bessel_I0(cos_arg); float val = (expf(-sin_arg) * i0) / (sinhf(inv_v) * 2.0f * v); + kernel_assert(isfinite_safe(val)); return val; } } @@ -185,7 +187,7 @@ ccl_device int bsdf_hair_chiang_setup(ccl_private ShaderData *sd, ccl_private Ch kernel_assert(isfinite_safe(bsdf->h)); bsdf->N = Y; - + bsdf->alpha = -bsdf->alpha; return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION; } @@ -224,9 +226,9 @@ ccl_device_inline void hair_attenuation( Ap_energy[3] *= fac; } -/* Given the tilt angle, generate the rotated theta_i for the different bounces. */ -ccl_device_inline void hair_alpha_angles(float sin_theta_i, - float cos_theta_i, +/* Update sin_theta_o and cos_theta_o to account for scale tilt for each bounce. */ +ccl_device_inline void hair_alpha_angles(float sin_theta_o, + float cos_theta_o, float alpha, ccl_private float *angles) { @@ -237,12 +239,12 @@ ccl_device_inline void hair_alpha_angles(float sin_theta_i, float sin_4alpha = 2.0f * sin_2alpha * cos_2alpha; float cos_4alpha = sqr(cos_2alpha) - sqr(sin_2alpha); - angles[0] = sin_theta_i * cos_2alpha + cos_theta_i * sin_2alpha; - angles[1] = fabsf(cos_theta_i * cos_2alpha - sin_theta_i * sin_2alpha); - angles[2] = sin_theta_i * cos_1alpha - cos_theta_i * sin_1alpha; - angles[3] = fabsf(cos_theta_i * cos_1alpha + sin_theta_i * sin_1alpha); - angles[4] = sin_theta_i * cos_4alpha - cos_theta_i * sin_4alpha; - angles[5] = fabsf(cos_theta_i * cos_4alpha + sin_theta_i * sin_4alpha); + angles[0] = sin_theta_o * cos_2alpha - cos_theta_o * sin_2alpha; + angles[1] = fabsf(cos_theta_o * cos_2alpha + sin_theta_o * sin_2alpha); + angles[2] = sin_theta_o * cos_1alpha + cos_theta_o * sin_1alpha; + angles[3] = fabsf(cos_theta_o * cos_1alpha - sin_theta_o * sin_1alpha); + angles[4] = sin_theta_o * cos_4alpha + cos_theta_o * sin_4alpha; + angles[5] = fabsf(cos_theta_o * cos_4alpha - sin_theta_o * sin_4alpha); } /* Evaluation function for our shader. */ @@ -293,17 +295,17 @@ ccl_device Spectrum bsdf_hair_chiang_eval(KernelGlobals kg, const float phi = phi_i - phi_o; float angles[6]; - hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles); + hair_alpha_angles(sin_theta_o, cos_theta_o, bsdf->alpha, angles); Spectrum F = zero_spectrum(); float F_energy = 0.0f; /* Primary specular (R), Transmission (TT) and Secondary Specular (TRT). */ for (int i = 0; i < 3; i++) { - const float Mp = longitudinal_scattering(angles[2 * i], + const float Mp = longitudinal_scattering(sin_theta_i, + cos_theta_i, + angles[2 * i], angles[2 * i + 1], - sin_theta_o, - cos_theta_o, (i == 0) ? bsdf->m0_roughness : (i == 1) ? 0.25f * bsdf->v : 4.0f * bsdf->v); @@ -347,6 +349,7 @@ ccl_device int bsdf_hair_chiang_sample(KernelGlobals kg, kernel_assert(fabsf(dot(X, Y)) < 1e-3f); const float3 Z = safe_normalize(cross(X, Y)); + /* wo in pbrt. */ const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z)); const float sin_theta_o = local_O.x; @@ -387,19 +390,20 @@ ccl_device int bsdf_hair_chiang_sample(KernelGlobals kg, v *= 4.0f; } + float angles[6]; + hair_alpha_angles(sin_theta_o, cos_theta_o, bsdf->alpha, angles); + float sin_theta_o_tilted = sin_theta_o; + float cos_theta_o_tilted = cos_theta_o; + if (p < 3) { + sin_theta_o_tilted = angles[2 * p]; + cos_theta_o_tilted = angles[2 * p + 1]; + } rand.z = max(rand.z, 1e-5f); const float fac = 1.0f + v * logf(rand.z + (1.0f - rand.z) * expf(-2.0f / v)); - float sin_theta_i = -fac * sin_theta_o + - cos_from_sin(fac) * cosf(M_2PI_F * rand.y) * cos_theta_o; + float sin_theta_i = -fac * sin_theta_o_tilted + + sin_from_cos(fac) * cosf(M_2PI_F * rand.y) * cos_theta_o_tilted; float cos_theta_i = cos_from_sin(sin_theta_i); - float angles[6]; - if (p < 3) { - hair_alpha_angles(sin_theta_i, cos_theta_i, -bsdf->alpha, angles); - sin_theta_i = angles[2 * p]; - cos_theta_i = angles[2 * p + 1]; - } - float phi; if (p < 3) { phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(rand.x, bsdf->s); @@ -409,17 +413,15 @@ ccl_device int bsdf_hair_chiang_sample(KernelGlobals kg, } const float phi_i = phi_o + phi; - hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles); - Spectrum F = zero_spectrum(); float F_energy = 0.0f; /* Primary specular (R), Transmission (TT) and Secondary Specular (TRT). */ for (int i = 0; i < 3; i++) { - const float Mp = longitudinal_scattering(angles[2 * i], + const float Mp = longitudinal_scattering(sin_theta_i, + cos_theta_i, + angles[2 * i], angles[2 * i + 1], - sin_theta_o, - cos_theta_o, (i == 0) ? bsdf->m0_roughness : (i == 1) ? 0.25f * bsdf->v : 4.0f * bsdf->v); diff --git a/tests/data b/tests/data index 9c778e46424..753727081d7 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit 9c778e4642436b603d51923213483cccef1d08a1 +Subproject commit 753727081d73e1469f45fb9b36ad081c12cfcfab