bsdf_hair_principled.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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. #ifdef __KERNEL_CPU__
  17. # include <fenv.h>
  18. #endif
  19. #include "kernel/kernel_color.h"
  20. #ifndef __BSDF_HAIR_PRINCIPLED_H__
  21. # define __BSDF_HAIR_PRINCIPLED_H__
  22. CCL_NAMESPACE_BEGIN
  23. typedef ccl_addr_space struct PrincipledHairExtra {
  24. /* Geometry data. */
  25. float4 geom;
  26. } PrincipledHairExtra;
  27. typedef ccl_addr_space struct PrincipledHairBSDF {
  28. SHADER_CLOSURE_BASE;
  29. /* Absorption coefficient. */
  30. float3 sigma;
  31. /* Variance of the underlying logistic distribution. */
  32. float v;
  33. /* Scale factor of the underlying logistic distribution. */
  34. float s;
  35. /* Cuticle tilt angle. */
  36. float alpha;
  37. /* IOR. */
  38. float eta;
  39. /* Effective variance for the diffuse bounce only. */
  40. float m0_roughness;
  41. /* Extra closure. */
  42. PrincipledHairExtra *extra;
  43. } PrincipledHairBSDF;
  44. static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairBSDF),
  45. "PrincipledHairBSDF is too large!");
  46. static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairExtra),
  47. "PrincipledHairExtra is too large!");
  48. ccl_device_inline float cos_from_sin(const float s)
  49. {
  50. return safe_sqrtf(1.0f - s * s);
  51. }
  52. /* Gives the change in direction in the normal plane for the given angles and p-th-order
  53. * scattering. */
  54. ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
  55. {
  56. return 2.0f * p * gamma_t - 2.0f * gamma_o + p * M_PI_F;
  57. }
  58. /* Remaps the given angle to [-pi, pi]. */
  59. ccl_device_inline float wrap_angle(float a)
  60. {
  61. while (a > M_PI_F) {
  62. a -= M_2PI_F;
  63. }
  64. while (a < -M_PI_F) {
  65. a += M_2PI_F;
  66. }
  67. return a;
  68. }
  69. /* Logistic distribution function. */
  70. ccl_device_inline float logistic(float x, float s)
  71. {
  72. float v = expf(-fabsf(x) / s);
  73. return v / (s * sqr(1.0f + v));
  74. }
  75. /* Logistic cumulative density function. */
  76. ccl_device_inline float logistic_cdf(float x, float s)
  77. {
  78. float arg = -x / s;
  79. /* expf() overflows if arg >= 89.0. */
  80. if (arg > 88.0f) {
  81. return 0.0f;
  82. }
  83. else {
  84. return 1.0f / (1.0f + expf(arg));
  85. }
  86. }
  87. /* Numerical approximation to the Bessel function of the first kind. */
  88. ccl_device_inline float bessel_I0(float x)
  89. {
  90. x = sqr(x);
  91. float val = 1.0f + 0.25f * x;
  92. float pow_x_2i = sqr(x);
  93. uint64_t i_fac_2 = 1;
  94. int pow_4_i = 16;
  95. for (int i = 2; i < 10; i++) {
  96. i_fac_2 *= i * i;
  97. float newval = val + pow_x_2i / (pow_4_i * i_fac_2);
  98. if (val == newval) {
  99. return val;
  100. }
  101. val = newval;
  102. pow_x_2i *= x;
  103. pow_4_i *= 4;
  104. }
  105. return val;
  106. }
  107. /* Logarithm of the Bessel function of the first kind. */
  108. ccl_device_inline float log_bessel_I0(float x)
  109. {
  110. if (x > 12.0f) {
  111. /* log(1/x) == -log(x) iff x > 0.
  112. * This is only used with positive cosines */
  113. return x + 0.5f * (1.f / (8.0f * x) - M_LN_2PI_F - logf(x));
  114. }
  115. else {
  116. return logf(bessel_I0(x));
  117. }
  118. }
  119. /* Logistic distribution limited to the interval [-pi, pi]. */
  120. ccl_device_inline float trimmed_logistic(float x, float s)
  121. {
  122. /* The logistic distribution is symmetric and centered around zero,
  123. * so logistic_cdf(x, s) = 1 - logistic_cdf(-x, s).
  124. * Therefore, logistic_cdf(x, s)-logistic_cdf(-x, s) = 1 - 2*logistic_cdf(-x, s) */
  125. float scaling_fac = 1.0f - 2.0f * logistic_cdf(-M_PI_F, s);
  126. float val = logistic(x, s);
  127. return safe_divide(val, scaling_fac);
  128. }
  129. /* Sampling function for the trimmed logistic function. */
  130. ccl_device_inline float sample_trimmed_logistic(float u, float s)
  131. {
  132. float cdf_minuspi = logistic_cdf(-M_PI_F, s);
  133. float x = -s * logf(1.0f / (u * (1.0f - 2.0f * cdf_minuspi) + cdf_minuspi) - 1.0f);
  134. return clamp(x, -M_PI_F, M_PI_F);
  135. }
  136. /* Azimuthal scattering function Np. */
  137. ccl_device_inline float azimuthal_scattering(
  138. float phi, int p, float s, float gamma_o, float gamma_t)
  139. {
  140. float phi_o = wrap_angle(phi - delta_phi(p, gamma_o, gamma_t));
  141. float val = trimmed_logistic(phi_o, s);
  142. return val;
  143. }
  144. /* Longitudinal scattering function Mp. */
  145. ccl_device_inline float longitudinal_scattering(
  146. float sin_theta_i, float cos_theta_i, float sin_theta_o, float cos_theta_o, float v)
  147. {
  148. float inv_v = 1.0f / v;
  149. float cos_arg = cos_theta_i * cos_theta_o * inv_v;
  150. float sin_arg = sin_theta_i * sin_theta_o * inv_v;
  151. if (v <= 0.1f) {
  152. float i0 = log_bessel_I0(cos_arg);
  153. float val = expf(i0 - sin_arg - inv_v + 0.6931f + logf(0.5f * inv_v));
  154. return val;
  155. }
  156. else {
  157. float i0 = bessel_I0(cos_arg);
  158. float val = (expf(-sin_arg) * i0) / (sinhf(inv_v) * 2.0f * v);
  159. return val;
  160. }
  161. }
  162. /* Combine the three values using their luminances. */
  163. ccl_device_inline float4 combine_with_energy(KernelGlobals *kg, float3 c)
  164. {
  165. return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c));
  166. }
  167. # ifdef __HAIR__
  168. /* Set up the hair closure. */
  169. ccl_device int bsdf_principled_hair_setup(ShaderData *sd, PrincipledHairBSDF *bsdf)
  170. {
  171. bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
  172. bsdf->v = clamp(bsdf->v, 0.001f, 1.0f);
  173. bsdf->s = clamp(bsdf->s, 0.001f, 1.0f);
  174. /* Apply Primary Reflection Roughness modifier. */
  175. bsdf->m0_roughness = clamp(bsdf->m0_roughness * bsdf->v, 0.001f, 1.0f);
  176. /* Map from roughness_u and roughness_v to variance and scale factor. */
  177. bsdf->v = sqr(0.726f * bsdf->v + 0.812f * sqr(bsdf->v) + 3.700f * pow20(bsdf->v));
  178. bsdf->s = (0.265f * bsdf->s + 1.194f * sqr(bsdf->s) + 5.372f * pow22(bsdf->s)) * M_SQRT_PI_8_F;
  179. bsdf->m0_roughness = sqr(0.726f * bsdf->m0_roughness + 0.812f * sqr(bsdf->m0_roughness) +
  180. 3.700f * pow20(bsdf->m0_roughness));
  181. /* Compute local frame, aligned to curve tangent and ray direction. */
  182. float3 X = safe_normalize(sd->dPdu);
  183. float3 Y = safe_normalize(cross(X, sd->I));
  184. float3 Z = safe_normalize(cross(X, Y));
  185. /* TODO: the solution below works where sd->Ng is the normal
  186. * pointing from the center of the curve to the shading point.
  187. * It doesn't work for triangles, see https://developer.blender.org/T43625 */
  188. /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at
  189. * the center, to grazing the other edge. This is the sine of the angle
  190. * between sd->Ng and Z, as seen from the tangent X. */
  191. /* TODO: we convert this value to a cosine later and discard the sign, so
  192. * we could probably save some operations. */
  193. float h = dot(cross(sd->Ng, X), Z);
  194. kernel_assert(fabsf(h) < 1.0f + 1e-4f);
  195. kernel_assert(isfinite3_safe(Y));
  196. kernel_assert(isfinite_safe(h));
  197. bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
  198. return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
  199. }
  200. # endif /* __HAIR__ */
  201. /* Given the Fresnel term and transmittance, generate the attenuation terms for each bounce. */
  202. ccl_device_inline void hair_attenuation(KernelGlobals *kg, float f, float3 T, float4 *Ap)
  203. {
  204. /* Primary specular (R). */
  205. Ap[0] = make_float4(f, f, f, f);
  206. /* Transmission (TT). */
  207. float3 col = sqr(1.0f - f) * T;
  208. Ap[1] = combine_with_energy(kg, col);
  209. /* Secondary specular (TRT). */
  210. col *= T * f;
  211. Ap[2] = combine_with_energy(kg, col);
  212. /* Residual component (TRRT+). */
  213. col *= safe_divide_color(T * f, make_float3(1.0f, 1.0f, 1.0f) - T * f);
  214. Ap[3] = combine_with_energy(kg, col);
  215. /* Normalize sampling weights. */
  216. float totweight = Ap[0].w + Ap[1].w + Ap[2].w + Ap[3].w;
  217. float fac = safe_divide(1.0f, totweight);
  218. Ap[0].w *= fac;
  219. Ap[1].w *= fac;
  220. Ap[2].w *= fac;
  221. Ap[3].w *= fac;
  222. }
  223. /* Given the tilt angle, generate the rotated theta_i for the different bounces. */
  224. ccl_device_inline void hair_alpha_angles(float sin_theta_i,
  225. float cos_theta_i,
  226. float alpha,
  227. float *angles)
  228. {
  229. float sin_1alpha = sinf(alpha);
  230. float cos_1alpha = cos_from_sin(sin_1alpha);
  231. float sin_2alpha = 2.0f * sin_1alpha * cos_1alpha;
  232. float cos_2alpha = sqr(cos_1alpha) - sqr(sin_1alpha);
  233. float sin_4alpha = 2.0f * sin_2alpha * cos_2alpha;
  234. float cos_4alpha = sqr(cos_2alpha) - sqr(sin_2alpha);
  235. angles[0] = sin_theta_i * cos_2alpha + cos_theta_i * sin_2alpha;
  236. angles[1] = fabsf(cos_theta_i * cos_2alpha - sin_theta_i * sin_2alpha);
  237. angles[2] = sin_theta_i * cos_1alpha - cos_theta_i * sin_1alpha;
  238. angles[3] = fabsf(cos_theta_i * cos_1alpha + sin_theta_i * sin_1alpha);
  239. angles[4] = sin_theta_i * cos_4alpha - cos_theta_i * sin_4alpha;
  240. angles[5] = fabsf(cos_theta_i * cos_4alpha + sin_theta_i * sin_4alpha);
  241. }
  242. /* Evaluation function for our shader. */
  243. ccl_device float3 bsdf_principled_hair_eval(KernelGlobals *kg,
  244. const ShaderData *sd,
  245. const ShaderClosure *sc,
  246. const float3 omega_in,
  247. float *pdf)
  248. {
  249. kernel_assert(isfinite3_safe(sd->P) && isfinite_safe(sd->ray_length));
  250. const PrincipledHairBSDF *bsdf = (const PrincipledHairBSDF *)sc;
  251. float3 Y = float4_to_float3(bsdf->extra->geom);
  252. float3 X = safe_normalize(sd->dPdu);
  253. kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
  254. float3 Z = safe_normalize(cross(X, Y));
  255. float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
  256. float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
  257. float sin_theta_o = wo.x;
  258. float cos_theta_o = cos_from_sin(sin_theta_o);
  259. float phi_o = atan2f(wo.z, wo.y);
  260. float sin_theta_t = sin_theta_o / bsdf->eta;
  261. float cos_theta_t = cos_from_sin(sin_theta_t);
  262. float sin_gamma_o = bsdf->extra->geom.w;
  263. float cos_gamma_o = cos_from_sin(sin_gamma_o);
  264. float gamma_o = safe_asinf(sin_gamma_o);
  265. float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
  266. float cos_gamma_t = cos_from_sin(sin_gamma_t);
  267. float gamma_t = safe_asinf(sin_gamma_t);
  268. float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
  269. float4 Ap[4];
  270. hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
  271. float sin_theta_i = wi.x;
  272. float cos_theta_i = cos_from_sin(sin_theta_i);
  273. float phi_i = atan2f(wi.z, wi.y);
  274. float phi = phi_i - phi_o;
  275. float angles[6];
  276. hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
  277. float4 F;
  278. float Mp, Np;
  279. /* Primary specular (R). */
  280. Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
  281. Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
  282. F = Ap[0] * Mp * Np;
  283. kernel_assert(isfinite3_safe(float4_to_float3(F)));
  284. /* Transmission (TT). */
  285. Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
  286. Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
  287. F += Ap[1] * Mp * Np;
  288. kernel_assert(isfinite3_safe(float4_to_float3(F)));
  289. /* Secondary specular (TRT). */
  290. Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
  291. Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
  292. F += Ap[2] * Mp * Np;
  293. kernel_assert(isfinite3_safe(float4_to_float3(F)));
  294. /* Residual component (TRRT+). */
  295. Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
  296. Np = M_1_2PI_F;
  297. F += Ap[3] * Mp * Np;
  298. kernel_assert(isfinite3_safe(float4_to_float3(F)));
  299. *pdf = F.w;
  300. return float4_to_float3(F);
  301. }
  302. /* Sampling function for the hair shader. */
  303. ccl_device int bsdf_principled_hair_sample(KernelGlobals *kg,
  304. const ShaderClosure *sc,
  305. ShaderData *sd,
  306. float randu,
  307. float randv,
  308. float3 *eval,
  309. float3 *omega_in,
  310. float3 *domega_in_dx,
  311. float3 *domega_in_dy,
  312. float *pdf)
  313. {
  314. PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
  315. float3 Y = float4_to_float3(bsdf->extra->geom);
  316. float3 X = safe_normalize(sd->dPdu);
  317. kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
  318. float3 Z = safe_normalize(cross(X, Y));
  319. float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z));
  320. float2 u[2];
  321. u[0] = make_float2(randu, randv);
  322. u[1].x = lcg_step_float_addrspace(&sd->lcg_state);
  323. u[1].y = lcg_step_float_addrspace(&sd->lcg_state);
  324. float sin_theta_o = wo.x;
  325. float cos_theta_o = cos_from_sin(sin_theta_o);
  326. float phi_o = atan2f(wo.z, wo.y);
  327. float sin_theta_t = sin_theta_o / bsdf->eta;
  328. float cos_theta_t = cos_from_sin(sin_theta_t);
  329. float sin_gamma_o = bsdf->extra->geom.w;
  330. float cos_gamma_o = cos_from_sin(sin_gamma_o);
  331. float gamma_o = safe_asinf(sin_gamma_o);
  332. float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
  333. float cos_gamma_t = cos_from_sin(sin_gamma_t);
  334. float gamma_t = safe_asinf(sin_gamma_t);
  335. float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
  336. float4 Ap[4];
  337. hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
  338. int p = 0;
  339. for (; p < 3; p++) {
  340. if (u[0].x < Ap[p].w) {
  341. break;
  342. }
  343. u[0].x -= Ap[p].w;
  344. }
  345. float v = bsdf->v;
  346. if (p == 1) {
  347. v *= 0.25f;
  348. }
  349. if (p >= 2) {
  350. v *= 4.0f;
  351. }
  352. u[1].x = max(u[1].x, 1e-5f);
  353. float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
  354. float sin_theta_i = -fac * sin_theta_o +
  355. cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o;
  356. float cos_theta_i = cos_from_sin(sin_theta_i);
  357. float angles[6];
  358. if (p < 3) {
  359. hair_alpha_angles(sin_theta_i, cos_theta_i, -bsdf->alpha, angles);
  360. sin_theta_i = angles[2 * p];
  361. cos_theta_i = angles[2 * p + 1];
  362. }
  363. float phi;
  364. if (p < 3) {
  365. phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(u[0].y, bsdf->s);
  366. }
  367. else {
  368. phi = M_2PI_F * u[0].y;
  369. }
  370. float phi_i = phi_o + phi;
  371. hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
  372. float4 F;
  373. float Mp, Np;
  374. /* Primary specular (R). */
  375. Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
  376. Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
  377. F = Ap[0] * Mp * Np;
  378. kernel_assert(isfinite3_safe(float4_to_float3(F)));
  379. /* Transmission (TT). */
  380. Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
  381. Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
  382. F += Ap[1] * Mp * Np;
  383. kernel_assert(isfinite3_safe(float4_to_float3(F)));
  384. /* Secondary specular (TRT). */
  385. Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
  386. Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
  387. F += Ap[2] * Mp * Np;
  388. kernel_assert(isfinite3_safe(float4_to_float3(F)));
  389. /* Residual component (TRRT+). */
  390. Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
  391. Np = M_1_2PI_F;
  392. F += Ap[3] * Mp * Np;
  393. kernel_assert(isfinite3_safe(float4_to_float3(F)));
  394. *eval = float4_to_float3(F);
  395. *pdf = F.w;
  396. *omega_in = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
  397. # ifdef __RAY_DIFFERENTIALS__
  398. float3 N = safe_normalize(sd->I + *omega_in);
  399. *domega_in_dx = (2 * dot(N, sd->dI.dx)) * N - sd->dI.dx;
  400. *domega_in_dy = (2 * dot(N, sd->dI.dy)) * N - sd->dI.dy;
  401. # endif
  402. return LABEL_GLOSSY | ((p == 0) ? LABEL_REFLECT : LABEL_TRANSMIT);
  403. }
  404. /* Implements Filter Glossy by capping the effective roughness. */
  405. ccl_device void bsdf_principled_hair_blur(ShaderClosure *sc, float roughness)
  406. {
  407. PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
  408. bsdf->v = fmaxf(roughness, bsdf->v);
  409. bsdf->s = fmaxf(roughness, bsdf->s);
  410. bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness);
  411. }
  412. CCL_NAMESPACE_END
  413. #endif /* __BSDF_HAIR_PRINCIPLED_H__ */