Blender  V3.3
bsdf_microfacet.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Adapted from Open Shading Language
4  * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5  * All Rights Reserved.
6  *
7  * Modifications Copyright 2011-2022 Blender Foundation. */
8 
9 #pragma once
10 
12 
13 #include "kernel/sample/pattern.h"
14 
16 
18 
19 typedef struct MicrofacetExtra {
22  float clearcoat;
24 
25 typedef struct MicrofacetBsdf {
27 
28  float alpha_x, alpha_y, ior;
32 
33 static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetBsdf), "MicrofacetBsdf is too large!");
34 
35 /* Beckmann and GGX microfacet importance sampling. */
36 
38  const float cos_theta_i,
39  const float sin_theta_i,
40  float randu,
41  float randv,
42  ccl_private float *slope_x,
43  ccl_private float *slope_y,
44  ccl_private float *G1i)
45 {
46  /* special case (normal incidence) */
47  if (cos_theta_i >= 0.99999f) {
48  const float r = sqrtf(-logf(randu));
49  const float phi = M_2PI_F * randv;
50  *slope_x = r * cosf(phi);
51  *slope_y = r * sinf(phi);
52  *G1i = 1.0f;
53  return;
54  }
55 
56  /* precomputations */
57  const float tan_theta_i = sin_theta_i / cos_theta_i;
58  const float inv_a = tan_theta_i;
59  const float cot_theta_i = 1.0f / tan_theta_i;
60  const float erf_a = fast_erff(cot_theta_i);
61  const float exp_a2 = expf(-cot_theta_i * cot_theta_i);
62  const float SQRT_PI_INV = 0.56418958354f;
63  const float Lambda = 0.5f * (erf_a - 1.0f) + (0.5f * SQRT_PI_INV) * (exp_a2 * inv_a);
64  const float G1 = 1.0f / (1.0f + Lambda); /* masking */
65 
66  *G1i = G1;
67 
68 #if defined(__KERNEL_GPU__)
69  /* Based on paper from Wenzel Jakob
70  * An Improved Visible Normal Sampling Routine for the Beckmann Distribution
71  *
72  * http://www.mitsuba-renderer.org/~wenzel/files/visnormal.pdf
73  *
74  * Reformulation from OpenShadingLanguage which avoids using inverse
75  * trigonometric functions.
76  */
77 
78  /* Sample slope X.
79  *
80  * Compute a coarse approximation using the approximation:
81  * exp(-ierf(x)^2) ~= 1 - x * x
82  * solve y = 1 + b + K * (1 - b * b)
83  */
84  float K = tan_theta_i * SQRT_PI_INV;
85  float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a));
86  float y_exact = randu * (1.0f + erf_a + K * exp_a2);
87  float b = K > 0 ? (0.5f - sqrtf(K * (K - y_approx + 1.0f) + 0.25f)) / K : y_approx - 1.0f;
88 
89  /* Perform newton step to refine toward the true root. */
90  float inv_erf = fast_ierff(b);
91  float value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact;
92  /* Check if we are close enough already,
93  * this also avoids NaNs as we get close to the root.
94  */
95  if (fabsf(value) > 1e-6f) {
96  b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 1. */
97  inv_erf = fast_ierff(b);
98  value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact;
99  b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 2. */
100  /* Compute the slope from the refined value. */
101  *slope_x = fast_ierff(b);
102  }
103  else {
104  /* We are close enough already. */
105  *slope_x = inv_erf;
106  }
107  *slope_y = fast_ierff(2.0f * randv - 1.0f);
108 #else
109  /* Use precomputed table on CPU, it gives better performance. */
110  int beckmann_table_offset = kernel_data.tables.beckmann_offset;
111 
112  *slope_x = lookup_table_read_2D(
113  kg, randu, cos_theta_i, beckmann_table_offset, BECKMANN_TABLE_SIZE, BECKMANN_TABLE_SIZE);
114  *slope_y = fast_ierff(2.0f * randv - 1.0f);
115 #endif
116 }
117 
118 /* GGX microfacet importance sampling from:
119  *
120  * Importance Sampling Microfacet-Based BSDFs using the Distribution of Visible Normals.
121  * E. Heitz and E. d'Eon, EGSR 2014
122  */
123 
124 ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i,
125  const float sin_theta_i,
126  float randu,
127  float randv,
128  ccl_private float *slope_x,
129  ccl_private float *slope_y,
130  ccl_private float *G1i)
131 {
132  /* special case (normal incidence) */
133  if (cos_theta_i >= 0.99999f) {
134  const float r = sqrtf(randu / (1.0f - randu));
135  const float phi = M_2PI_F * randv;
136  *slope_x = r * cosf(phi);
137  *slope_y = r * sinf(phi);
138  *G1i = 1.0f;
139 
140  return;
141  }
142 
143  /* precomputations */
144  const float tan_theta_i = sin_theta_i / cos_theta_i;
145  const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i * tan_theta_i));
146 
147  *G1i = 1.0f / G1_inv;
148 
149  /* sample slope_x */
150  const float A = 2.0f * randu * G1_inv - 1.0f;
151  const float AA = A * A;
152  const float tmp = 1.0f / (AA - 1.0f);
153  const float B = tan_theta_i;
154  const float BB = B * B;
155  const float D = safe_sqrtf(BB * (tmp * tmp) - (AA - BB) * tmp);
156  const float slope_x_1 = B * tmp - D;
157  const float slope_x_2 = B * tmp + D;
158  *slope_x = (A < 0.0f || slope_x_2 * tan_theta_i > 1.0f) ? slope_x_1 : slope_x_2;
159 
160  /* sample slope_y */
161  float S;
162 
163  if (randv > 0.5f) {
164  S = 1.0f;
165  randv = 2.0f * (randv - 0.5f);
166  }
167  else {
168  S = -1.0f;
169  randv = 2.0f * (0.5f - randv);
170  }
171 
172  const float z = (randv * (randv * (randv * 0.27385f - 0.73369f) + 0.46341f)) /
173  (randv * (randv * (randv * 0.093073f + 0.309420f) - 1.000000f) + 0.597999f);
174  *slope_y = S * z * safe_sqrtf(1.0f + (*slope_x) * (*slope_x));
175 }
176 
178  const float3 omega_i,
179  const float alpha_x,
180  const float alpha_y,
181  const float randu,
182  const float randv,
183  bool beckmann,
184  ccl_private float *G1i)
185 {
186  /* 1. stretch omega_i */
187  float3 omega_i_ = make_float3(alpha_x * omega_i.x, alpha_y * omega_i.y, omega_i.z);
188  omega_i_ = normalize(omega_i_);
189 
190  /* get polar coordinates of omega_i_ */
191  float costheta_ = 1.0f;
192  float sintheta_ = 0.0f;
193  float cosphi_ = 1.0f;
194  float sinphi_ = 0.0f;
195 
196  if (omega_i_.z < 0.99999f) {
197  costheta_ = omega_i_.z;
198  sintheta_ = safe_sqrtf(1.0f - costheta_ * costheta_);
199 
200  float invlen = 1.0f / sintheta_;
201  cosphi_ = omega_i_.x * invlen;
202  sinphi_ = omega_i_.y * invlen;
203  }
204 
205  /* 2. sample P22_{omega_i}(x_slope, y_slope, 1, 1) */
206  float slope_x, slope_y;
207 
208  if (beckmann) {
210  kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i);
211  }
212  else {
213  microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i);
214  }
215 
216  /* 3. rotate */
217  float tmp = cosphi_ * slope_x - sinphi_ * slope_y;
218  slope_y = sinphi_ * slope_x + cosphi_ * slope_y;
219  slope_x = tmp;
220 
221  /* 4. unstretch */
222  slope_x = alpha_x * slope_x;
223  slope_y = alpha_y * slope_y;
224 
225  /* 5. compute normal */
226  return normalize(make_float3(-slope_x, -slope_y, 1.0f));
227 }
228 
229 /* Calculate the reflection color
230  *
231  * If fresnel is used, the color is an interpolation of the F0 color and white
232  * with respect to the fresnel
233  *
234  * Else it is simply white
235  */
237  float3 L,
238  float3 H)
239 {
240  float3 F = make_float3(1.0f, 1.0f, 1.0f);
241  bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
243  if (use_fresnel) {
244  float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
245 
246  F = interpolate_fresnel_color(L, H, bsdf->ior, F0, bsdf->extra->cspec0);
247  }
248 
249  return F;
250 }
251 
252 ccl_device_forceinline float D_GTR1(float NdotH, float alpha)
253 {
254  if (alpha >= 1.0f)
255  return M_1_PI_F;
256  float alpha2 = alpha * alpha;
257  float t = 1.0f + (alpha2 - 1.0f) * NdotH * NdotH;
258  return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t);
259 }
260 
263 {
265 
266  float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
267  bsdf->extra->fresnel_color = interpolate_fresnel_color(
268  sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0);
269 
270  if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
271  bsdf->extra->fresnel_color *= 0.25f * bsdf->extra->clearcoat;
272  }
273 
274  bsdf->sample_weight *= average(bsdf->extra->fresnel_color);
275 }
276 
277 /* GGX microfacet with Smith shadow-masking from:
278  *
279  * Microfacet Models for Refraction through Rough Surfaces
280  * B. Walter, S. R. Marschner, H. Li, K. E. Torrance, EGSR 2007
281  *
282  * Anisotropic from:
283  *
284  * Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs
285  * E. Heitz, Research Report 2014
286  *
287  * Anisotropy is only supported for reflection currently, but adding it for
288  * transmission is just a matter of copying code from reflection if needed. */
289 
291 {
292  bsdf->extra = NULL;
293 
294  bsdf->alpha_x = saturatef(bsdf->alpha_x);
295  bsdf->alpha_y = saturatef(bsdf->alpha_y);
296 
297  bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
298 
299  return SD_BSDF | SD_BSDF_HAS_EVAL;
300 }
301 
302 /* Required to maintain OSL interface. */
304 {
305  bsdf->alpha_y = bsdf->alpha_x;
306 
307  return bsdf_microfacet_ggx_setup(bsdf);
308 }
309 
311  ccl_private const ShaderData *sd)
312 {
313  bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
314 
315  bsdf->alpha_x = saturatef(bsdf->alpha_x);
316  bsdf->alpha_y = saturatef(bsdf->alpha_y);
317 
319 
321 
322  return SD_BSDF | SD_BSDF_HAS_EVAL;
323 }
324 
326  ccl_private const ShaderData *sd)
327 {
328  bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
329 
330  bsdf->alpha_x = saturatef(bsdf->alpha_x);
331  bsdf->alpha_y = bsdf->alpha_x;
332 
334 
336 
337  return SD_BSDF | SD_BSDF_HAS_EVAL;
338 }
339 
341 {
342  bsdf->extra = NULL;
343 
344  bsdf->alpha_x = saturatef(bsdf->alpha_x);
345  bsdf->alpha_y = bsdf->alpha_x;
346 
348 
349  return SD_BSDF | SD_BSDF_HAS_EVAL;
350 }
351 
353 {
355 
356  bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
357  bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
358 }
359 
361  const float3 I,
362  const float3 omega_in,
363  ccl_private float *pdf)
364 {
365  ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
366  float alpha_x = bsdf->alpha_x;
367  float alpha_y = bsdf->alpha_y;
368  bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
369  float3 N = bsdf->N;
370 
371  if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
372  *pdf = 0.0f;
373  return make_float3(0.0f, 0.0f, 0.0f);
374  }
375 
376  float cosNO = dot(N, I);
377  float cosNI = dot(N, omega_in);
378 
379  if (cosNI > 0 && cosNO > 0) {
380  /* get half vector */
381  float3 m = normalize(omega_in + I);
382  float alpha2 = alpha_x * alpha_y;
383  float D, G1o, G1i;
384 
385  if (alpha_x == alpha_y) {
386  /* isotropic
387  * eq. 20: (F*G*D)/(4*in*on)
388  * eq. 33: first we calculate D(m) */
389  float cosThetaM = dot(N, m);
390  float cosThetaM2 = cosThetaM * cosThetaM;
391  float cosThetaM4 = cosThetaM2 * cosThetaM2;
392  float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
393 
394  if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
395  /* use GTR1 for clearcoat */
396  D = D_GTR1(cosThetaM, bsdf->alpha_x);
397 
398  /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
399  alpha2 = 0.0625f;
400  }
401  else {
402  /* use GTR2 otherwise */
403  D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
404  }
405 
406  /* eq. 34: now calculate G1(i,m) and G1(o,m) */
407  G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
408  G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
409  }
410  else {
411  /* anisotropic */
412  float3 X, Y, Z = N;
413  make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
414 
415  /* distribution */
416  float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
417  float slope_x = -local_m.x / (local_m.z * alpha_x);
418  float slope_y = -local_m.y / (local_m.z * alpha_y);
419  float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
420 
421  float cosThetaM = local_m.z;
422  float cosThetaM2 = cosThetaM * cosThetaM;
423  float cosThetaM4 = cosThetaM2 * cosThetaM2;
424 
425  D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
426 
427  /* G1(i,m) and G1(o,m) */
428  float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
429  float cosPhiO = dot(I, X);
430  float sinPhiO = dot(I, Y);
431 
432  float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
433  (sinPhiO * sinPhiO) * (alpha_y * alpha_y);
434  alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
435 
436  G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
437 
438  float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
439  float cosPhiI = dot(omega_in, X);
440  float sinPhiI = dot(omega_in, Y);
441 
442  float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
443  (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
444  alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
445 
446  G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
447  }
448 
449  float G = G1o * G1i;
450 
451  /* eq. 20 */
452  float common = D * 0.25f / cosNO;
453 
454  float3 F = reflection_color(bsdf, omega_in, m);
455  if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
456  F *= 0.25f * bsdf->extra->clearcoat;
457  }
458 
459  float3 out = F * G * common;
460 
461  /* eq. 2 in distribution of visible normals sampling
462  * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
463 
464  /* eq. 38 - but see also:
465  * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
466  * `pdf = pm * 0.25 / dot(m, I);` */
467  *pdf = G1o * common;
468 
469  return out;
470  }
471 
472  return make_float3(0.0f, 0.0f, 0.0f);
473 }
474 
476  const float3 I,
477  const float3 omega_in,
478  ccl_private float *pdf)
479 {
480  ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
481  float alpha_x = bsdf->alpha_x;
482  float alpha_y = bsdf->alpha_y;
483  float m_eta = bsdf->ior;
484  bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
485  float3 N = bsdf->N;
486 
487  if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
488  *pdf = 0.0f;
489  return make_float3(0.0f, 0.0f, 0.0f);
490  }
491 
492  float cosNO = dot(N, I);
493  float cosNI = dot(N, omega_in);
494 
495  if (cosNO <= 0 || cosNI >= 0) {
496  *pdf = 0.0f;
497  return make_float3(0.0f, 0.0f, 0.0f); /* vectors on same side -- not possible */
498  }
499  /* compute half-vector of the refraction (eq. 16) */
500  float3 ht = -(m_eta * omega_in + I);
501  float3 Ht = normalize(ht);
502  float cosHO = dot(Ht, I);
503  float cosHI = dot(Ht, omega_in);
504 
505  float D, G1o, G1i;
506 
507  /* eq. 33: first we calculate D(m) with m=Ht: */
508  float alpha2 = alpha_x * alpha_y;
509  float cosThetaM = dot(N, Ht);
510  float cosThetaM2 = cosThetaM * cosThetaM;
511  float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
512  float cosThetaM4 = cosThetaM2 * cosThetaM2;
513  D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
514 
515  /* eq. 34: now calculate G1(i,m) and G1(o,m) */
516  G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
517  G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
518 
519  float G = G1o * G1i;
520 
521  /* probability */
522  float Ht2 = dot(ht, ht);
523 
524  /* eq. 2 in distribution of visible normals sampling
525  * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
526 
527  /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
528  * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
529  float common = D * (m_eta * m_eta) / (cosNO * Ht2);
530  float out = G * fabsf(cosHI * cosHO) * common;
531  *pdf = G1o * fabsf(cosHO * cosHI) * common;
532 
533  return make_float3(out, out, out);
534 }
535 
537  ccl_private const ShaderClosure *sc,
538  float3 Ng,
539  float3 I,
540  float3 dIdx,
541  float3 dIdy,
542  float randu,
543  float randv,
544  ccl_private float3 *eval,
545  ccl_private float3 *omega_in,
546  ccl_private float3 *domega_in_dx,
547  ccl_private float3 *domega_in_dy,
548  ccl_private float *pdf)
549 {
550  ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
551  float alpha_x = bsdf->alpha_x;
552  float alpha_y = bsdf->alpha_y;
553  bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
554  float3 N = bsdf->N;
555  int label;
556 
557  float cosNO = dot(N, I);
558  if (cosNO > 0) {
559  float3 X, Y, Z = N;
560 
561  if (alpha_x == alpha_y)
562  make_orthonormals(Z, &X, &Y);
563  else
564  make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
565 
566  /* importance sampling with distribution of visible normals. vectors are
567  * transformed to local space before and after */
568  float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
569  float3 local_m;
570  float G1o;
571 
572  local_m = microfacet_sample_stretched(
573  kg, local_I, alpha_x, alpha_y, randu, randv, false, &G1o);
574 
575  float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z;
576  float cosThetaM = local_m.z;
577 
578  /* reflection or refraction? */
579  if (!m_refractive) {
580  float cosMO = dot(m, I);
582 
583  if (cosMO > 0) {
584  /* eq. 39 - compute actual reflected direction */
585  *omega_in = 2 * cosMO * m - I;
586 
587  if (dot(Ng, *omega_in) > 0) {
588  if (alpha_x * alpha_y <= 1e-7f) {
589  /* some high number for MIS */
590  *pdf = 1e6f;
591  *eval = make_float3(1e6f, 1e6f, 1e6f);
592 
593  bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
595 
596  /* if fresnel is used, calculate the color with reflection_color(...) */
597  if (use_fresnel) {
598  *eval *= reflection_color(bsdf, *omega_in, m);
599  }
600 
602  }
603  else {
604  /* microfacet normal is visible to this ray */
605  /* eq. 33 */
606  float alpha2 = alpha_x * alpha_y;
607  float D, G1i;
608 
609  if (alpha_x == alpha_y) {
610  /* isotropic */
611  float cosThetaM2 = cosThetaM * cosThetaM;
612  float cosThetaM4 = cosThetaM2 * cosThetaM2;
613  float tanThetaM2 = 1 / (cosThetaM2)-1;
614 
615  /* eval BRDF*cosNI */
616  float cosNI = dot(N, *omega_in);
617 
618  if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
619  /* use GTR1 for clearcoat */
620  D = D_GTR1(cosThetaM, bsdf->alpha_x);
621 
622  /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
623  alpha2 = 0.0625f;
624 
625  /* recalculate G1o */
626  G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
627  }
628  else {
629  /* use GTR2 otherwise */
630  D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
631  }
632 
633  /* eq. 34: now calculate G1(i,m) */
634  G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
635  }
636  else {
637  /* anisotropic distribution */
638  float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
639  float slope_x = -local_m.x / (local_m.z * alpha_x);
640  float slope_y = -local_m.y / (local_m.z * alpha_y);
641  float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
642 
643  float cosThetaM = local_m.z;
644  float cosThetaM2 = cosThetaM * cosThetaM;
645  float cosThetaM4 = cosThetaM2 * cosThetaM2;
646 
647  D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
648 
649  /* calculate G1(i,m) */
650  float cosNI = dot(N, *omega_in);
651 
652  float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
653  float cosPhiI = dot(*omega_in, X);
654  float sinPhiI = dot(*omega_in, Y);
655 
656  float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
657  (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
658  alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
659 
660  G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
661  }
662 
663  /* see eval function for derivation */
664  float common = (G1o * D) * 0.25f / cosNO;
665  *pdf = common;
666 
667  float3 F = reflection_color(bsdf, *omega_in, m);
668 
669  *eval = G1i * common * F;
670  }
671 
672  if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
673  *eval *= 0.25f * bsdf->extra->clearcoat;
674  }
675 
676 #ifdef __RAY_DIFFERENTIALS__
677  *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
678  *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
679 #endif
680  }
681  else {
682  *eval = make_float3(0.0f, 0.0f, 0.0f);
683  *pdf = 0.0f;
684  }
685  }
686  }
687  else {
689 
690  /* CAUTION: the i and o variables are inverted relative to the paper
691  * eq. 39 - compute actual refractive direction */
692  float3 R, T;
693 #ifdef __RAY_DIFFERENTIALS__
694  float3 dRdx, dRdy, dTdx, dTdy;
695 #endif
696  float m_eta = bsdf->ior, fresnel;
697  bool inside;
698 
699  fresnel = fresnel_dielectric(m_eta,
700  m,
701  I,
702  &R,
703  &T,
705  dIdx,
706  dIdy,
707  &dRdx,
708  &dRdy,
709  &dTdx,
710  &dTdy,
711 #endif
712  &inside);
713 
714  if (!inside && fresnel != 1.0f) {
715 
716  *omega_in = T;
717 #ifdef __RAY_DIFFERENTIALS__
718  *domega_in_dx = dTdx;
719  *domega_in_dy = dTdy;
720 #endif
721 
722  if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
723  /* some high number for MIS */
724  *pdf = 1e6f;
725  *eval = make_float3(1e6f, 1e6f, 1e6f);
727  }
728  else {
729  /* eq. 33 */
730  float alpha2 = alpha_x * alpha_y;
731  float cosThetaM2 = cosThetaM * cosThetaM;
732  float cosThetaM4 = cosThetaM2 * cosThetaM2;
733  float tanThetaM2 = 1 / (cosThetaM2)-1;
734  float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
735 
736  /* eval BRDF*cosNI */
737  float cosNI = dot(N, *omega_in);
738 
739  /* eq. 34: now calculate G1(i,m) */
740  float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
741 
742  /* eq. 21 */
743  float cosHI = dot(m, *omega_in);
744  float cosHO = dot(m, I);
745  float Ht2 = m_eta * cosHI + cosHO;
746  Ht2 *= Ht2;
747 
748  /* see eval function for derivation */
749  float common = (G1o * D) * (m_eta * m_eta) / (cosNO * Ht2);
750  float out = G1i * fabsf(cosHI * cosHO) * common;
751  *pdf = cosHO * fabsf(cosHI) * common;
752 
753  *eval = make_float3(out, out, out);
754  }
755  }
756  else {
757  *eval = make_float3(0.0f, 0.0f, 0.0f);
758  *pdf = 0.0f;
759  }
760  }
761  }
762  else {
764  }
765  return label;
766 }
767 
768 /* Beckmann microfacet with Smith shadow-masking from:
769  *
770  * Microfacet Models for Refraction through Rough Surfaces
771  * B. Walter, S. R. Marschner, H. Li, K. E. Torrance, EGSR 2007 */
772 
774 {
775  bsdf->alpha_x = saturatef(bsdf->alpha_x);
776  bsdf->alpha_y = saturatef(bsdf->alpha_y);
777 
779  return SD_BSDF | SD_BSDF_HAS_EVAL;
780 }
781 
782 /* Required to maintain OSL interface. */
784 {
785  bsdf->alpha_y = bsdf->alpha_x;
786 
787  return bsdf_microfacet_beckmann_setup(bsdf);
788 }
789 
791 {
792  bsdf->alpha_x = saturatef(bsdf->alpha_x);
793  bsdf->alpha_y = bsdf->alpha_x;
794 
796  return SD_BSDF | SD_BSDF_HAS_EVAL;
797 }
798 
800 {
802 
803  bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
804  bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
805 }
806 
807 ccl_device_inline float bsdf_beckmann_G1(float alpha, float cos_n)
808 {
809  cos_n *= cos_n;
810  float invA = alpha * safe_sqrtf((1.0f - cos_n) / cos_n);
811  if (invA < 0.625f) {
812  return 1.0f;
813  }
814 
815  float a = 1.0f / invA;
816  return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f);
817 }
818 
820  float alpha_x, float alpha_y, float cos_n, float cos_phi, float sin_phi)
821 {
822  cos_n *= cos_n;
823  sin_phi *= sin_phi;
824  cos_phi *= cos_phi;
825  alpha_x *= alpha_x;
826  alpha_y *= alpha_y;
827 
828  float alphaO2 = (cos_phi * alpha_x + sin_phi * alpha_y) / (cos_phi + sin_phi);
829  float invA = safe_sqrtf(alphaO2 * (1 - cos_n) / cos_n);
830  if (invA < 0.625f) {
831  return 1.0f;
832  }
833 
834  float a = 1.0f / invA;
835  return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f);
836 }
837 
839  const float3 I,
840  const float3 omega_in,
841  ccl_private float *pdf)
842 {
843  ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
844  float alpha_x = bsdf->alpha_x;
845  float alpha_y = bsdf->alpha_y;
846  bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
847  float3 N = bsdf->N;
848 
849  if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
850  *pdf = 0.0f;
851  return make_float3(0.0f, 0.0f, 0.0f);
852  }
853 
854  float cosNO = dot(N, I);
855  float cosNI = dot(N, omega_in);
856 
857  if (cosNO > 0 && cosNI > 0) {
858  /* get half vector */
859  float3 m = normalize(omega_in + I);
860 
861  float alpha2 = alpha_x * alpha_y;
862  float D, G1o, G1i;
863 
864  if (alpha_x == alpha_y) {
865  /* isotropic
866  * eq. 20: (F*G*D)/(4*in*on)
867  * eq. 25: first we calculate D(m) */
868  float cosThetaM = dot(N, m);
869  float cosThetaM2 = cosThetaM * cosThetaM;
870  float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
871  float cosThetaM4 = cosThetaM2 * cosThetaM2;
872  D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
873 
874  /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
875  G1o = bsdf_beckmann_G1(alpha_x, cosNO);
876  G1i = bsdf_beckmann_G1(alpha_x, cosNI);
877  }
878  else {
879  /* anisotropic */
880  float3 X, Y, Z = N;
881  make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
882 
883  /* distribution */
884  float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
885  float slope_x = -local_m.x / (local_m.z * alpha_x);
886  float slope_y = -local_m.y / (local_m.z * alpha_y);
887 
888  float cosThetaM = local_m.z;
889  float cosThetaM2 = cosThetaM * cosThetaM;
890  float cosThetaM4 = cosThetaM2 * cosThetaM2;
891 
892  D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
893 
894  /* G1(i,m) and G1(o,m) */
895  G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
896  G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
897  }
898 
899  float G = G1o * G1i;
900 
901  /* eq. 20 */
902  float common = D * 0.25f / cosNO;
903  float out = G * common;
904 
905  /* eq. 2 in distribution of visible normals sampling
906  * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
907 
908  /* eq. 38 - but see also:
909  * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
910  * pdf = pm * 0.25 / dot(m, I); */
911  *pdf = G1o * common;
912 
913  return make_float3(out, out, out);
914  }
915 
916  return make_float3(0.0f, 0.0f, 0.0f);
917 }
918 
920  const float3 I,
921  const float3 omega_in,
922  ccl_private float *pdf)
923 {
924  ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
925  float alpha_x = bsdf->alpha_x;
926  float alpha_y = bsdf->alpha_y;
927  float m_eta = bsdf->ior;
928  bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
929  float3 N = bsdf->N;
930 
931  if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
932  *pdf = 0.0f;
933  return make_float3(0.0f, 0.0f, 0.0f);
934  }
935 
936  float cosNO = dot(N, I);
937  float cosNI = dot(N, omega_in);
938 
939  if (cosNO <= 0 || cosNI >= 0) {
940  *pdf = 0.0f;
941  return make_float3(0.0f, 0.0f, 0.0f);
942  }
943  /* compute half-vector of the refraction (eq. 16) */
944  float3 ht = -(m_eta * omega_in + I);
945  float3 Ht = normalize(ht);
946  float cosHO = dot(Ht, I);
947  float cosHI = dot(Ht, omega_in);
948 
949  /* eq. 25: first we calculate D(m) with m=Ht: */
950  float alpha2 = alpha_x * alpha_y;
951  float cosThetaM = min(dot(N, Ht), 1.0f);
952  float cosThetaM2 = cosThetaM * cosThetaM;
953  float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
954  float cosThetaM4 = cosThetaM2 * cosThetaM2;
955  float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
956 
957  /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
958  float G1o = bsdf_beckmann_G1(alpha_x, cosNO);
959  float G1i = bsdf_beckmann_G1(alpha_x, cosNI);
960  float G = G1o * G1i;
961 
962  /* probability */
963  float Ht2 = dot(ht, ht);
964 
965  /* eq. 2 in distribution of visible normals sampling
966  * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
967 
968  /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
969  * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
970  float common = D * (m_eta * m_eta) / (cosNO * Ht2);
971  float out = G * fabsf(cosHI * cosHO) * common;
972  *pdf = G1o * fabsf(cosHO * cosHI) * common;
973 
974  return make_float3(out, out, out);
975 }
976 
978  ccl_private const ShaderClosure *sc,
979  float3 Ng,
980  float3 I,
981  float3 dIdx,
982  float3 dIdy,
983  float randu,
984  float randv,
985  ccl_private float3 *eval,
986  ccl_private float3 *omega_in,
987  ccl_private float3 *domega_in_dx,
988  ccl_private float3 *domega_in_dy,
989  ccl_private float *pdf)
990 {
991  ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
992  float alpha_x = bsdf->alpha_x;
993  float alpha_y = bsdf->alpha_y;
994  bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
995  float3 N = bsdf->N;
996  int label;
997 
998  float cosNO = dot(N, I);
999  if (cosNO > 0) {
1000  float3 X, Y, Z = N;
1001 
1002  if (alpha_x == alpha_y)
1003  make_orthonormals(Z, &X, &Y);
1004  else
1005  make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
1006 
1007  /* importance sampling with distribution of visible normals. vectors are
1008  * transformed to local space before and after */
1009  float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
1010  float3 local_m;
1011  float G1o;
1012 
1013  local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, true, &G1o);
1014 
1015  float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z;
1016  float cosThetaM = local_m.z;
1017 
1018  /* reflection or refraction? */
1019  if (!m_refractive) {
1021  float cosMO = dot(m, I);
1022 
1023  if (cosMO > 0) {
1024  /* eq. 39 - compute actual reflected direction */
1025  *omega_in = 2 * cosMO * m - I;
1026 
1027  if (dot(Ng, *omega_in) > 0) {
1028  if (alpha_x * alpha_y <= 1e-7f) {
1029  /* some high number for MIS */
1030  *pdf = 1e6f;
1031  *eval = make_float3(1e6f, 1e6f, 1e6f);
1033  }
1034  else {
1035  /* microfacet normal is visible to this ray
1036  * eq. 25 */
1037  float alpha2 = alpha_x * alpha_y;
1038  float D, G1i;
1039 
1040  if (alpha_x == alpha_y) {
1041  /* Isotropic distribution. */
1042  float cosThetaM2 = cosThetaM * cosThetaM;
1043  float cosThetaM4 = cosThetaM2 * cosThetaM2;
1044  float tanThetaM2 = 1 / (cosThetaM2)-1;
1045  D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
1046 
1047  /* eval BRDF*cosNI */
1048  float cosNI = dot(N, *omega_in);
1049 
1050  /* eq. 26, 27: now calculate G1(i,m) */
1051  G1i = bsdf_beckmann_G1(alpha_x, cosNI);
1052  }
1053  else {
1054  /* anisotropic distribution */
1055  float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
1056  float slope_x = -local_m.x / (local_m.z * alpha_x);
1057  float slope_y = -local_m.y / (local_m.z * alpha_y);
1058 
1059  float cosThetaM = local_m.z;
1060  float cosThetaM2 = cosThetaM * cosThetaM;
1061  float cosThetaM4 = cosThetaM2 * cosThetaM2;
1062 
1063  D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
1064 
1065  /* G1(i,m) */
1066  G1i = bsdf_beckmann_aniso_G1(
1067  alpha_x, alpha_y, dot(*omega_in, N), dot(*omega_in, X), dot(*omega_in, Y));
1068  }
1069 
1070  float G = G1o * G1i;
1071 
1072  /* see eval function for derivation */
1073  float common = D * 0.25f / cosNO;
1074  float out = G * common;
1075  *pdf = G1o * common;
1076 
1077  *eval = make_float3(out, out, out);
1078  }
1079 
1080 #ifdef __RAY_DIFFERENTIALS__
1081  *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
1082  *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
1083 #endif
1084  }
1085  else {
1086  *eval = make_float3(0.0f, 0.0f, 0.0f);
1087  *pdf = 0.0f;
1088  }
1089  }
1090  }
1091  else {
1093 
1094  /* CAUTION: the i and o variables are inverted relative to the paper
1095  * eq. 39 - compute actual refractive direction */
1096  float3 R, T;
1097 #ifdef __RAY_DIFFERENTIALS__
1098  float3 dRdx, dRdy, dTdx, dTdy;
1099 #endif
1100  float m_eta = bsdf->ior, fresnel;
1101  bool inside;
1102 
1103  fresnel = fresnel_dielectric(m_eta,
1104  m,
1105  I,
1106  &R,
1107  &T,
1108 #ifdef __RAY_DIFFERENTIALS__
1109  dIdx,
1110  dIdy,
1111  &dRdx,
1112  &dRdy,
1113  &dTdx,
1114  &dTdy,
1115 #endif
1116  &inside);
1117 
1118  if (!inside && fresnel != 1.0f) {
1119  *omega_in = T;
1120 
1121 #ifdef __RAY_DIFFERENTIALS__
1122  *domega_in_dx = dTdx;
1123  *domega_in_dy = dTdy;
1124 #endif
1125 
1126  if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
1127  /* some high number for MIS */
1128  *pdf = 1e6f;
1129  *eval = make_float3(1e6f, 1e6f, 1e6f);
1131  }
1132  else {
1133  /* eq. 33 */
1134  float alpha2 = alpha_x * alpha_y;
1135  float cosThetaM2 = cosThetaM * cosThetaM;
1136  float cosThetaM4 = cosThetaM2 * cosThetaM2;
1137  float tanThetaM2 = 1 / (cosThetaM2)-1;
1138  float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
1139 
1140  /* eval BRDF*cosNI */
1141  float cosNI = dot(N, *omega_in);
1142 
1143  /* eq. 26, 27: now calculate G1(i,m) */
1144  float G1i = bsdf_beckmann_G1(alpha_x, cosNI);
1145  float G = G1o * G1i;
1146 
1147  /* eq. 21 */
1148  float cosHI = dot(m, *omega_in);
1149  float cosHO = dot(m, I);
1150  float Ht2 = m_eta * cosHI + cosHO;
1151  Ht2 *= Ht2;
1152 
1153  /* see eval function for derivation */
1154  float common = D * (m_eta * m_eta) / (cosNO * Ht2);
1155  float out = G * fabsf(cosHI * cosHO) * common;
1156  *pdf = G1o * cosHO * fabsf(cosHI) * common;
1157 
1158  *eval = make_float3(out, out, out);
1159  }
1160  }
1161  else {
1162  *eval = make_float3(0.0f, 0.0f, 0.0f);
1163  *pdf = 0.0f;
1164  }
1165  }
1166  }
1167  else {
1168  label = (m_refractive) ? LABEL_TRANSMIT | LABEL_GLOSSY : LABEL_REFLECT | LABEL_GLOSSY;
1169  }
1170  return label;
1171 }
1172 
MINLINE float safe_sqrtf(float a)
#define K(key)
_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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
#define Z
Definition: GeomUtils.cpp:201
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color or the default fallback if none is specified Separate Split a vector into its X
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color or the default fallback if none is specified Separate Split a vector into its Y
#define A
ccl_device_inline float bsdf_beckmann_G1(float alpha, float cos_n)
ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosure *sc, const float3 I, const float3 omega_in, ccl_private float *pdf)
ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, const float3 omega_i, const float alpha_x, const float alpha_y, const float randu, const float randv, bool beckmann, ccl_private float *G1i)
ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float roughness)
ccl_device int bsdf_microfacet_beckmann_isotropic_setup(ccl_private MicrofacetBsdf *bsdf)
struct MicrofacetBsdf MicrofacetBsdf
Definition: closures.cpp:118
ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, ccl_private float3 *eval, ccl_private float3 *omega_in, ccl_private float3 *domega_in_dx, ccl_private float3 *domega_in_dy, ccl_private float *pdf)
CCL_NAMESPACE_BEGIN struct MicrofacetExtra MicrofacetExtra
ccl_device int bsdf_microfacet_beckmann_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_fresnel_setup(ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd)
ccl_device_forceinline float D_GTR1(float NdotH, float alpha)
ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const ShaderClosure *sc, const float3 I, const float3 omega_in, ccl_private float *pdf)
ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, ccl_private float3 *eval, ccl_private float3 *omega_in, ccl_private float3 *domega_in_dx, ccl_private float3 *domega_in_dy, ccl_private float *pdf)
ccl_device_inline float bsdf_beckmann_aniso_G1(float alpha_x, float alpha_y, float cos_n, float cos_phi, float sin_phi)
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd)
ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(ccl_private const ShaderClosure *sc, const float3 I, const float3 omega_in, ccl_private float *pdf)
ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClosure *sc, const float3 I, const float3 omega_in, ccl_private float *pdf)
ccl_device int bsdf_microfacet_beckmann_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device_forceinline float3 reflection_color(ccl_private const MicrofacetBsdf *bsdf, float3 L, float3 H)
ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const ShaderData *sd, ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_isotropic_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device void bsdf_microfacet_beckmann_blur(ccl_private ShaderClosure *sc, float roughness)
ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, const float cos_theta_i, const float sin_theta_i, float randu, float randv, ccl_private float *slope_x, ccl_private float *slope_y, ccl_private float *G1i)
ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, const float sin_theta_i, float randu, float randv, ccl_private float *slope_x, ccl_private float *slope_y, ccl_private float *G1i)
ccl_device float fresnel_dielectric_cos(float cosi, float eta)
Definition: bsdf_util.h:79
CCL_NAMESPACE_BEGIN ccl_device float fresnel_dielectric(float eta, const float3 N, const float3 I, ccl_private float3 *R, ccl_private float3 *T, ccl_private bool *is_inside)
Definition: bsdf_util.h:13
ccl_device_forceinline float3 interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0)
Definition: bsdf_util.h:114
#define kernel_assert(cond)
Definition: cpu/compat.h:34
#define ccl_device_forceinline
Definition: cuda/compat.h:35
#define logf(x)
Definition: cuda/compat.h:105
#define sinf(x)
Definition: cuda/compat.h:102
#define cosf(x)
Definition: cuda/compat.h:101
#define ccl_device
Definition: cuda/compat.h:32
#define expf(x)
Definition: cuda/compat.h:106
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_inline
Definition: cuda/compat.h:34
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
const char * label
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define CLOSURE_IS_BSDF_MICROFACET_FRESNEL(type)
@ CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID
@ CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID
@ CLOSURE_BSDF_MICROFACET_GGX_ID
@ CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID
@ CLOSURE_BSDF_MICROFACET_BECKMANN_ID
@ CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID
@ SD_BSDF_HAS_EVAL
Definition: kernel/types.h:744
@ SD_BSDF
Definition: kernel/types.h:742
#define BECKMANN_TABLE_SIZE
Definition: kernel/types.h:37
ShaderData
Definition: kernel/types.h:925
#define __RAY_DIFFERENTIALS__
Definition: kernel/types.h:62
@ LABEL_TRANSMIT
Definition: kernel/types.h:317
@ LABEL_SINGULAR
Definition: kernel/types.h:321
@ LABEL_GLOSSY
Definition: kernel/types.h:320
@ LABEL_REFLECT
Definition: kernel/types.h:318
ShaderClosure
Definition: kernel/types.h:726
ccl_device float lookup_table_read_2D(KernelGlobals kg, float x, float y, int offset, int xsize, int ysize)
Definition: lookup_table.h:26
ccl_device_inline float fast_erff(float x)
Definition: math_fast.h:554
ccl_device_inline float fast_ierff(float x)
Definition: math_fast.h:589
ccl_device_inline float average(const float2 &a)
Definition: math_float2.h:170
ccl_device_inline float3 saturate(float3 a)
Definition: math_float3.h:387
#define N
#define T
#define B
#define F
#define R
#define L
#define G(x, y, z)
#define H(x, y, z)
#define fmaxf(x, y)
Definition: metal/compat.h:228
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
#define make_float3(x, y, z)
Definition: metal/compat.h:204
static unsigned a[3]
Definition: RandGen.cpp:78
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
#define I
ccl_device void make_orthonormals_tangent(const float3 N, const float3 T, ccl_private float3 *a, ccl_private float3 *b)
#define min(a, b)
Definition: sort.c:35
Definition: pbvh_intern.h:21
ccl_private MicrofacetExtra * extra
float z
float y
float x
#define M_2PI_F
Definition: util/math.h:60
ccl_device_inline float saturatef(float a)
Definition: util/math.h:404
#define M_1_PI_F
Definition: util/math.h:43
#define M_PI_F
Definition: util/math.h:34
ccl_device_inline void make_orthonormals(const float3 N, ccl_private float3 *a, ccl_private float3 *b)
Definition: util/math.h:566
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:13