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