Cycles: Remove few function arguments needed only for the split kernel
[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 ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
21                                                 LightSample *ls,
22                                                 ccl_addr_space PathState *state,
23                                                 float3 I,
24                                                 differential3 dI,
25                                                 float t,
26                                                 float time)
27 {
28         /* setup shading at emitter */
29 #ifdef __SPLIT_KERNEL__
30         ShaderData *sd = kg->sd_input;
31 #else
32         ShaderData sd_object;
33         ShaderData *sd = &sd_object;
34 #endif
35         float3 eval;
36
37 #ifdef __BACKGROUND_MIS__
38         if(ls->type == LIGHT_BACKGROUND) {
39                 Ray ray;
40                 ray.D = ls->D;
41                 ray.P = ls->P;
42                 ray.t = 1.0f;
43 #ifdef __OBJECT_MOTION__
44                 ray.time = time;
45 #endif
46                 ray.dP = differential3_zero();
47                 ray.dD = dI;
48
49                 shader_setup_from_background(kg, sd, &ray);
50
51                 path_state_modify_bounce(state, true);
52                 eval = shader_eval_background(kg, sd, state, 0, SHADER_CONTEXT_EMISSION);
53                 path_state_modify_bounce(state, false);
54         }
55         else
56 #endif
57         {
58                 shader_setup_from_sample(kg, sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time);
59
60                 ls->Ng = ccl_fetch(sd, Ng);
61
62                 /* no path flag, we're evaluating this for all closures. that's weak but
63                  * we'd have to do multiple evaluations otherwise */
64                 path_state_modify_bounce(state, true);
65                 shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_EMISSION);
66                 path_state_modify_bounce(state, false);
67
68                 /* evaluate emissive closure */
69                 if(ccl_fetch(sd, flag) & SD_EMISSION)
70                         eval = shader_emissive_eval(kg, sd);
71                 else
72                         eval = make_float3(0.0f, 0.0f, 0.0f);
73         }
74         
75         eval *= ls->eval_fac;
76
77         return eval;
78 }
79
80 ccl_device_noinline bool direct_emission(KernelGlobals *kg,
81                                          ShaderData *sd,
82                                          LightSample *ls,
83                                          ccl_addr_space PathState *state,
84                                          Ray *ray,
85                                          BsdfEval *eval,
86                                          bool *is_lamp)
87 {
88         if(ls->pdf == 0.0f)
89                 return false;
90
91         /* todo: implement */
92         differential3 dD = differential3_zero();
93
94         /* evaluate closure */
95
96         float3 light_eval = direct_emissive_eval(kg,
97                                                  ls,
98                                                  state,
99                                                  -ls->D,
100                                                  dD,
101                                                  ls->t,
102                                                  ccl_fetch(sd, time));
103
104         if(is_zero(light_eval))
105                 return false;
106
107         /* evaluate BSDF at shading point */
108
109 #ifdef __VOLUME__
110         if(ccl_fetch(sd, prim) != PRIM_NONE)
111                 shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
112         else {
113                 float bsdf_pdf;
114                 shader_volume_phase_eval(kg, sd, ls->D, eval, &bsdf_pdf);
115                 if(ls->shader & SHADER_USE_MIS) {
116                         /* Multiple importance sampling. */
117                         float mis_weight = power_heuristic(ls->pdf, bsdf_pdf);
118                         light_eval *= mis_weight;
119                 }
120         }
121 #else
122         shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
123 #endif
124
125         bsdf_eval_mul(eval, light_eval/ls->pdf);
126
127 #ifdef __PASSES__
128         /* use visibility flag to skip lights */
129         if(ls->shader & SHADER_EXCLUDE_ANY) {
130                 if(ls->shader & SHADER_EXCLUDE_DIFFUSE)
131                         eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
132                 if(ls->shader & SHADER_EXCLUDE_GLOSSY)
133                         eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
134                 if(ls->shader & SHADER_EXCLUDE_TRANSMIT)
135                         eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
136                 if(ls->shader & SHADER_EXCLUDE_SCATTER)
137                         eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
138         }
139 #endif
140
141         if(bsdf_eval_is_zero(eval))
142                 return false;
143
144         if(ls->shader & SHADER_CAST_SHADOW) {
145                 /* setup ray */
146                 bool transmit = (dot(ccl_fetch(sd, Ng), ls->D) < 0.0f);
147                 ray->P = ray_offset(ccl_fetch(sd, P), (transmit)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng));
148
149                 if(ls->t == FLT_MAX) {
150                         /* distant light */
151                         ray->D = ls->D;
152                         ray->t = ls->t;
153                 }
154                 else {
155                         /* other lights, avoid self-intersection */
156                         ray->D = ray_offset(ls->P, ls->Ng) - ray->P;
157                         ray->D = normalize_len(ray->D, &ray->t);
158                 }
159
160                 ray->dP = ccl_fetch(sd, dP);
161                 ray->dD = differential3_zero();
162         }
163         else {
164                 /* signal to not cast shadow ray */
165                 ray->t = 0.0f;
166         }
167
168         /* return if it's a lamp for shadow pass */
169         *is_lamp = (ls->prim == PRIM_NONE && ls->type != LIGHT_BACKGROUND);
170
171         return true;
172 }
173
174 /* Indirect Primitive Emission */
175
176 ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
177 {
178         /* evaluate emissive closure */
179         float3 L = shader_emissive_eval(kg, sd);
180
181 #ifdef __HAIR__
182         if(!(path_flag & PATH_RAY_MIS_SKIP) && (ccl_fetch(sd, flag) & SD_USE_MIS) && (ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE))
183 #else
184         if(!(path_flag & PATH_RAY_MIS_SKIP) && (ccl_fetch(sd, flag) & SD_USE_MIS))
185 #endif
186         {
187                 /* multiple importance sampling, get triangle light pdf,
188                  * and compute weight with respect to BSDF pdf */
189                 float pdf = triangle_light_pdf(kg, ccl_fetch(sd, Ng), ccl_fetch(sd, I), t);
190                 float mis_weight = power_heuristic(bsdf_pdf, pdf);
191
192                 return L*mis_weight;
193         }
194
195         return L;
196 }
197
198 /* Indirect Lamp Emission */
199
200 ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg,
201                                                 ccl_addr_space PathState *state,
202                                                 Ray *ray,
203                                                 float3 *emission)
204 {
205         bool hit_lamp = false;
206
207         *emission = make_float3(0.0f, 0.0f, 0.0f);
208
209         for(int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
210                 LightSample ls;
211
212                 if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
213                         continue;
214
215 #ifdef __PASSES__
216                 /* use visibility flag to skip lights */
217                 if(ls.shader & SHADER_EXCLUDE_ANY) {
218                         if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
219                            ((ls.shader & SHADER_EXCLUDE_GLOSSY) &&
220                             ((state->flag & (PATH_RAY_GLOSSY|PATH_RAY_REFLECT)) == (PATH_RAY_GLOSSY|PATH_RAY_REFLECT))) ||
221                            ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
222                            ((ls.shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
223                                 continue;
224                 }
225 #endif
226
227                 float3 L = direct_emissive_eval(kg,
228                                                 &ls,
229                                                 state,
230                                                 -ray->D,
231                                                 ray->dD,
232                                                 ls.t,
233                                                 ray->time);
234
235 #ifdef __VOLUME__
236                 if(state->volume_stack[0].shader != SHADER_NONE) {
237                         /* shadow attenuation */
238                         Ray volume_ray = *ray;
239                         volume_ray.t = ls.t;
240                         float3 volume_tp = make_float3(1.0f, 1.0f, 1.0f);
241                         kernel_volume_shadow(kg, state, &volume_ray, &volume_tp);
242                         L *= volume_tp;
243                 }
244 #endif
245
246                 if(!(state->flag & PATH_RAY_MIS_SKIP)) {
247                         /* multiple importance sampling, get regular light pdf,
248                          * and compute weight with respect to BSDF pdf */
249                         float mis_weight = power_heuristic(state->ray_pdf, ls.pdf);
250                         L *= mis_weight;
251                 }
252
253                 *emission += L;
254                 hit_lamp = true;
255         }
256
257         return hit_lamp;
258 }
259
260 /* Indirect Background */
261
262 ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
263                                                ccl_addr_space PathState *state,
264                                                ccl_addr_space Ray *ray)
265 {
266 #ifdef __BACKGROUND__
267         int shader = kernel_data.background.surface_shader;
268
269         /* use visibility flag to skip lights */
270         if(shader & SHADER_EXCLUDE_ANY) {
271                 if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
272                    ((shader & SHADER_EXCLUDE_GLOSSY) &&
273                     ((state->flag & (PATH_RAY_GLOSSY|PATH_RAY_REFLECT)) == (PATH_RAY_GLOSSY|PATH_RAY_REFLECT))) ||
274                    ((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
275                    ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)) ||
276                    ((shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
277                         return make_float3(0.0f, 0.0f, 0.0f);
278         }
279
280         /* evaluate background closure */
281 #ifdef __SPLIT_KERNEL__
282         Ray priv_ray = *ray;
283         shader_setup_from_background(kg, kg->sd_input, &priv_ray);
284
285         path_state_modify_bounce(state, true);
286         float3 L = shader_eval_background(kg, kg->sd_input, state, state->flag, SHADER_CONTEXT_EMISSION);
287         path_state_modify_bounce(state, false);
288 #else
289         ShaderData sd;
290         shader_setup_from_background(kg, &sd, ray);
291
292         path_state_modify_bounce(state, true);
293         float3 L = shader_eval_background(kg, &sd, state, state->flag, SHADER_CONTEXT_EMISSION);
294         path_state_modify_bounce(state, false);
295 #endif
296
297 #ifdef __BACKGROUND_MIS__
298         /* check if background light exists or if we should skip pdf */
299         int res = kernel_data.integrator.pdf_background_res;
300
301         if(!(state->flag & PATH_RAY_MIS_SKIP) && res) {
302                 /* multiple importance sampling, get background light pdf for ray
303                  * direction, and compute weight with respect to BSDF pdf */
304                 float pdf = background_light_pdf(kg, ray->P, ray->D);
305                 float mis_weight = power_heuristic(state->ray_pdf, pdf);
306
307                 return L*mis_weight;
308         }
309 #endif
310
311         return L;
312 #else
313         return make_float3(0.8f, 0.8f, 0.8f);
314 #endif
315 }
316
317 CCL_NAMESPACE_END
318