44 return 2.0f * p * gamma_t - 2.0f * gamma_o + p *
M_PI_F;
57 return v / (s *
sqr(1.0f +
v));
69 return 1.0f / (1.0f +
expf(arg));
77 float val = 1.0f + 0.25f *
x;
78 float pow_x_2i =
sqr(x);
81 for (
int i = 2; i < 10; i++) {
83 float newval = val + pow_x_2i / (pow_4_i * i_fac_2);
100 return x + 0.5f * (1.f / (8.0f *
x) - M_LN_2PI_F -
logf(x));
122 float x = -s *
logf(1.0f / (u * (1.0f - 2.0f * cdf_minuspi) + cdf_minuspi) - 1.0f);
128 float phi,
int p,
float s,
float gamma_o,
float gamma_t)
137 float sin_theta_i,
float cos_theta_i,
float sin_theta_o,
float cos_theta_o,
float v)
139 float inv_v = 1.0f /
v;
140 float cos_arg = cos_theta_i * cos_theta_o * inv_v;
141 float sin_arg = sin_theta_i * sin_theta_o * inv_v;
144 float val =
expf(i0 - sin_arg - inv_v + 0.6931f +
logf(0.5f * inv_v));
150 float val = (
expf(-sin_arg) * i0) / (
sinhf(inv_v) * 2.0f *
v);
161 bsdf->v =
clamp(bsdf->v, 0.001f, 1.0f);
162 bsdf->s =
clamp(bsdf->s, 0.001f, 1.0f);
164 bsdf->m0_roughness =
clamp(bsdf->m0_roughness * bsdf->v, 0.001f, 1.0f);
167 bsdf->v =
sqr(0.726f * bsdf->v + 0.812f *
sqr(bsdf->v) + 3.700f *
pow20(bsdf->v));
168 bsdf->s = (0.265f * bsdf->s + 1.194f *
sqr(bsdf->s) + 5.372f *
pow22(bsdf->s)) * M_SQRT_PI_8_F;
169 bsdf->m0_roughness =
sqr(0.726f * bsdf->m0_roughness + 0.812f *
sqr(bsdf->m0_roughness) +
170 3.700f *
pow20(bsdf->m0_roughness));
190 bsdf->alpha = -bsdf->alpha;
220 float totweight = Ap_energy[0] + Ap_energy[1] + Ap_energy[2] + Ap_energy[3];
235 float sin_1alpha =
sinf(alpha);
237 float sin_2alpha = 2.0f * sin_1alpha * cos_1alpha;
238 float cos_2alpha =
sqr(cos_1alpha) -
sqr(sin_1alpha);
239 float sin_4alpha = 2.0f * sin_2alpha * cos_2alpha;
240 float cos_4alpha =
sqr(cos_2alpha) -
sqr(sin_2alpha);
242 angles[0] = sin_theta_o * cos_2alpha - cos_theta_o * sin_2alpha;
243 angles[1] =
fabsf(cos_theta_o * cos_2alpha + sin_theta_o * sin_2alpha);
244 angles[2] = sin_theta_o * cos_1alpha + cos_theta_o * sin_1alpha;
245 angles[3] =
fabsf(cos_theta_o * cos_1alpha - sin_theta_o * sin_1alpha);
246 angles[4] = sin_theta_o * cos_4alpha + cos_theta_o * sin_4alpha;
247 angles[5] =
fabsf(cos_theta_o * cos_4alpha - sin_theta_o * sin_4alpha);
270 const float sin_theta_o = local_O.
x;
272 const float phi_o =
atan2f(local_O.
z, local_O.
y);
274 const float sin_theta_t = sin_theta_o / bsdf->eta;
277 const float sin_gamma_o = bsdf->h;
279 const float gamma_o =
safe_asinf(sin_gamma_o);
281 const float sin_gamma_t = sin_gamma_o * cos_theta_o /
sqrtf(
sqr(bsdf->eta) -
sqr(sin_theta_o));
283 const float gamma_t =
safe_asinf(sin_gamma_t);
285 const Spectrum T =
exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
291 const float sin_theta_i = local_I.
x;
293 const float phi_i =
atan2f(local_I.
z, local_I.
y);
295 const float phi = phi_i - phi_o;
301 float F_energy = 0.0f;
304 for (
int i = 0; i < 3; i++) {
309 (i == 0) ? bsdf->m0_roughness :
310 (i == 1) ? 0.25f * bsdf->v :
313 F += Ap[i] * Mp * Np;
314 F_energy += Ap_energy[i] * Mp * Np;
321 sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
322 const float Np = M_1_2PI_F;
323 F += Ap[3] * Mp * Np;
324 F_energy += Ap_energy[3] * Mp * Np;
344 *sampled_roughness =
make_float2(bsdf->m0_roughness, bsdf->m0_roughness);
355 const float sin_theta_o = local_O.
x;
357 const float phi_o =
atan2f(local_O.
z, local_O.
y);
359 const float sin_theta_t = sin_theta_o / bsdf->eta;
362 const float sin_gamma_o = bsdf->h;
364 const float gamma_o =
safe_asinf(sin_gamma_o);
366 const float sin_gamma_t = sin_gamma_o * cos_theta_o /
sqrtf(
sqr(bsdf->eta) -
sqr(sin_theta_o));
368 const float gamma_t =
safe_asinf(sin_gamma_t);
370 const Spectrum T =
exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
378 if (rand.
z < Ap_energy[p]) {
381 rand.
z -= Ap_energy[p];
383 rand.
z /= Ap_energy[p];
395 float sin_theta_o_tilted = sin_theta_o;
396 float cos_theta_o_tilted = cos_theta_o;
398 sin_theta_o_tilted = angles[2 * p];
399 cos_theta_o_tilted = angles[2 * p + 1];
401 rand.
z =
max(rand.
z, 1e-5f);
402 const float fac = 1.0f +
v *
logf(rand.
z + (1.0f - rand.
z) *
expf(-2.0f /
v));
403 float sin_theta_i = -fac * sin_theta_o_tilted +
414 const float phi_i = phi_o + phi;
417 float F_energy = 0.0f;
420 for (
int i = 0; i < 3; i++) {
425 (i == 0) ? bsdf->m0_roughness :
426 (i == 1) ? 0.25f * bsdf->v :
429 F += Ap[i] * Mp * Np;
430 F_energy += Ap_energy[i] * Mp * Np;
437 sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
438 const float Np = M_1_2PI_F;
439 F += Ap[3] * Mp * Np;
440 F_energy += Ap_energy[3] * Mp * Np;
447 *wo =
X * sin_theta_i +
Y * cos_theta_i *
cosf(phi_i) + Z * cos_theta_i *
sinf(phi_i);
457 bsdf->
v =
fmaxf(roughness, bsdf->v);
458 bsdf->s =
fmaxf(roughness, bsdf->s);
459 bsdf->m0_roughness =
fmaxf(roughness, bsdf->m0_roughness);
MINLINE float safe_divide(float a, float b)
MINLINE float safe_asinf(float a)
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float logistic_cdf(float x, float s)
ccl_device_inline float logistic(float x, float s)
ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
ccl_device_inline float log_bessel_I0(float x)
ccl_device void bsdf_hair_chiang_blur(ccl_private ShaderClosure *sc, float roughness)
ccl_device_inline float longitudinal_scattering(float sin_theta_i, float cos_theta_i, float sin_theta_o, float cos_theta_o, float v)
ccl_device_inline float sample_trimmed_logistic(float u, float s)
ccl_device Spectrum bsdf_hair_chiang_albedo(ccl_private const ShaderData *sd, ccl_private const ShaderClosure *sc)
ccl_device Spectrum bsdf_hair_chiang_eval(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private const ShaderClosure *sc, const float3 wo, ccl_private float *pdf)
ccl_device_inline void hair_attenuation(KernelGlobals kg, float f, Spectrum T, ccl_private Spectrum *Ap, ccl_private float *Ap_energy)
ccl_device_inline float wrap_angle(float a)
ccl_device_inline void hair_alpha_angles(float sin_theta_o, float cos_theta_o, float alpha, ccl_private float *angles)
ccl_device_inline float azimuthal_scattering(float phi, int p, float s, float gamma_o, float gamma_t)
ccl_device_inline float bessel_I0(float x)
ccl_device_inline float trimmed_logistic(float x, float s)
ccl_device int bsdf_hair_chiang_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, ccl_private ShaderData *sd, float3 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness)
CCL_NAMESPACE_BEGIN struct ChiangHairBSDF ChiangHairBSDF
ccl_device float fresnel_dielectric_cos(float cosi, float eta)
ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(const float azimuthal_roughness)
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define kernel_assert(cond)
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
@ CLOSURE_BSDF_HAIR_CHIANG_ID
@ SD_BSDF_HAS_TRANSMISSION
ccl_device float spectrum_to_gray(KernelGlobals kg, Spectrum c)
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float cross(const float2 a, const float2 b)
ccl_device_inline float3 exp(float3 v)
unsigned __int64 uint64_t
SPECTRUM_DATA_TYPE Spectrum
ccl_device_inline float pow22(float a)
ccl_device_inline float pow20(float a)
ccl_device_inline float sqr(float a)
ccl_device_inline float sin_from_cos(const float c)
ccl_device_inline bool isfinite_safe(float f)
ccl_device_inline float cos_from_sin(const float s)
ccl_device_inline int clamp(int a, int mn, int mx)