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