Cycles: better path termination for transparency.
[blender.git] / intern / cycles / kernel / closure / bsdf_principled_sheen.h
1 /*
2  * Copyright 2011-2017 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_PRINCIPLED_SHEEN_H__
18 #define __BSDF_PRINCIPLED_SHEEN_H__
19
20 /* DISNEY PRINCIPLED SHEEN BRDF
21  *
22  * Shading model by Brent Burley (Disney): "Physically Based Shading at Disney" (2012)
23  */
24
25 CCL_NAMESPACE_BEGIN
26
27 typedef ccl_addr_space struct PrincipledSheenBsdf {
28         SHADER_CLOSURE_BASE;
29 } PrincipledSheenBsdf;
30
31 ccl_device float3 calculate_principled_sheen_brdf(const PrincipledSheenBsdf *bsdf,
32         float3 N, float3 V, float3 L, float3 H, float *pdf)
33 {
34         float NdotL = dot(N, L);
35         float NdotV = dot(N, V);
36
37         if(NdotL < 0 || NdotV < 0) {
38                 *pdf = 0.0f;
39                 return make_float3(0.0f, 0.0f, 0.0f);
40         }
41
42         float LdotH = dot(L, H);
43
44         float value = schlick_fresnel(LdotH) * NdotL;
45
46         return make_float3(value, value, value);
47 }
48
49 ccl_device int bsdf_principled_sheen_setup(PrincipledSheenBsdf *bsdf)
50 {
51         bsdf->type = CLOSURE_BSDF_PRINCIPLED_SHEEN_ID;
52         return SD_BSDF|SD_BSDF_HAS_EVAL;
53 }
54
55 ccl_device float3 bsdf_principled_sheen_eval_reflect(const ShaderClosure *sc, const float3 I,
56         const float3 omega_in, float *pdf)
57 {
58         const PrincipledSheenBsdf *bsdf = (const PrincipledSheenBsdf *)sc;
59
60         float3 N = bsdf->N;
61         float3 V = I; // outgoing
62         float3 L = omega_in; // incoming
63         float3 H = normalize(L + V);
64
65         if(dot(N, omega_in) > 0.0f) {
66                 *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
67                 return calculate_principled_sheen_brdf(bsdf, N, V, L, H, pdf);
68         }
69         else {
70                 *pdf = 0.0f;
71                 return make_float3(0.0f, 0.0f, 0.0f);
72         }
73 }
74
75 ccl_device float3 bsdf_principled_sheen_eval_transmit(const ShaderClosure *sc, const float3 I,
76         const float3 omega_in, float *pdf)
77 {
78         return make_float3(0.0f, 0.0f, 0.0f);
79 }
80
81 ccl_device int bsdf_principled_sheen_sample(const ShaderClosure *sc,
82         float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
83         float3 *eval, float3 *omega_in, float3 *domega_in_dx,
84         float3 *domega_in_dy, float *pdf)
85 {
86         const PrincipledSheenBsdf *bsdf = (const PrincipledSheenBsdf *)sc;
87
88         float3 N = bsdf->N;
89
90         sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
91
92         if(dot(Ng, *omega_in) > 0) {
93                 float3 H = normalize(I + *omega_in);
94
95                 *eval = calculate_principled_sheen_brdf(bsdf, N, I, *omega_in, H, pdf);
96
97 #ifdef __RAY_DIFFERENTIALS__
98                 // TODO: find a better approximation for the diffuse bounce
99                 *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
100                 *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
101 #endif
102         }
103         else {
104                 *pdf = 0.0f;
105         }
106         return LABEL_REFLECT|LABEL_DIFFUSE;
107 }
108
109 CCL_NAMESPACE_END
110
111 #endif /* __BSDF_PRINCIPLED_SHEEN_H__ */
112
113