Blender  V2.93
bsdf_hair_principled.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifdef __KERNEL_CPU__
18 # include <fenv.h>
19 #endif
20 
21 #include "kernel/kernel_color.h"
22 
23 #ifndef __BSDF_HAIR_PRINCIPLED_H__
24 # define __BSDF_HAIR_PRINCIPLED_H__
25 
27 
29  /* Geometry data. */
30  float4 geom;
32 
35 
36  /* Absorption coefficient. */
38  /* Variance of the underlying logistic distribution. */
39  float v;
40  /* Scale factor of the underlying logistic distribution. */
41  float s;
42  /* Cuticle tilt angle. */
43  float alpha;
44  /* IOR. */
45  float eta;
46  /* Effective variance for the diffuse bounce only. */
47  float m0_roughness;
48 
49  /* Extra closure. */
52 
53 static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairBSDF),
54  "PrincipledHairBSDF is too large!");
55 static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairExtra),
56  "PrincipledHairExtra is too large!");
57 
58 ccl_device_inline float cos_from_sin(const float s)
59 {
60  return safe_sqrtf(1.0f - s * s);
61 }
62 
63 /* Gives the change in direction in the normal plane for the given angles and p-th-order
64  * scattering. */
65 ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
66 {
67  return 2.0f * p * gamma_t - 2.0f * gamma_o + p * M_PI_F;
68 }
69 
70 /* Remaps the given angle to [-pi, pi]. */
72 {
73  while (a > M_PI_F) {
74  a -= M_2PI_F;
75  }
76  while (a < -M_PI_F) {
77  a += M_2PI_F;
78  }
79  return a;
80 }
81 
82 /* Logistic distribution function. */
83 ccl_device_inline float logistic(float x, float s)
84 {
85  float v = expf(-fabsf(x) / s);
86  return v / (s * sqr(1.0f + v));
87 }
88 
89 /* Logistic cumulative density function. */
90 ccl_device_inline float logistic_cdf(float x, float s)
91 {
92  float arg = -x / s;
93  /* expf() overflows if arg >= 89.0. */
94  if (arg > 88.0f) {
95  return 0.0f;
96  }
97  else {
98  return 1.0f / (1.0f + expf(arg));
99  }
100 }
101 
102 /* Numerical approximation to the Bessel function of the first kind. */
104 {
105  x = sqr(x);
106  float val = 1.0f + 0.25f * x;
107  float pow_x_2i = sqr(x);
108  uint64_t i_fac_2 = 1;
109  int pow_4_i = 16;
110  for (int i = 2; i < 10; i++) {
111  i_fac_2 *= i * i;
112  float newval = val + pow_x_2i / (pow_4_i * i_fac_2);
113  if (val == newval) {
114  return val;
115  }
116  val = newval;
117  pow_x_2i *= x;
118  pow_4_i *= 4;
119  }
120  return val;
121 }
122 
123 /* Logarithm of the Bessel function of the first kind. */
125 {
126  if (x > 12.0f) {
127  /* log(1/x) == -log(x) if x > 0.
128  * This is only used with positive cosines. */
129  return x + 0.5f * (1.f / (8.0f * x) - M_LN_2PI_F - logf(x));
130  }
131  else {
132  return logf(bessel_I0(x));
133  }
134 }
135 
136 /* Logistic distribution limited to the interval [-pi, pi]. */
137 ccl_device_inline float trimmed_logistic(float x, float s)
138 {
139  /* The logistic distribution is symmetric and centered around zero,
140  * so logistic_cdf(x, s) = 1 - logistic_cdf(-x, s).
141  * Therefore, logistic_cdf(x, s)-logistic_cdf(-x, s) = 1 - 2*logistic_cdf(-x, s) */
142  float scaling_fac = 1.0f - 2.0f * logistic_cdf(-M_PI_F, s);
143  float val = logistic(x, s);
144  return safe_divide(val, scaling_fac);
145 }
146 
147 /* Sampling function for the trimmed logistic function. */
149 {
150  float cdf_minuspi = logistic_cdf(-M_PI_F, s);
151  float x = -s * logf(1.0f / (u * (1.0f - 2.0f * cdf_minuspi) + cdf_minuspi) - 1.0f);
152  return clamp(x, -M_PI_F, M_PI_F);
153 }
154 
155 /* Azimuthal scattering function Np. */
157  float phi, int p, float s, float gamma_o, float gamma_t)
158 {
159  float phi_o = wrap_angle(phi - delta_phi(p, gamma_o, gamma_t));
160  float val = trimmed_logistic(phi_o, s);
161  return val;
162 }
163 
164 /* Longitudinal scattering function Mp. */
166  float sin_theta_i, float cos_theta_i, float sin_theta_o, float cos_theta_o, float v)
167 {
168  float inv_v = 1.0f / v;
169  float cos_arg = cos_theta_i * cos_theta_o * inv_v;
170  float sin_arg = sin_theta_i * sin_theta_o * inv_v;
171  if (v <= 0.1f) {
172  float i0 = log_bessel_I0(cos_arg);
173  float val = expf(i0 - sin_arg - inv_v + 0.6931f + logf(0.5f * inv_v));
174  return val;
175  }
176  else {
177  float i0 = bessel_I0(cos_arg);
178  float val = (expf(-sin_arg) * i0) / (sinhf(inv_v) * 2.0f * v);
179  return val;
180  }
181 }
182 
183 /* Combine the three values using their luminances. */
185 {
186  return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c));
187 }
188 
189 # ifdef __HAIR__
190 /* Set up the hair closure. */
191 ccl_device int bsdf_principled_hair_setup(ShaderData *sd, PrincipledHairBSDF *bsdf)
192 {
193  bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
194  bsdf->v = clamp(bsdf->v, 0.001f, 1.0f);
195  bsdf->s = clamp(bsdf->s, 0.001f, 1.0f);
196  /* Apply Primary Reflection Roughness modifier. */
197  bsdf->m0_roughness = clamp(bsdf->m0_roughness * bsdf->v, 0.001f, 1.0f);
198 
199  /* Map from roughness_u and roughness_v to variance and scale factor. */
200  bsdf->v = sqr(0.726f * bsdf->v + 0.812f * sqr(bsdf->v) + 3.700f * pow20(bsdf->v));
201  bsdf->s = (0.265f * bsdf->s + 1.194f * sqr(bsdf->s) + 5.372f * pow22(bsdf->s)) * M_SQRT_PI_8_F;
202  bsdf->m0_roughness = sqr(0.726f * bsdf->m0_roughness + 0.812f * sqr(bsdf->m0_roughness) +
203  3.700f * pow20(bsdf->m0_roughness));
204 
205  /* Compute local frame, aligned to curve tangent and ray direction. */
206  float3 X = safe_normalize(sd->dPdu);
207  float3 Y = safe_normalize(cross(X, sd->I));
209 
210  /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at
211  * the center, to grazing the other edge. This is the sine of the angle
212  * between sd->Ng and Z, as seen from the tangent X. */
213 
214  /* TODO: we convert this value to a cosine later and discard the sign, so
215  * we could probably save some operations. */
216  float h = (sd->type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) ?
217  -sd->v :
218  dot(cross(sd->Ng, X), Z);
219 
220  kernel_assert(fabsf(h) < 1.0f + 1e-4f);
223 
224  bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
225 
227 }
228 
229 # endif /* __HAIR__ */
230 
231 /* Given the Fresnel term and transmittance, generate the attenuation terms for each bounce. */
232 ccl_device_inline void hair_attenuation(KernelGlobals *kg, float f, float3 T, float4 *Ap)
233 {
234  /* Primary specular (R). */
235  Ap[0] = make_float4(f, f, f, f);
236 
237  /* Transmission (TT). */
238  float3 col = sqr(1.0f - f) * T;
239  Ap[1] = combine_with_energy(kg, col);
240 
241  /* Secondary specular (TRT). */
242  col *= T * f;
243  Ap[2] = combine_with_energy(kg, col);
244 
245  /* Residual component (TRRT+). */
246  col *= safe_divide_color(T * f, make_float3(1.0f, 1.0f, 1.0f) - T * f);
247  Ap[3] = combine_with_energy(kg, col);
248 
249  /* Normalize sampling weights. */
250  float totweight = Ap[0].w + Ap[1].w + Ap[2].w + Ap[3].w;
251  float fac = safe_divide(1.0f, totweight);
252 
253  Ap[0].w *= fac;
254  Ap[1].w *= fac;
255  Ap[2].w *= fac;
256  Ap[3].w *= fac;
257 }
258 
259 /* Given the tilt angle, generate the rotated theta_i for the different bounces. */
260 ccl_device_inline void hair_alpha_angles(float sin_theta_i,
261  float cos_theta_i,
262  float alpha,
263  float *angles)
264 {
265  float sin_1alpha = sinf(alpha);
266  float cos_1alpha = cos_from_sin(sin_1alpha);
267  float sin_2alpha = 2.0f * sin_1alpha * cos_1alpha;
268  float cos_2alpha = sqr(cos_1alpha) - sqr(sin_1alpha);
269  float sin_4alpha = 2.0f * sin_2alpha * cos_2alpha;
270  float cos_4alpha = sqr(cos_2alpha) - sqr(sin_2alpha);
271 
272  angles[0] = sin_theta_i * cos_2alpha + cos_theta_i * sin_2alpha;
273  angles[1] = fabsf(cos_theta_i * cos_2alpha - sin_theta_i * sin_2alpha);
274  angles[2] = sin_theta_i * cos_1alpha - cos_theta_i * sin_1alpha;
275  angles[3] = fabsf(cos_theta_i * cos_1alpha + sin_theta_i * sin_1alpha);
276  angles[4] = sin_theta_i * cos_4alpha - cos_theta_i * sin_4alpha;
277  angles[5] = fabsf(cos_theta_i * cos_4alpha + sin_theta_i * sin_4alpha);
278 }
279 
280 /* Evaluation function for our shader. */
282  const ShaderData *sd,
283  const ShaderClosure *sc,
284  const float3 omega_in,
285  float *pdf)
286 {
287  kernel_assert(isfinite3_safe(sd->P) && isfinite_safe(sd->ray_length));
288 
289  const PrincipledHairBSDF *bsdf = (const PrincipledHairBSDF *)sc;
290  float3 Y = float4_to_float3(bsdf->extra->geom);
291 
292  float3 X = safe_normalize(sd->dPdu);
293  kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
295 
296  float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
297  float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
298 
299  float sin_theta_o = wo.x;
300  float cos_theta_o = cos_from_sin(sin_theta_o);
301  float phi_o = atan2f(wo.z, wo.y);
302 
303  float sin_theta_t = sin_theta_o / bsdf->eta;
304  float cos_theta_t = cos_from_sin(sin_theta_t);
305 
306  float sin_gamma_o = bsdf->extra->geom.w;
307  float cos_gamma_o = cos_from_sin(sin_gamma_o);
308  float gamma_o = safe_asinf(sin_gamma_o);
309 
310  float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
311  float cos_gamma_t = cos_from_sin(sin_gamma_t);
312  float gamma_t = safe_asinf(sin_gamma_t);
313 
314  float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
315  float4 Ap[4];
316  hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
317 
318  float sin_theta_i = wi.x;
319  float cos_theta_i = cos_from_sin(sin_theta_i);
320  float phi_i = atan2f(wi.z, wi.y);
321 
322  float phi = phi_i - phi_o;
323 
324  float angles[6];
325  hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
326 
327  float4 F;
328  float Mp, Np;
329 
330  /* Primary specular (R). */
331  Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
332  Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
333  F = Ap[0] * Mp * Np;
335 
336  /* Transmission (TT). */
337  Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
338  Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
339  F += Ap[1] * Mp * Np;
341 
342  /* Secondary specular (TRT). */
343  Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
344  Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
345  F += Ap[2] * Mp * Np;
347 
348  /* Residual component (TRRT+). */
349  Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
350  Np = M_1_2PI_F;
351  F += Ap[3] * Mp * Np;
353 
354  *pdf = F.w;
355  return float4_to_float3(F);
356 }
357 
358 /* Sampling function for the hair shader. */
360  const ShaderClosure *sc,
361  ShaderData *sd,
362  float randu,
363  float randv,
364  float3 *eval,
365  float3 *omega_in,
366  float3 *domega_in_dx,
367  float3 *domega_in_dy,
368  float *pdf)
369 {
371 
372  float3 Y = float4_to_float3(bsdf->extra->geom);
373 
374  float3 X = safe_normalize(sd->dPdu);
375  kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
377 
378  float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
379 
380  float2 u[2];
381  u[0] = make_float2(randu, randv);
382  u[1].x = lcg_step_float_addrspace(&sd->lcg_state);
383  u[1].y = lcg_step_float_addrspace(&sd->lcg_state);
384 
385  float sin_theta_o = wo.x;
386  float cos_theta_o = cos_from_sin(sin_theta_o);
387  float phi_o = atan2f(wo.z, wo.y);
388 
389  float sin_theta_t = sin_theta_o / bsdf->eta;
390  float cos_theta_t = cos_from_sin(sin_theta_t);
391 
392  float sin_gamma_o = bsdf->extra->geom.w;
393  float cos_gamma_o = cos_from_sin(sin_gamma_o);
394  float gamma_o = safe_asinf(sin_gamma_o);
395 
396  float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
397  float cos_gamma_t = cos_from_sin(sin_gamma_t);
398  float gamma_t = safe_asinf(sin_gamma_t);
399 
400  float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
401  float4 Ap[4];
402  hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
403 
404  int p = 0;
405  for (; p < 3; p++) {
406  if (u[0].x < Ap[p].w) {
407  break;
408  }
409  u[0].x -= Ap[p].w;
410  }
411 
412  float v = bsdf->v;
413  if (p == 1) {
414  v *= 0.25f;
415  }
416  if (p >= 2) {
417  v *= 4.0f;
418  }
419 
420  u[1].x = max(u[1].x, 1e-5f);
421  float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
422  float sin_theta_i = -fac * sin_theta_o +
423  cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o;
424  float cos_theta_i = cos_from_sin(sin_theta_i);
425 
426  float angles[6];
427  if (p < 3) {
428  hair_alpha_angles(sin_theta_i, cos_theta_i, -bsdf->alpha, angles);
429  sin_theta_i = angles[2 * p];
430  cos_theta_i = angles[2 * p + 1];
431  }
432 
433  float phi;
434  if (p < 3) {
435  phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(u[0].y, bsdf->s);
436  }
437  else {
438  phi = M_2PI_F * u[0].y;
439  }
440  float phi_i = phi_o + phi;
441 
442  hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
443 
444  float4 F;
445  float Mp, Np;
446 
447  /* Primary specular (R). */
448  Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
449  Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
450  F = Ap[0] * Mp * Np;
452 
453  /* Transmission (TT). */
454  Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
455  Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
456  F += Ap[1] * Mp * Np;
458 
459  /* Secondary specular (TRT). */
460  Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
461  Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
462  F += Ap[2] * Mp * Np;
464 
465  /* Residual component (TRRT+). */
466  Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
467  Np = M_1_2PI_F;
468  F += Ap[3] * Mp * Np;
470 
471  *eval = float4_to_float3(F);
472  *pdf = F.w;
473 
474  *omega_in = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
475 
476 # ifdef __RAY_DIFFERENTIALS__
477  float3 N = safe_normalize(sd->I + *omega_in);
478  *domega_in_dx = (2 * dot(N, sd->dI.dx)) * N - sd->dI.dx;
479  *domega_in_dy = (2 * dot(N, sd->dI.dy)) * N - sd->dI.dy;
480 # endif
481 
482  return LABEL_GLOSSY | ((p == 0) ? LABEL_REFLECT : LABEL_TRANSMIT);
483 }
484 
485 /* Implements Filter Glossy by capping the effective roughness. */
487 {
489 
490  bsdf->v = fmaxf(roughness, bsdf->v);
491  bsdf->s = fmaxf(roughness, bsdf->s);
492  bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness);
493 }
494 
495 /* Hair Albedo */
496 
498  const float azimuthal_roughness)
499 {
500  const float x = azimuthal_roughness;
501  return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
502 }
503 
505 {
508 }
509 
511 bsdf_principled_hair_sigma_from_reflectance(const float3 color, const float azimuthal_roughness)
512 {
513  const float3 sigma = log3(color) /
514  bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness);
515  return sigma * sigma;
516 }
517 
519  const float pheomelanin)
520 {
521  return eumelanin * make_float3(0.506f, 0.841f, 1.653f) +
522  pheomelanin * make_float3(0.343f, 0.733f, 1.924f);
523 }
524 
526 
527 #endif /* __BSDF_HAIR_PRINCIPLED_H__ */
sqrt(x)+1/max(0
MINLINE float safe_sqrtf(float a)
MINLINE float safe_divide(float a, float b)
MINLINE float safe_asinf(float a)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
#define X
Definition: GeomUtils.cpp:213
#define Z
Definition: GeomUtils.cpp:215
#define Y
Definition: GeomUtils.cpp:214
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float logistic_cdf(float x, float s)
CCL_NAMESPACE_BEGIN typedef ccl_addr_space struct PrincipledHairExtra PrincipledHairExtra
ccl_device int bsdf_principled_hair_sample(KernelGlobals *kg, const ShaderClosure *sc, ShaderData *sd, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
ccl_device_inline float4 combine_with_energy(KernelGlobals *kg, float3 c)
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 void bsdf_principled_hair_blur(ShaderClosure *sc, float roughness)
ccl_device_inline float log_bessel_I0(float x)
ccl_device float3 bsdf_principled_hair_albedo(ShaderClosure *sc)
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 float3 bsdf_principled_hair_sigma_from_concentration(const float eumelanin, const float pheomelanin)
ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(const float azimuthal_roughness)
ccl_device_inline float sample_trimmed_logistic(float u, float s)
ccl_addr_space struct PrincipledHairBSDF PrincipledHairBSDF
ccl_device_inline void hair_alpha_angles(float sin_theta_i, float cos_theta_i, float alpha, float *angles)
ccl_device_inline float wrap_angle(float a)
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 float3 bsdf_principled_hair_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
ccl_device_inline void hair_attenuation(KernelGlobals *kg, float f, float3 T, float4 *Ap)
ccl_device_inline float3 bsdf_principled_hair_sigma_from_reflectance(const float3 color, const float azimuthal_roughness)
ccl_device_inline float cos_from_sin(const float s)
ccl_device float fresnel_dielectric_cos(float cosi, float eta)
Definition: bsdf_util.h:104
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static CCL_NAMESPACE_BEGIN const double alpha
uint col
ccl_device float linear_rgb_to_gray(KernelGlobals *kg, float3 c)
Definition: kernel_color.h:31
#define kernel_assert(cond)
#define ccl_addr_space
#define logf(x)
#define sinf(x)
#define cosf(x)
#define ccl_device
#define expf(x)
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define atan2f(x, y)
#define fmaxf(x, y)
#define make_float2(x, y)
#define make_float4(x, y, z, w)
#define sinhf(x)
#define fabsf(x)
#define sqrtf(x)
#define make_float3(x, y, z)
ccl_device float lcg_step_float_addrspace(ccl_addr_space uint *rng)
@ SD_BSDF_HAS_EVAL
Definition: kernel_types.h:849
@ SD_BSDF_NEEDS_LCG
Definition: kernel_types.h:861
@ SD_BSDF
Definition: kernel_types.h:847
@ PRIMITIVE_MOTION_CURVE_RIBBON
Definition: kernel_types.h:691
@ PRIMITIVE_CURVE_RIBBON
Definition: kernel_types.h:690
ShaderData
@ LABEL_TRANSMIT
Definition: kernel_types.h:328
@ LABEL_GLOSSY
Definition: kernel_types.h:331
@ LABEL_REFLECT
Definition: kernel_types.h:329
ShaderClosure
Definition: kernel_types.h:831
#define T
#define F
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
params N
unsigned __int64 uint64_t
Definition: stdint.h:93
PrincipledHairExtra * extra
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
@ CLOSURE_BSDF_HAIR_PRINCIPLED_ID
Definition: svm_types.h:565
float max
__forceinline avxf cross(const avxf &a, const avxf &b)
Definition: util_avxf.h:119
#define M_SQRT_PI_8_F
Definition: util_math.h:61
ccl_device_inline float pow22(float a)
Definition: util_math.h:661
ccl_device_inline float pow20(float a)
Definition: util_math.h:656
ccl_device_inline float sqr(float a)
Definition: util_math.h:651
#define M_2PI_F
Definition: util_math.h:69
#define M_LN_2PI_F
Definition: util_math.h:64
ccl_device_inline float3 safe_divide_color(float3 a, float3 b)
Definition: util_math.h:514
ccl_device_inline bool isfinite_safe(float f)
Definition: util_math.h:270
#define M_1_2PI_F
Definition: util_math.h:58
#define M_PI_F
Definition: util_math.h:43
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition: util_math.h:415
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float2 safe_normalize(const float2 &a)
ccl_device_inline float3 exp3(float3 v)
ccl_device_inline float3 log3(float3 v)
ccl_device_inline bool isfinite3_safe(float3 v)