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