25static_assert(
sizeof(ShaderClosure) >=
sizeof(
HairBsdf),
"HairBsdf is too large!");
30 bsdf->roughness1 =
clamp(bsdf->roughness1, 0.001f, 1.0f);
31 bsdf->roughness2 =
clamp(bsdf->roughness2, 0.001f, 1.0f);
38 bsdf->roughness1 =
clamp(bsdf->roughness1, 0.001f, 1.0f);
39 bsdf->roughness2 =
clamp(bsdf->roughness2, 0.001f, 1.0f);
49 if (
dot(bsdf->N, wo) < 0.0f) {
54 const float offset = bsdf->
offset;
56 const float roughness1 = bsdf->roughness1;
57 const float roughness2 = bsdf->roughness2;
59 const float Iz =
dot(Tg, wi);
64 const float wo_z =
dot(Tg, wo);
68 const float cosphi_i =
dot(wo_y, locy);
75 const float roughness1_inv = 1.0f / roughness1;
76 const float roughness2_inv = 1.0f / roughness2;
77 float phi_i =
fast_acosf(cosphi_i) * roughness2_inv;
79 const float costheta_i =
fast_cosf(theta_i);
81 const float a_R =
fast_atan2f(((
M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
82 const float b_R =
fast_atan2f(((-
M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
84 const float theta_h = (theta_i + theta_r) * 0.5f;
85 const float t = theta_h - offset;
87 const float phi_pdf =
fast_cosf(phi_i * 0.5f) * 0.25f * roughness2_inv;
88 const float theta_pdf = roughness1 /
89 (2 * (t * t + roughness1 * roughness1) * (a_R - b_R) * costheta_i);
90 *pdf = phi_pdf * theta_pdf;
101 if (
dot(bsdf->N, wo) >= 0.0f) {
106 const float offset = bsdf->
offset;
107 const float3 Tg = bsdf->T;
108 const float roughness1 = bsdf->roughness1;
109 const float roughness2 = bsdf->roughness2;
110 const float Iz =
dot(Tg, wi);
115 const float wo_z =
dot(Tg, wo);
126 const float costheta_i =
fast_cosf(theta_i);
128 const float roughness1_inv = 1.0f / roughness1;
129 const float a_TT =
fast_atan2f(((
M_PI_2_F + theta_r) / 2 - offset) * roughness1_inv, 1.0f);
130 const float b_TT =
fast_atan2f(((-
M_PI_2_F + theta_r) / 2 - offset) * roughness1_inv, 1.0f);
133 const float theta_h = (theta_i + theta_r) / 2;
134 const float t = theta_h - offset;
135 const float phi =
fabsf(phi_i);
137 const float p =
M_PI_F - phi;
138 const float theta_pdf = roughness1 /
139 (2 * (t * t + roughness1 * roughness1) * (a_TT - b_TT) * costheta_i);
140 const float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
142 *pdf = phi_pdf * theta_pdf;
156 const float offset = bsdf->
offset;
157 const float3 Tg = bsdf->T;
158 const float roughness1 = bsdf->roughness1;
159 const float roughness2 = bsdf->roughness2;
160 *sampled_roughness =
make_float2(roughness1, roughness2);
161 const float Iz =
dot(Tg, wi);
166 const float roughness1_inv = 1.0f / roughness1;
167 const float a_R =
fast_atan2f(((
M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
168 const float b_R =
fast_atan2f(((-
M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
170 const float t = roughness1 *
tanf(rand.
x * (a_R - b_R) + b_R);
172 const float theta_h = t + offset;
173 const float theta_i = 2 * theta_h - theta_r;
179 const float phi = 2 *
safe_asinf(1 - 2 * rand.
y) * roughness2;
181 const float phi_pdf =
fast_cosf(phi * 0.5f) * 0.25f / roughness2;
183 const float theta_pdf = roughness1 /
184 (2 * (t * t + roughness1 * roughness1) * (a_R - b_R) * costheta_i);
189 *wo = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg;
191 *pdf =
fabsf(phi_pdf * theta_pdf);
211 const float offset = bsdf->
offset;
212 const float3 Tg = bsdf->T;
213 const float roughness1 = bsdf->roughness1;
214 const float roughness2 = bsdf->roughness2;
215 *sampled_roughness =
make_float2(roughness1, roughness2);
216 const float Iz =
dot(Tg, wi);
221 const float roughness1_inv = 1.0f / roughness1;
222 const float a_TT =
fast_atan2f(((
M_PI_2_F + theta_r) / 2 - offset) * roughness1_inv, 1.0f);
223 const float b_TT =
fast_atan2f(((-
M_PI_2_F + theta_r) / 2 - offset) * roughness1_inv, 1.0f);
226 const float t = roughness1 *
tanf(rand.
x * (a_TT - b_TT) + b_TT);
228 const float theta_h = t + offset;
229 const float theta_i = 2 * theta_h - theta_r;
235 const float p = roughness2 *
tanf(c_TT * (rand.
y - 0.5f));
236 const float phi = p +
M_PI_F;
237 const float theta_pdf = roughness1 /
238 (2 * (t * t + roughness1 * roughness1) * (a_TT - b_TT) * costheta_i);
239 const float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
244 *wo = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg;
246 *pdf =
fabsf(phi_pdf * theta_pdf);
MINLINE float safe_asinf(float a)
ccl_device Spectrum bsdf_hair_reflection_eval(const ccl_private ShaderClosure *sc, const float3 wi, const float3 wo, ccl_private float *pdf)
ccl_device int bsdf_hair_reflection_setup(ccl_private HairBsdf *bsdf)
ccl_device int bsdf_hair_reflection_sample(const ccl_private ShaderClosure *sc, const float3, const float3 wi, const float2 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness)
ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
ccl_device Spectrum bsdf_hair_transmission_eval(const ccl_private ShaderClosure *sc, const float3 wi, const float3 wo, ccl_private float *pdf)
ccl_device int bsdf_hair_transmission_sample(const ccl_private ShaderClosure *sc, const float3, const float3 wi, const float2 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define kernel_assert(cond)
#define CCL_NAMESPACE_END
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
constexpr T clamp(T, U, U) RET
@ CLOSURE_BSDF_HAIR_TRANSMISSION_ID
@ CLOSURE_BSDF_HAIR_REFLECTION_ID
@ SD_BSDF_HAS_TRANSMISSION
ccl_device float fast_atan2f(const float y, const float x)
ccl_device float fast_acosf(const float x)
ccl_device void fast_sincosf(float x, ccl_private float *sine, ccl_private float *cosine)
ccl_device float fast_cosf(float x)