ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / kernel / closure / bsdf_hair_principled.h
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
26 CCL_NAMESPACE_BEGIN
27
28 typedef ccl_addr_space struct PrincipledHairExtra {
29   /* Geometry data. */
30   float4 geom;
31 } PrincipledHairExtra;
32
33 typedef ccl_addr_space struct PrincipledHairBSDF {
34   SHADER_CLOSURE_BASE;
35
36   /* Absorption coefficient. */
37   float3 sigma;
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. */
50   PrincipledHairExtra *extra;
51 } PrincipledHairBSDF;
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 scattering. */
64 ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
65 {
66   return 2.0f * p * gamma_t - 2.0f * gamma_o + p * M_PI_F;
67 }
68
69 /* Remaps the given angle to [-pi, pi]. */
70 ccl_device_inline float wrap_angle(float a)
71 {
72   while (a > M_PI_F) {
73     a -= M_2PI_F;
74   }
75   while (a < -M_PI_F) {
76     a += M_2PI_F;
77   }
78   return a;
79 }
80
81 /* Logistic distribution function. */
82 ccl_device_inline float logistic(float x, float s)
83 {
84   float v = expf(-fabsf(x) / s);
85   return v / (s * sqr(1.0f + v));
86 }
87
88 /* Logistic cumulative density function. */
89 ccl_device_inline float logistic_cdf(float x, float s)
90 {
91   float arg = -x / s;
92   /* expf() overflows if arg >= 89.0. */
93   if (arg > 88.0f) {
94     return 0.0f;
95   }
96   else {
97     return 1.0f / (1.0f + expf(arg));
98   }
99 }
100
101 /* Numerical approximation to the Bessel function of the first kind. */
102 ccl_device_inline float bessel_I0(float x)
103 {
104   x = sqr(x);
105   float val = 1.0f + 0.25f * x;
106   float pow_x_2i = sqr(x);
107   uint64_t i_fac_2 = 1;
108   int pow_4_i = 16;
109   for (int i = 2; i < 10; i++) {
110     i_fac_2 *= i * i;
111     float newval = val + pow_x_2i / (pow_4_i * i_fac_2);
112     if (val == newval) {
113       return val;
114     }
115     val = newval;
116     pow_x_2i *= x;
117     pow_4_i *= 4;
118   }
119   return val;
120 }
121
122 /* Logarithm of the Bessel function of the first kind. */
123 ccl_device_inline float log_bessel_I0(float x)
124 {
125   if (x > 12.0f) {
126     /* log(1/x) == -log(x) iff x > 0.
127      * This is only used with positive cosines */
128     return x + 0.5f * (1.f / (8.0f * x) - M_LN_2PI_F - logf(x));
129   }
130   else {
131     return logf(bessel_I0(x));
132   }
133 }
134
135 /* Logistic distribution limited to the interval [-pi, pi]. */
136 ccl_device_inline float trimmed_logistic(float x, float s)
137 {
138   /* The logistic distribution is symmetric and centered around zero,
139    * so logistic_cdf(x, s) = 1 - logistic_cdf(-x, s).
140    * Therefore, logistic_cdf(x, s)-logistic_cdf(-x, s) = 1 - 2*logistic_cdf(-x, s) */
141   float scaling_fac = 1.0f - 2.0f * logistic_cdf(-M_PI_F, s);
142   float val = logistic(x, s);
143   return safe_divide(val, scaling_fac);
144 }
145
146 /* Sampling function for the trimmed logistic function. */
147 ccl_device_inline float sample_trimmed_logistic(float u, float s)
148 {
149   float cdf_minuspi = logistic_cdf(-M_PI_F, s);
150   float x = -s * logf(1.0f / (u * (1.0f - 2.0f * cdf_minuspi) + cdf_minuspi) - 1.0f);
151   return clamp(x, -M_PI_F, M_PI_F);
152 }
153
154 /* Azimuthal scattering function Np. */
155 ccl_device_inline float azimuthal_scattering(
156     float phi, int p, float s, float gamma_o, float gamma_t)
157 {
158   float phi_o = wrap_angle(phi - delta_phi(p, gamma_o, gamma_t));
159   float val = trimmed_logistic(phi_o, s);
160   return val;
161 }
162
163 /* Longitudinal scattering function Mp. */
164 ccl_device_inline float longitudinal_scattering(
165     float sin_theta_i, float cos_theta_i, float sin_theta_o, float cos_theta_o, float v)
166 {
167   float inv_v = 1.0f / v;
168   float cos_arg = cos_theta_i * cos_theta_o * inv_v;
169   float sin_arg = sin_theta_i * sin_theta_o * inv_v;
170   if (v <= 0.1f) {
171     float i0 = log_bessel_I0(cos_arg);
172     float val = expf(i0 - sin_arg - inv_v + 0.6931f + logf(0.5f * inv_v));
173     return val;
174   }
175   else {
176     float i0 = bessel_I0(cos_arg);
177     float val = (expf(-sin_arg) * i0) / (sinhf(inv_v) * 2.0f * v);
178     return val;
179   }
180 }
181
182 /* Combine the three values using their luminances. */
183 ccl_device_inline float4 combine_with_energy(KernelGlobals *kg, float3 c)
184 {
185   return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c));
186 }
187
188 #  ifdef __HAIR__
189 /* Set up the hair closure. */
190 ccl_device int bsdf_principled_hair_setup(ShaderData *sd, PrincipledHairBSDF *bsdf)
191 {
192   bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
193   bsdf->v = clamp(bsdf->v, 0.001f, 1.0f);
194   bsdf->s = clamp(bsdf->s, 0.001f, 1.0f);
195   /* Apply Primary Reflection Roughness modifier. */
196   bsdf->m0_roughness = clamp(bsdf->m0_roughness * bsdf->v, 0.001f, 1.0f);
197
198   /* Map from roughness_u and roughness_v to variance and scale factor. */
199   bsdf->v = sqr(0.726f * bsdf->v + 0.812f * sqr(bsdf->v) + 3.700f * pow20(bsdf->v));
200   bsdf->s = (0.265f * bsdf->s + 1.194f * sqr(bsdf->s) + 5.372f * pow22(bsdf->s)) * M_SQRT_PI_8_F;
201   bsdf->m0_roughness = sqr(0.726f * bsdf->m0_roughness + 0.812f * sqr(bsdf->m0_roughness) +
202                            3.700f * pow20(bsdf->m0_roughness));
203
204   /* Compute local frame, aligned to curve tangent and ray direction. */
205   float3 X = safe_normalize(sd->dPdu);
206   float3 Y = safe_normalize(cross(X, sd->I));
207   float3 Z = safe_normalize(cross(X, Y));
208   /* TODO: the solution below works where sd->Ng is the normal
209    * pointing from the center of the curve to the shading point.
210    * It doesn't work for triangles, see https://developer.blender.org/T43625 */
211
212   /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at
213    * the center, to grazing the other edge. This is the sine of the angle
214    * between sd->Ng and Z, as seen from the tangent X. */
215
216   /* TODO: we convert this value to a cosine later and discard the sign, so
217    * we could probably save some operations. */
218   float h = dot(cross(sd->Ng, X), Z);
219
220   kernel_assert(fabsf(h) < 1.0f + 1e-4f);
221   kernel_assert(isfinite3_safe(Y));
222   kernel_assert(isfinite_safe(h));
223
224   bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
225
226   return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
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. */
281 ccl_device float3 bsdf_principled_hair_eval(KernelGlobals *kg,
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);
294   float3 Z = safe_normalize(cross(X, Y));
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;
334   kernel_assert(isfinite3_safe(float4_to_float3(F)));
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;
340   kernel_assert(isfinite3_safe(float4_to_float3(F)));
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;
346   kernel_assert(isfinite3_safe(float4_to_float3(F)));
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;
352   kernel_assert(isfinite3_safe(float4_to_float3(F)));
353
354   *pdf = F.w;
355   return float4_to_float3(F);
356 }
357
358 /* Sampling function for the hair shader. */
359 ccl_device int bsdf_principled_hair_sample(KernelGlobals *kg,
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 {
370   PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
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);
376   float3 Z = safe_normalize(cross(X, Y));
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;
451   kernel_assert(isfinite3_safe(float4_to_float3(F)));
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;
457   kernel_assert(isfinite3_safe(float4_to_float3(F)));
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;
463   kernel_assert(isfinite3_safe(float4_to_float3(F)));
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;
469   kernel_assert(isfinite3_safe(float4_to_float3(F)));
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. */
486 ccl_device void bsdf_principled_hair_blur(ShaderClosure *sc, float roughness)
487 {
488   PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
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 CCL_NAMESPACE_END
496
497 #endif /* __BSDF_HAIR_PRINCIPLED_H__ */