ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / kernel / kernel_path_volume.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 #ifdef __VOLUME_SCATTER__
20
21 ccl_device_inline void kernel_path_volume_connect_light(KernelGlobals *kg,
22                                                         ShaderData *sd,
23                                                         ShaderData *emission_sd,
24                                                         float3 throughput,
25                                                         ccl_addr_space PathState *state,
26                                                         PathRadiance *L)
27 {
28 #  ifdef __EMISSION__
29   if (!kernel_data.integrator.use_direct_light)
30     return;
31
32   /* sample illumination from lights to find path contribution */
33   float light_u, light_v;
34   path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
35
36   Ray light_ray;
37   BsdfEval L_light;
38   LightSample ls;
39   bool is_lamp;
40
41   /* connect to light from given point where shader has been evaluated */
42   light_ray.time = sd->time;
43
44   if (light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
45     float terminate = path_state_rng_light_termination(kg, state);
46     if (direct_emission(
47             kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
48       /* trace shadow ray */
49       float3 shadow;
50
51       if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
52         /* accumulate */
53         path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
54       }
55     }
56   }
57 #  endif /* __EMISSION__ */
58 }
59
60 #  ifdef __KERNEL_GPU__
61 ccl_device_noinline
62 #  else
63 ccl_device
64 #  endif
65     bool
66     kernel_path_volume_bounce(KernelGlobals *kg,
67                               ShaderData *sd,
68                               ccl_addr_space float3 *throughput,
69                               ccl_addr_space PathState *state,
70                               PathRadianceState *L_state,
71                               ccl_addr_space Ray *ray)
72 {
73   /* sample phase function */
74   float phase_pdf;
75   BsdfEval phase_eval;
76   float3 phase_omega_in;
77   differential3 phase_domega_in;
78   float phase_u, phase_v;
79   path_state_rng_2D(kg, state, PRNG_BSDF_U, &phase_u, &phase_v);
80   int label;
81
82   label = shader_volume_phase_sample(
83       kg, sd, phase_u, phase_v, &phase_eval, &phase_omega_in, &phase_domega_in, &phase_pdf);
84
85   if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval))
86     return false;
87
88   /* modify throughput */
89   path_radiance_bsdf_bounce(kg, L_state, throughput, &phase_eval, phase_pdf, state->bounce, label);
90
91   /* set labels */
92   state->ray_pdf = phase_pdf;
93 #  ifdef __LAMP_MIS__
94   state->ray_t = 0.0f;
95 #  endif
96   state->min_ray_pdf = fminf(phase_pdf, state->min_ray_pdf);
97
98   /* update path state */
99   path_state_next(kg, state, label);
100
101   /* Russian roulette termination of volume ray scattering. */
102   float probability = path_state_continuation_probability(kg, state, *throughput);
103
104   if (probability == 0.0f) {
105     return false;
106   }
107   else if (probability != 1.0f) {
108     /* Use dimension from the previous bounce, has not been used yet. */
109     float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE - PRNG_BOUNCE_NUM);
110
111     if (terminate >= probability) {
112       return false;
113     }
114
115     *throughput /= probability;
116   }
117
118   /* setup ray */
119   ray->P = sd->P;
120   ray->D = phase_omega_in;
121   ray->t = FLT_MAX;
122
123 #  ifdef __RAY_DIFFERENTIALS__
124   ray->dP = sd->dP;
125   ray->dD = phase_domega_in;
126 #  endif
127
128   return true;
129 }
130
131 #  ifndef __SPLIT_KERNEL__
132 ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg,
133                                                           ShaderData *sd,
134                                                           ShaderData *emission_sd,
135                                                           float3 throughput,
136                                                           ccl_addr_space PathState *state,
137                                                           PathRadiance *L,
138                                                           bool sample_all_lights,
139                                                           Ray *ray,
140                                                           const VolumeSegment *segment)
141 {
142 #    ifdef __EMISSION__
143   if (!kernel_data.integrator.use_direct_light)
144     return;
145
146   Ray light_ray;
147   BsdfEval L_light;
148   bool is_lamp;
149
150   light_ray.time = sd->time;
151
152   if (sample_all_lights) {
153     /* lamp sampling */
154     for (int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
155       if (UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
156         continue;
157
158       int num_samples = light_select_num_samples(kg, i);
159       float num_samples_inv = 1.0f / (num_samples * kernel_data.integrator.num_all_lights);
160       uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
161
162       for (int j = 0; j < num_samples; j++) {
163         /* sample random position on given light */
164         float light_u, light_v;
165         path_branched_rng_2D(
166             kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
167
168         LightSample ls;
169         lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls);
170
171         float3 tp = throughput;
172
173         /* sample position on volume segment */
174         float rphase = path_branched_rng_1D(
175             kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
176         float rscatter = path_branched_rng_1D(
177             kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
178
179         VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
180                                                                        state,
181                                                                        ray,
182                                                                        sd,
183                                                                        &tp,
184                                                                        rphase,
185                                                                        rscatter,
186                                                                        segment,
187                                                                        (ls.t != FLT_MAX) ? &ls.P :
188                                                                                            NULL,
189                                                                        false);
190
191         /* todo: split up light_sample so we don't have to call it again with new position */
192         if (result == VOLUME_PATH_SCATTERED &&
193             lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) {
194           if (kernel_data.integrator.pdf_triangles != 0.0f)
195             ls.pdf *= 2.0f;
196
197           float terminate = path_branched_rng_light_termination(
198               kg, state->rng_hash, state, j, num_samples);
199           if (direct_emission(
200                   kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
201             /* trace shadow ray */
202             float3 shadow;
203
204             if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
205               /* accumulate */
206               path_radiance_accum_light(
207                   L, state, tp * num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
208             }
209           }
210         }
211       }
212     }
213
214     /* mesh light sampling */
215     if (kernel_data.integrator.pdf_triangles != 0.0f) {
216       int num_samples = kernel_data.integrator.mesh_light_samples;
217       float num_samples_inv = 1.0f / num_samples;
218
219       for (int j = 0; j < num_samples; j++) {
220         /* sample random position on random triangle */
221         float light_u, light_v;
222         path_branched_rng_2D(
223             kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
224
225         /* only sample triangle lights */
226         if (kernel_data.integrator.num_all_lights)
227           light_u = 0.5f * light_u;
228
229         LightSample ls;
230         light_sample(kg, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
231
232         float3 tp = throughput;
233
234         /* sample position on volume segment */
235         float rphase = path_branched_rng_1D(
236             kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
237         float rscatter = path_branched_rng_1D(
238             kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
239
240         VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
241                                                                        state,
242                                                                        ray,
243                                                                        sd,
244                                                                        &tp,
245                                                                        rphase,
246                                                                        rscatter,
247                                                                        segment,
248                                                                        (ls.t != FLT_MAX) ? &ls.P :
249                                                                                            NULL,
250                                                                        false);
251
252         /* todo: split up light_sample so we don't have to call it again with new position */
253         if (result == VOLUME_PATH_SCATTERED &&
254             light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
255           if (kernel_data.integrator.num_all_lights)
256             ls.pdf *= 2.0f;
257
258           float terminate = path_branched_rng_light_termination(
259               kg, state->rng_hash, state, j, num_samples);
260           if (direct_emission(
261                   kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
262             /* trace shadow ray */
263             float3 shadow;
264
265             if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
266               /* accumulate */
267               path_radiance_accum_light(
268                   L, state, tp * num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp);
269             }
270           }
271         }
272       }
273     }
274   }
275   else {
276     /* sample random position on random light */
277     float light_u, light_v;
278     path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
279
280     LightSample ls;
281     light_sample(kg, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
282
283     float3 tp = throughput;
284
285     /* sample position on volume segment */
286     float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
287     float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
288
289     VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
290                                                                    state,
291                                                                    ray,
292                                                                    sd,
293                                                                    &tp,
294                                                                    rphase,
295                                                                    rscatter,
296                                                                    segment,
297                                                                    (ls.t != FLT_MAX) ? &ls.P :
298                                                                                        NULL,
299                                                                    false);
300
301     /* todo: split up light_sample so we don't have to call it again with new position */
302     if (result == VOLUME_PATH_SCATTERED &&
303         light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
304       /* sample random light */
305       float terminate = path_state_rng_light_termination(kg, state);
306       if (direct_emission(
307               kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
308         /* trace shadow ray */
309         float3 shadow;
310
311         if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow)) {
312           /* accumulate */
313           path_radiance_accum_light(L, state, tp, &L_light, shadow, 1.0f, is_lamp);
314         }
315       }
316     }
317   }
318 #    endif /* __EMISSION__ */
319 }
320 #  endif /* __SPLIT_KERNEL__ */
321
322 #endif /* __VOLUME_SCATTER__ */
323
324 CCL_NAMESPACE_END