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