Fix T54317: overlapping volume render bug after recent changes.
[blender-staging.git] / intern / cycles / kernel / kernel_path_surface.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 #if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) || defined(__SHADOW_TRICKS__) || defined(__BAKING__)
20 /* branched path tracing: connect path directly to position on one or more lights and add it to L */
21 ccl_device_noinline void kernel_branched_path_surface_connect_light(
22         KernelGlobals *kg,
23         ShaderData *sd,
24         ShaderData *emission_sd,
25         ccl_addr_space PathState *state,
26         float3 throughput,
27         float num_samples_adjust,
28         PathRadiance *L,
29         int sample_all_lights)
30 {
31 #ifdef __EMISSION__
32         /* sample illumination from lights to find path contribution */
33         if(!(sd->flag & SD_BSDF_HAS_EVAL))
34                 return;
35
36         Ray light_ray;
37         BsdfEval L_light;
38         bool is_lamp;
39
40 #  ifdef __OBJECT_MOTION__
41         light_ray.time = sd->time;
42 #  endif
43
44         if(sample_all_lights) {
45                 /* lamp sampling */
46                 for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
47                         if(UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
48                                 continue;
49
50                         int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
51                         float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
52                         uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
53
54                         for(int j = 0; j < num_samples; j++) {
55                                 float light_u, light_v;
56                                 path_branched_rng_2D(kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
57                                 float terminate = path_branched_rng_light_termination(kg, lamp_rng_hash, state, j, num_samples);
58
59                                 LightSample ls;
60                                 if(lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) {
61                                         /* The sampling probability returned by lamp_light_sample assumes that all lights were sampled.
62                                          * However, this code only samples lamps, so if the scene also had mesh lights, the real probability is twice as high. */
63                                         if(kernel_data.integrator.pdf_triangles != 0.0f)
64                                                 ls.pdf *= 2.0f;
65
66                                         if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
67                                                 /* trace shadow ray */
68                                                 float3 shadow;
69
70                                                 if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
71                                                         /* accumulate */
72                                                         path_radiance_accum_light(L, state, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
73                                                 }
74                                                 else {
75                                                         path_radiance_accum_total_light(L, state, throughput*num_samples_inv, &L_light);
76                                                 }
77                                         }
78                                 }
79                         }
80                 }
81
82                 /* mesh light sampling */
83                 if(kernel_data.integrator.pdf_triangles != 0.0f) {
84                         int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples);
85                         float num_samples_inv = num_samples_adjust/num_samples;
86
87                         for(int j = 0; j < num_samples; j++) {
88                                 float light_u, light_v;
89                                 path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
90                                 float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples);
91
92                                 /* only sample triangle lights */
93                                 if(kernel_data.integrator.num_all_lights)
94                                         light_u = 0.5f*light_u;
95
96                                 LightSample ls;
97                                 if(light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
98                                         /* Same as above, probability needs to be corrected since the sampling was forced to select a mesh light. */
99                                         if(kernel_data.integrator.num_all_lights)
100                                                 ls.pdf *= 2.0f;
101
102                                         if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
103                                                 /* trace shadow ray */
104                                                 float3 shadow;
105
106                                                 if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
107                                                         /* accumulate */
108                                                         path_radiance_accum_light(L, state, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
109                                                 }
110                                                 else {
111                                                         path_radiance_accum_total_light(L, state, throughput*num_samples_inv, &L_light);
112                                                 }
113                                         }
114                                 }
115                         }
116                 }
117         }
118         else {
119                 /* sample one light at random */
120                 float light_u, light_v;
121                 path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
122                 float terminate = path_state_rng_light_termination(kg, state);
123
124                 LightSample ls;
125                 if(light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
126                         /* sample random light */
127                         if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
128                                 /* trace shadow ray */
129                                 float3 shadow;
130
131                                 if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
132                                         /* accumulate */
133                                         path_radiance_accum_light(L, state, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, is_lamp);
134                                 }
135                                 else {
136                                         path_radiance_accum_total_light(L, state, throughput*num_samples_adjust, &L_light);
137                                 }
138                         }
139                 }
140         }
141 #endif
142 }
143
144 /* branched path tracing: bounce off or through surface to with new direction stored in ray */
145 ccl_device bool kernel_branched_path_surface_bounce(
146         KernelGlobals *kg,
147         ShaderData *sd,
148         const ShaderClosure *sc,
149         int sample,
150         int num_samples,
151         ccl_addr_space float3 *throughput,
152         ccl_addr_space PathState *state,
153         PathRadianceState *L_state,
154         ccl_addr_space Ray *ray,
155         float sum_sample_weight)
156 {
157         /* sample BSDF */
158         float bsdf_pdf;
159         BsdfEval bsdf_eval;
160         float3 bsdf_omega_in;
161         differential3 bsdf_domega_in;
162         float bsdf_u, bsdf_v;
163         path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
164         int label;
165
166         label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval,
167                 &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
168
169         if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
170                 return false;
171
172         /* modify throughput */
173         path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
174
175 #ifdef __DENOISING_FEATURES__
176         state->denoising_feature_weight *= sc->sample_weight / (sum_sample_weight * num_samples);
177 #endif
178
179         /* modify path state */
180         path_state_next(kg, state, label);
181
182         /* setup ray */
183         ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng);
184         ray->D = normalize(bsdf_omega_in);
185         ray->t = FLT_MAX;
186 #ifdef __RAY_DIFFERENTIALS__
187         ray->dP = sd->dP;
188         ray->dD = bsdf_domega_in;
189 #endif
190 #ifdef __OBJECT_MOTION__
191         ray->time = sd->time;
192 #endif
193
194 #ifdef __VOLUME__
195         /* enter/exit volume */
196         if(label & LABEL_TRANSMIT)
197                 kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
198 #endif
199
200         /* branch RNG state */
201         path_state_branch(state, sample, num_samples);
202
203         /* set MIS state */
204         state->min_ray_pdf = fminf(bsdf_pdf, FLT_MAX);
205         state->ray_pdf = bsdf_pdf;
206 #ifdef __LAMP_MIS__
207         state->ray_t = 0.0f;
208 #endif
209
210         return true;
211 }
212
213 #endif
214
215 /* path tracing: connect path directly to position on a light and add it to L */
216 ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg,
217         ShaderData *sd, ShaderData *emission_sd, float3 throughput, ccl_addr_space PathState *state,
218         PathRadiance *L)
219 {
220 #ifdef __EMISSION__
221         if(!(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)))
222                 return;
223
224 #ifdef __SHADOW_TRICKS__
225         if(state->flag & PATH_RAY_SHADOW_CATCHER) {
226                 kernel_branched_path_surface_connect_light(kg,
227                                                            sd,
228                                                            emission_sd,
229                                                            state,
230                                                            throughput,
231                                                            1.0f,
232                                                            L,
233                                                            1);
234                 return;
235         }
236 #endif
237
238         /* sample illumination from lights to find path contribution */
239         float light_u, light_v;
240         path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
241
242         Ray light_ray;
243         BsdfEval L_light;
244         bool is_lamp;
245
246 #ifdef __OBJECT_MOTION__
247         light_ray.time = sd->time;
248 #endif
249
250         LightSample ls;
251         if(light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
252                 float terminate = path_state_rng_light_termination(kg, state);
253                 if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
254                         /* trace shadow ray */
255                         float3 shadow;
256
257                         if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
258                                 /* accumulate */
259                                 path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
260                         }
261                         else {
262                                 path_radiance_accum_total_light(L, state, throughput, &L_light);
263                         }
264                 }
265         }
266 #endif
267 }
268
269 /* path tracing: bounce off or through surface to with new direction stored in ray */
270 ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
271                                            ShaderData *sd,
272                                            ccl_addr_space float3 *throughput,
273                                            ccl_addr_space PathState *state,
274                                            PathRadianceState *L_state,
275                                            ccl_addr_space Ray *ray)
276 {
277         /* no BSDF? we can stop here */
278         if(sd->flag & SD_BSDF) {
279                 /* sample BSDF */
280                 float bsdf_pdf;
281                 BsdfEval bsdf_eval;
282                 float3 bsdf_omega_in;
283                 differential3 bsdf_domega_in;
284                 float bsdf_u, bsdf_v;
285                 path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
286                 int label;
287
288                 label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval,
289                         &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
290
291                 if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
292                         return false;
293
294                 /* modify throughput */
295                 path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
296
297                 /* set labels */
298                 if(!(label & LABEL_TRANSPARENT)) {
299                         state->ray_pdf = bsdf_pdf;
300 #ifdef __LAMP_MIS__
301                         state->ray_t = 0.0f;
302 #endif
303                         state->min_ray_pdf = fminf(bsdf_pdf, state->min_ray_pdf);
304                 }
305
306                 /* update path state */
307                 path_state_next(kg, state, label);
308
309                 /* setup ray */
310                 ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng);
311                 ray->D = normalize(bsdf_omega_in);
312
313                 if(state->bounce == 0)
314                         ray->t -= sd->ray_length; /* clipping works through transparent */
315                 else
316                         ray->t = FLT_MAX;
317
318 #ifdef __RAY_DIFFERENTIALS__
319                 ray->dP = sd->dP;
320                 ray->dD = bsdf_domega_in;
321 #endif
322
323 #ifdef __VOLUME__
324                 /* enter/exit volume */
325                 if(label & LABEL_TRANSMIT)
326                         kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
327 #endif
328                 return true;
329         }
330 #ifdef __VOLUME__
331         else if(sd->flag & SD_HAS_ONLY_VOLUME) {
332                 if(!path_state_volume_next(kg, state)) {
333                         return false;
334                 }
335
336                 if(state->bounce == 0)
337                         ray->t -= sd->ray_length; /* clipping works through transparent */
338                 else
339                         ray->t = FLT_MAX;
340
341                 /* setup ray position, direction stays unchanged */
342                 ray->P = ray_offset(sd->P, -sd->Ng);
343 #ifdef __RAY_DIFFERENTIALS__
344                 ray->dP = sd->dP;
345 #endif
346
347                 /* enter/exit volume */
348                 kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
349                 return true;
350         }
351 #endif
352         else {
353                 /* no bsdf or volume? */
354                 return false;
355         }
356 }
357
358 CCL_NAMESPACE_END
359