Cycles: change __device and similar qualifiers to ccl_device in kernel code.
[blender.git] / intern / cycles / kernel / kernel_emission.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 CCL_NAMESPACE_BEGIN
18
19 /* Direction Emission */
20
21 ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
22         LightSample *ls, float u, float v, float3 I, differential3 dI, float t, float time, int bounce)
23 {
24         /* setup shading at emitter */
25         ShaderData sd;
26         float3 eval;
27
28 #ifdef __BACKGROUND_MIS__
29         if(ls->type == LIGHT_BACKGROUND) {
30                 Ray ray;
31                 ray.D = ls->D;
32                 ray.P = ls->P;
33                 ray.t = 1.0f;
34 #ifdef __OBJECT_MOTION__
35                 ray.time = time;
36 #endif
37                 ray.dP = differential3_zero();
38                 ray.dD = dI;
39 #ifdef __CAMERA_MOTION__
40                 ray.time = time;
41 #endif
42                 shader_setup_from_background(kg, &sd, &ray, bounce+1);
43                 eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
44         }
45         else
46 #endif
47         {
48 #ifdef __HAIR__
49                 if(ls->type == LIGHT_STRAND)
50                         shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time, bounce+1, ls->prim);
51                 else
52 #endif
53                         shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time, bounce+1, ~0);
54
55                 ls->Ng = sd.Ng;
56
57                 /* no path flag, we're evaluating this for all closures. that's weak but
58                  * we'd have to do multiple evaluations otherwise */
59                 shader_eval_surface(kg, &sd, rando, 0, SHADER_CONTEXT_EMISSION);
60
61                 /* evaluate emissive closure */
62                 if(sd.flag & SD_EMISSION)
63                         eval = shader_emissive_eval(kg, &sd);
64                 else
65                         eval = make_float3(0.0f, 0.0f, 0.0f);
66         }
67         
68         eval *= ls->eval_fac;
69
70         return eval;
71 }
72
73 ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
74         float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval,
75         bool *is_lamp, int bounce)
76 {
77         LightSample ls;
78
79 #ifdef __BRANCHED_PATH__
80         if(lindex != -1) {
81                 /* sample position on a specified light */
82                 light_select(kg, lindex, randu, randv, sd->P, &ls);
83         }
84         else
85 #endif
86         {
87                 /* sample a light and position on int */
88                 light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls);
89         }
90
91         if(ls.pdf == 0.0f)
92                 return false;
93
94         /* todo: implement */
95         differential3 dD = differential3_zero();
96
97         /* evaluate closure */
98         float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D, dD, ls.t, sd->time, bounce);
99
100         if(is_zero(light_eval))
101                 return false;
102
103         /* evaluate BSDF at shading point */
104         float bsdf_pdf;
105
106         shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf);
107
108         if(ls.shader & SHADER_USE_MIS) {
109                 /* multiple importance sampling */
110                 float mis_weight = power_heuristic(ls.pdf, bsdf_pdf);
111                 light_eval *= mis_weight;
112         }
113         
114         bsdf_eval_mul(eval, light_eval/ls.pdf);
115
116 #ifdef __PASSES__
117         /* use visibility flag to skip lights */
118         if(ls.shader & SHADER_EXCLUDE_ANY) {
119                 if(ls.shader & SHADER_EXCLUDE_DIFFUSE)
120                         eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
121                 if(ls.shader & SHADER_EXCLUDE_GLOSSY)
122                         eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
123                 if(ls.shader & SHADER_EXCLUDE_TRANSMIT)
124                         eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
125         }
126 #endif
127
128         if(bsdf_eval_is_zero(eval))
129                 return false;
130
131         if(ls.shader & SHADER_CAST_SHADOW) {
132                 /* setup ray */
133                 bool transmit = (dot(sd->Ng, ls.D) < 0.0f);
134                 ray->P = ray_offset(sd->P, (transmit)? -sd->Ng: sd->Ng);
135
136                 if(ls.t == FLT_MAX) {
137                         /* distant light */
138                         ray->D = ls.D;
139                         ray->t = ls.t;
140                 }
141                 else {
142                         /* other lights, avoid self-intersection */
143                         ray->D = ray_offset(ls.P, ls.Ng) - ray->P;
144                         ray->D = normalize_len(ray->D, &ray->t);
145                 }
146
147                 ray->dP = sd->dP;
148                 ray->dD = differential3_zero();
149         }
150         else {
151                 /* signal to not cast shadow ray */
152                 ray->t = 0.0f;
153         }
154
155         /* return if it's a lamp for shadow pass */
156         *is_lamp = (ls.prim == ~0 && ls.type != LIGHT_BACKGROUND);
157
158         return true;
159 }
160
161 /* Indirect Primitive Emission */
162
163 ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
164 {
165         /* evaluate emissive closure */
166         float3 L = shader_emissive_eval(kg, sd);
167
168 #ifdef __HAIR__
169         if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->segment == ~0)) {
170 #else
171         if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS)) {
172 #endif
173                 /* multiple importance sampling, get triangle light pdf,
174                  * and compute weight with respect to BSDF pdf */
175                 float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t);
176                 float mis_weight = power_heuristic(bsdf_pdf, pdf);
177
178                 return L*mis_weight;
179         }
180
181         return L;
182 }
183
184 /* Indirect Lamp Emission */
185
186 ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission, int bounce)
187 {
188         LightSample ls;
189         int lamp = lamp_light_eval_sample(kg, randt);
190
191         if(lamp == ~0)
192                 return false;
193
194         if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
195                 return false;
196
197 #ifdef __PASSES__
198         /* use visibility flag to skip lights */
199         if(ls.shader & SHADER_EXCLUDE_ANY) {
200                 if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
201                    ((ls.shader & SHADER_EXCLUDE_GLOSSY) && (path_flag & PATH_RAY_GLOSSY)) ||
202                    ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)))
203                         return false;
204         }
205 #endif
206
207         /* todo: missing texture coordinates */
208         float u = 0.0f;
209         float v = 0.0f;
210         float3 L = direct_emissive_eval(kg, 0.0f, &ls, u, v, -ray->D, ray->dD, ls.t, ray->time, bounce);
211
212         if(!(path_flag & PATH_RAY_MIS_SKIP)) {
213                 /* multiple importance sampling, get regular light pdf,
214                  * and compute weight with respect to BSDF pdf */
215                 float mis_weight = power_heuristic(bsdf_pdf, ls.pdf);
216                 L *= mis_weight;
217         }
218
219         *emission = L;
220         return true;
221 }
222
223 /* Indirect Background */
224
225 ccl_device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, int bounce)
226 {
227 #ifdef __BACKGROUND__
228         int shader = kernel_data.background.shader;
229
230         /* use visibility flag to skip lights */
231         if(shader & SHADER_EXCLUDE_ANY) {
232                 if(((shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) ||
233                    ((shader & SHADER_EXCLUDE_GLOSSY) && (path_flag & PATH_RAY_GLOSSY)) ||
234                    ((shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
235                    ((shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)))
236                         return make_float3(0.0f, 0.0f, 0.0f);
237         }
238
239         /* evaluate background closure */
240         ShaderData sd;
241         shader_setup_from_background(kg, &sd, ray, bounce+1);
242
243         float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION);
244
245 #ifdef __BACKGROUND_MIS__
246         /* check if background light exists or if we should skip pdf */
247         int res = kernel_data.integrator.pdf_background_res;
248
249         if(!(path_flag & PATH_RAY_MIS_SKIP) && res) {
250                 /* multiple importance sampling, get background light pdf for ray
251                  * direction, and compute weight with respect to BSDF pdf */
252                 float pdf = background_light_pdf(kg, ray->D);
253                 float mis_weight = power_heuristic(bsdf_pdf, pdf);
254
255                 return L*mis_weight;
256         }
257 #endif
258
259         return L;
260 #else
261         return make_float3(0.8f, 0.8f, 0.8f);
262 #endif
263 }
264
265 CCL_NAMESPACE_END
266