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