ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / kernel / closure / bsdf_oren_nayar.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __BSDF_OREN_NAYAR_H__
18 #define __BSDF_OREN_NAYAR_H__
19
20 CCL_NAMESPACE_BEGIN
21
22 typedef ccl_addr_space struct OrenNayarBsdf {
23   SHADER_CLOSURE_BASE;
24
25   float roughness;
26   float a;
27   float b;
28 } OrenNayarBsdf;
29
30 ccl_device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc,
31                                                 float3 n,
32                                                 float3 v,
33                                                 float3 l)
34 {
35   const OrenNayarBsdf *bsdf = (const OrenNayarBsdf *)sc;
36   float nl = max(dot(n, l), 0.0f);
37   float nv = max(dot(n, v), 0.0f);
38   float t = dot(l, v) - nl * nv;
39
40   if (t > 0.0f)
41     t /= max(nl, nv) + FLT_MIN;
42   float is = nl * (bsdf->a + bsdf->b * t);
43   return make_float3(is, is, is);
44 }
45
46 ccl_device int bsdf_oren_nayar_setup(OrenNayarBsdf *bsdf)
47 {
48   float sigma = bsdf->roughness;
49
50   bsdf->type = CLOSURE_BSDF_OREN_NAYAR_ID;
51
52   sigma = saturate(sigma);
53
54   float div = 1.0f / (M_PI_F + ((3.0f * M_PI_F - 4.0f) / 6.0f) * sigma);
55
56   bsdf->a = 1.0f * div;
57   bsdf->b = sigma * div;
58
59   return SD_BSDF | SD_BSDF_HAS_EVAL;
60 }
61
62 ccl_device bool bsdf_oren_nayar_merge(const ShaderClosure *a, const ShaderClosure *b)
63 {
64   const OrenNayarBsdf *bsdf_a = (const OrenNayarBsdf *)a;
65   const OrenNayarBsdf *bsdf_b = (const OrenNayarBsdf *)b;
66
67   return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->roughness == bsdf_b->roughness);
68 }
69
70 ccl_device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc,
71                                                const float3 I,
72                                                const float3 omega_in,
73                                                float *pdf)
74 {
75   const OrenNayarBsdf *bsdf = (const OrenNayarBsdf *)sc;
76   if (dot(bsdf->N, omega_in) > 0.0f) {
77     *pdf = 0.5f * M_1_PI_F;
78     return bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, omega_in);
79   }
80   else {
81     *pdf = 0.0f;
82     return make_float3(0.0f, 0.0f, 0.0f);
83   }
84 }
85
86 ccl_device float3 bsdf_oren_nayar_eval_transmit(const ShaderClosure *sc,
87                                                 const float3 I,
88                                                 const float3 omega_in,
89                                                 float *pdf)
90 {
91   return make_float3(0.0f, 0.0f, 0.0f);
92 }
93
94 ccl_device int bsdf_oren_nayar_sample(const ShaderClosure *sc,
95                                       float3 Ng,
96                                       float3 I,
97                                       float3 dIdx,
98                                       float3 dIdy,
99                                       float randu,
100                                       float randv,
101                                       float3 *eval,
102                                       float3 *omega_in,
103                                       float3 *domega_in_dx,
104                                       float3 *domega_in_dy,
105                                       float *pdf)
106 {
107   const OrenNayarBsdf *bsdf = (const OrenNayarBsdf *)sc;
108   sample_uniform_hemisphere(bsdf->N, randu, randv, omega_in, pdf);
109
110   if (dot(Ng, *omega_in) > 0.0f) {
111     *eval = bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, *omega_in);
112
113 #ifdef __RAY_DIFFERENTIALS__
114     // TODO: find a better approximation for the bounce
115     *domega_in_dx = (2.0f * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
116     *domega_in_dy = (2.0f * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
117 #endif
118   }
119   else {
120     *pdf = 0.0f;
121     *eval = make_float3(0.0f, 0.0f, 0.0f);
122   }
123
124   return LABEL_REFLECT | LABEL_DIFFUSE;
125 }
126
127 CCL_NAMESPACE_END
128
129 #endif /* __BSDF_OREN_NAYAR_H__ */