2
* Adapted from Open Shading Language with this license:
4
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
7
* Modifications Copyright 2011, Blender Foundation.
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions are
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.
33
#ifndef __BSDF_MICROFACET_H__
34
#define __BSDF_MICROFACET_H__
40
__device_inline float safe_sqrtf(float f)
42
return sqrtf(max(f, 0.0f));
45
__device int bsdf_microfacet_ggx_setup(ShaderClosure *sc)
49
float m_ag = clamp(ag, 1e-4f, 1.0f);
52
sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
54
return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
57
__device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc)
60
float eta = sc->data1;
62
float m_ag = clamp(ag, 1e-4f, 1.0f);
67
sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
69
return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
72
__device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness)
74
float m_ag = sc->data0;
75
m_ag = fmaxf(roughness, m_ag);
79
__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
81
float m_ag = sc->data0;
82
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
85
if(m_refractive) return make_float3 (0, 0, 0);
86
float cosNO = dot(N, I);
87
float cosNI = dot(N, omega_in);
88
if(cosNI > 0 && cosNO > 0) {
90
float3 Hr = normalize(omega_in + I);
91
// eq. 20: (F*G*D)/(4*in*on)
92
// eq. 33: first we calculate D(m) with m=Hr:
93
float alpha2 = m_ag * m_ag;
94
float cosThetaM = dot(N, Hr);
95
float cosThetaM2 = cosThetaM * cosThetaM;
96
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
97
float cosThetaM4 = cosThetaM2 * cosThetaM2;
98
float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
99
// eq. 34: now calculate G1(i,m) and G1(o,m)
100
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
101
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
103
float out = (G * D) * 0.25f / cosNO;
105
float pm = D * cosThetaM;
106
// convert into pdf of the sampled direction
107
// eq. 38 - but see also:
108
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
109
*pdf = pm * 0.25f / dot(Hr, I);
110
return make_float3 (out, out, out);
112
return make_float3 (0, 0, 0);
115
__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
117
float m_ag = sc->data0;
118
float m_eta = sc->data1;
119
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
122
if(!m_refractive) return make_float3 (0, 0, 0);
123
float cosNO = dot(N, I);
124
float cosNI = dot(N, omega_in);
125
if(cosNO <= 0 || cosNI >= 0)
126
return make_float3 (0, 0, 0); // vectors on same side -- not possible
127
// compute half-vector of the refraction (eq. 16)
128
float3 ht = -(m_eta * omega_in + I);
129
float3 Ht = normalize(ht);
130
float cosHO = dot(Ht, I);
132
float cosHI = dot(Ht, omega_in);
133
// eq. 33: first we calculate D(m) with m=Ht:
134
float alpha2 = m_ag * m_ag;
135
float cosThetaM = dot(N, Ht);
136
float cosThetaM2 = cosThetaM * cosThetaM;
137
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
138
float cosThetaM4 = cosThetaM2 * cosThetaM2;
139
float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
140
// eq. 34: now calculate G1(i,m) and G1(o,m)
141
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
142
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
145
float invHt2 = 1 / dot(ht, ht);
146
*pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2;
147
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO;
148
return make_float3 (out, out, out);
151
__device int bsdf_microfacet_ggx_sample(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)
153
float m_ag = sc->data0;
154
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
157
float cosNO = dot(N, I);
160
make_orthonormals(Z, &X, &Y);
161
// generate a random microfacet normal m
163
// we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
164
//tttt and sin(atan(x)) == x/sqrt(1+x^2)
165
float alpha2 = m_ag * m_ag;
166
float tanThetaM2 = alpha2 * randu / (1 - randu);
167
float cosThetaM = 1 / safe_sqrtf(1 + tanThetaM2);
168
float sinThetaM = cosThetaM * safe_sqrtf(tanThetaM2);
169
float phiM = 2 * M_PI_F * randv;
170
float3 m = (cosf(phiM) * sinThetaM) * X +
171
(sinf(phiM) * sinThetaM) * Y +
174
float cosMO = dot(m, I);
176
// eq. 39 - compute actual reflected direction
177
*omega_in = 2 * cosMO * m - I;
178
if(dot(Ng, *omega_in) > 0) {
179
// microfacet normal is visible to this ray
181
float cosThetaM2 = cosThetaM * cosThetaM;
182
float cosThetaM4 = cosThetaM2 * cosThetaM2;
183
float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
185
float pm = D * cosThetaM;
186
// convert into pdf of the sampled direction
187
// eq. 38 - but see also:
188
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
189
*pdf = pm * 0.25f / cosMO;
191
float cosNI = dot(N, *omega_in);
192
// eq. 34: now calculate G1(i,m) and G1(o,m)
193
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
194
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
196
// eq. 20: (F*G*D)/(4*in*on)
197
float out = (G * D) * 0.25f / cosNO;
198
*eval = make_float3(out, out, out);
199
#ifdef __RAY_DIFFERENTIALS__
200
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
201
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
207
// CAUTION: the i and o variables are inverted relative to the paper
208
// eq. 39 - compute actual refractive direction
210
#ifdef __RAY_DIFFERENTIALS__
211
float3 dRdx, dRdy, dTdx, dTdy;
213
float m_eta = sc->data1;
215
fresnel_dielectric(m_eta, m, I, &R, &T,
216
#ifdef __RAY_DIFFERENTIALS__
217
dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
223
#ifdef __RAY_DIFFERENTIALS__
224
*domega_in_dx = dTdx;
225
*domega_in_dy = dTdy;
228
float cosThetaM2 = cosThetaM * cosThetaM;
229
float cosThetaM4 = cosThetaM2 * cosThetaM2;
230
float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
232
float pm = D * cosThetaM;
234
float cosNI = dot(N, *omega_in);
235
// eq. 34: now calculate G1(i,m) and G1(o,m)
236
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
237
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
240
float cosHI = dot(m, *omega_in);
241
float cosHO = dot(m, I);
242
float Ht2 = m_eta * cosHI + cosHO;
244
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
246
*pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
247
*eval = make_float3(out, out, out);
251
return (m_refractive) ? LABEL_TRANSMIT|LABEL_GLOSSY : LABEL_REFLECT|LABEL_GLOSSY;
256
__device int bsdf_microfacet_beckmann_setup(ShaderClosure *sc)
258
float ab = sc->data0;
259
float m_ab = clamp(ab, 1e-4f, 1.0f);
263
sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
264
return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
267
__device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc)
269
float ab = sc->data0;
270
float eta = sc->data1;
271
float m_ab = clamp(ab, 1e-4f, 1.0f);
277
sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
278
return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
281
__device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness)
283
float m_ab = sc->data0;
284
m_ab = fmaxf(roughness, m_ab);
288
__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
290
float m_ab = sc->data0;
291
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
294
if(m_refractive) return make_float3 (0, 0, 0);
295
float cosNO = dot(N, I);
296
float cosNI = dot(N, omega_in);
297
if(cosNO > 0 && cosNI > 0) {
299
float3 Hr = normalize(omega_in + I);
300
// eq. 20: (F*G*D)/(4*in*on)
301
// eq. 25: first we calculate D(m) with m=Hr:
302
float alpha2 = m_ab * m_ab;
303
float cosThetaM = dot(N, Hr);
304
float cosThetaM2 = cosThetaM * cosThetaM;
305
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
306
float cosThetaM4 = cosThetaM2 * cosThetaM2;
307
float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
308
// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
309
float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
310
float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
311
float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
312
float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
314
float out = (G * D) * 0.25f / cosNO;
316
float pm = D * cosThetaM;
317
// convert into pdf of the sampled direction
318
// eq. 38 - but see also:
319
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
320
*pdf = pm * 0.25f / dot(Hr, I);
321
return make_float3 (out, out, out);
323
return make_float3 (0, 0, 0);
326
__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
328
float m_ab = sc->data0;
329
float m_eta = sc->data1;
330
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
333
if(!m_refractive) return make_float3 (0, 0, 0);
334
float cosNO = dot(N, I);
335
float cosNI = dot(N, omega_in);
336
if(cosNO <= 0 || cosNI >= 0)
337
return make_float3 (0, 0, 0);
338
// compute half-vector of the refraction (eq. 16)
339
float3 ht = -(m_eta * omega_in + I);
340
float3 Ht = normalize(ht);
341
float cosHO = dot(Ht, I);
343
float cosHI = dot(Ht, omega_in);
344
// eq. 33: first we calculate D(m) with m=Ht:
345
float alpha2 = m_ab * m_ab;
346
float cosThetaM = dot(N, Ht);
347
float cosThetaM2 = cosThetaM * cosThetaM;
348
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
349
float cosThetaM4 = cosThetaM2 * cosThetaM2;
350
float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
351
// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
352
float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
353
float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
354
float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
355
float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
358
float invHt2 = 1 / dot(ht, ht);
359
*pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2;
360
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO;
361
return make_float3 (out, out, out);
364
__device int bsdf_microfacet_beckmann_sample(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)
366
float m_ab = sc->data0;
367
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
370
float cosNO = dot(N, I);
373
make_orthonormals(Z, &X, &Y);
374
// generate a random microfacet normal m
376
// we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
377
//tttt and sin(atan(x)) == x/sqrt(1+x^2)
378
float alpha2 = m_ab * m_ab;
379
float tanThetaM = safe_sqrtf(-alpha2 * logf(1 - randu));
380
float cosThetaM = 1 / safe_sqrtf(1 + tanThetaM * tanThetaM);
381
float sinThetaM = cosThetaM * tanThetaM;
382
float phiM = 2 * M_PI_F * randv;
383
float3 m = (cosf(phiM) * sinThetaM) * X +
384
(sinf(phiM) * sinThetaM) * Y +
388
float cosMO = dot(m, I);
390
// eq. 39 - compute actual reflected direction
391
*omega_in = 2 * cosMO * m - I;
392
if(dot(Ng, *omega_in) > 0) {
393
// microfacet normal is visible to this ray
395
float cosThetaM2 = cosThetaM * cosThetaM;
396
float tanThetaM2 = tanThetaM * tanThetaM;
397
float cosThetaM4 = cosThetaM2 * cosThetaM2;
398
float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
400
float pm = D * cosThetaM;
401
// convert into pdf of the sampled direction
402
// eq. 38 - but see also:
403
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
404
*pdf = pm * 0.25f / cosMO;
406
float cosNI = dot(N, *omega_in);
407
// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
408
float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
409
float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
410
float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
411
float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
413
// eq. 20: (F*G*D)/(4*in*on)
414
float out = (G * D) * 0.25f / cosNO;
415
*eval = make_float3(out, out, out);
416
#ifdef __RAY_DIFFERENTIALS__
417
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
418
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
424
// CAUTION: the i and o variables are inverted relative to the paper
425
// eq. 39 - compute actual refractive direction
427
#ifdef __RAY_DIFFERENTIALS__
428
float3 dRdx, dRdy, dTdx, dTdy;
430
float m_eta = sc->data1;
432
fresnel_dielectric(m_eta, m, I, &R, &T,
433
#ifdef __RAY_DIFFERENTIALS__
434
dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
440
#ifdef __RAY_DIFFERENTIALS__
441
*domega_in_dx = dTdx;
442
*domega_in_dy = dTdy;
446
float cosThetaM2 = cosThetaM * cosThetaM;
447
float tanThetaM2 = tanThetaM * tanThetaM;
448
float cosThetaM4 = cosThetaM2 * cosThetaM2;
449
float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
451
float pm = D * cosThetaM;
453
float cosNI = dot(N, *omega_in);
454
// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
455
float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
456
float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
457
float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
458
float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
461
float cosHI = dot(m, *omega_in);
462
float cosHO = dot(m, I);
463
float Ht2 = m_eta * cosHI + cosHO;
465
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
467
*pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
468
*eval = make_float3(out, out, out);
472
return (m_refractive) ? LABEL_TRANSMIT|LABEL_GLOSSY : LABEL_REFLECT|LABEL_GLOSSY;
477
#endif /* __BSDF_MICROFACET_H__ */