Cycles: Remove few function arguments needed only for the split kernel
[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 void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
22         ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L)
23 {
24 #ifdef __EMISSION__
25         if(!kernel_data.integrator.use_direct_light)
26                 return;
27
28         /* sample illumination from lights to find path contribution */
29         float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
30         float light_u, light_v;
31         path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
32
33         Ray light_ray;
34         BsdfEval L_light;
35         LightSample ls;
36         bool is_lamp;
37
38         /* connect to light from given point where shader has been evaluated */
39 #ifdef __OBJECT_MOTION__
40         light_ray.time = sd->time;
41 #endif
42
43         light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
44         if(ls.pdf == 0.0f)
45                 return;
46         
47         if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) {
48                 /* trace shadow ray */
49                 float3 shadow;
50
51                 if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
52                         /* accumulate */
53                         path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp);
54                 }
55         }
56 #endif
57 }
58
59 #ifdef __KERNEL_GPU__
60 ccl_device_noinline
61 #else
62 ccl_device
63 #endif
64 bool kernel_path_volume_bounce(KernelGlobals *kg, RNG *rng,
65         ShaderData *sd, float3 *throughput, PathState *state, PathRadiance *L, Ray *ray)
66 {
67         /* sample phase function */
68         float phase_pdf;
69         BsdfEval phase_eval;
70         float3 phase_omega_in;
71         differential3 phase_domega_in;
72         float phase_u, phase_v;
73         path_state_rng_2D(kg, rng, state, PRNG_PHASE_U, &phase_u, &phase_v);
74         int label;
75
76         label = shader_volume_phase_sample(kg, sd, phase_u, phase_v, &phase_eval,
77                 &phase_omega_in, &phase_domega_in, &phase_pdf);
78
79         if(phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval))
80                 return false;
81         
82         /* modify throughput */
83         path_radiance_bsdf_bounce(L, throughput, &phase_eval, phase_pdf, state->bounce, label);
84
85         /* set labels */
86         state->ray_pdf = phase_pdf;
87 #ifdef __LAMP_MIS__
88         state->ray_t = 0.0f;
89 #endif
90         state->min_ray_pdf = fminf(phase_pdf, state->min_ray_pdf);
91
92         /* update path state */
93         path_state_next(kg, state, label);
94
95         /* setup ray */
96         ray->P = sd->P;
97         ray->D = phase_omega_in;
98         ray->t = FLT_MAX;
99
100 #ifdef __RAY_DIFFERENTIALS__
101         ray->dP = sd->dP;
102         ray->dD = phase_domega_in;
103 #endif
104
105         return true;
106 }
107
108 ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
109         ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L,
110         bool sample_all_lights, Ray *ray, const VolumeSegment *segment)
111 {
112 #ifdef __EMISSION__
113         if(!kernel_data.integrator.use_direct_light)
114                 return;
115
116         Ray light_ray;
117         BsdfEval L_light;
118         bool is_lamp;
119
120 #ifdef __OBJECT_MOTION__
121         light_ray.time = sd->time;
122 #endif
123
124         if(sample_all_lights) {
125                 /* lamp sampling */
126                 for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
127                         if(UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
128                                 continue;
129
130                         int num_samples = light_select_num_samples(kg, i);
131                         float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights);
132                         RNG lamp_rng = cmj_hash(*rng, i);
133
134                         if(kernel_data.integrator.pdf_triangles != 0.0f)
135                                 num_samples_inv *= 0.5f;
136
137                         for(int j = 0; j < num_samples; j++) {
138                                 /* sample random position on given light */
139                                 float light_u, light_v;
140                                 path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
141
142                                 LightSample ls;
143                                 lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls);                
144
145                                 float3 tp = throughput;
146
147                                 /* sample position on volume segment */
148                                 float rphase = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_PHASE);
149                                 float rscatter = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_SCATTER_DISTANCE);
150
151                                 VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
152                                         state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
153                                         
154                                 (void)result;
155                                 kernel_assert(result == VOLUME_PATH_SCATTERED);
156
157                                 /* todo: split up light_sample so we don't have to call it again with new position */
158                                 lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls);
159
160                                 if(ls.pdf == 0.0f)
161                                         continue;
162
163                                 if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) {
164                                         /* trace shadow ray */
165                                         float3 shadow;
166
167                                         if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
168                                                 /* accumulate */
169                                                 path_radiance_accum_light(L, tp*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
170                                         }
171                                 }
172                         }
173                 }
174
175                 /* mesh light sampling */
176                 if(kernel_data.integrator.pdf_triangles != 0.0f) {
177                         int num_samples = kernel_data.integrator.mesh_light_samples;
178                         float num_samples_inv = 1.0f/num_samples;
179
180                         if(kernel_data.integrator.num_all_lights)
181                                 num_samples_inv *= 0.5f;
182
183                         for(int j = 0; j < num_samples; j++) {
184                                 /* sample random position on random triangle */
185                                 float light_t = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_LIGHT);
186                                 float light_u, light_v;
187                                 path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
188
189                                 /* only sample triangle lights */
190                                 if(kernel_data.integrator.num_all_lights)
191                                         light_t = 0.5f*light_t;
192
193                                 LightSample ls;
194                                 light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
195
196                                 float3 tp = throughput;
197
198                                 /* sample position on volume segment */
199                                 float rphase = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_PHASE);
200                                 float rscatter = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_SCATTER_DISTANCE);
201
202                                 VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
203                                         state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
204                                         
205                                 (void)result;
206                                 kernel_assert(result == VOLUME_PATH_SCATTERED);
207
208                                 /* todo: split up light_sample so we don't have to call it again with new position */
209                                 light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
210
211                                 if(ls.pdf == 0.0f)
212                                         continue;
213
214                                 if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) {
215                                         /* trace shadow ray */
216                                         float3 shadow;
217
218                                         if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
219                                                 /* accumulate */
220                                                 path_radiance_accum_light(L, tp*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
221                                         }
222                                 }
223                         }
224                 }
225         }
226         else {
227                 /* sample random position on random light */
228                 float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
229                 float light_u, light_v;
230                 path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
231
232                 LightSample ls;
233                 light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
234
235                 float3 tp = throughput;
236
237                 /* sample position on volume segment */
238                 float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE);
239                 float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE);
240
241                 VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
242                         state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
243                         
244                 (void)result;
245                 kernel_assert(result == VOLUME_PATH_SCATTERED);
246
247                 /* todo: split up light_sample so we don't have to call it again with new position */
248                 light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
249
250                 if(ls.pdf == 0.0f)
251                         return;
252
253                 /* sample random light */
254                 if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) {
255                         /* trace shadow ray */
256                         float3 shadow;
257
258                         if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
259                                 /* accumulate */
260                                 path_radiance_accum_light(L, tp, &L_light, shadow, 1.0f, state->bounce, is_lamp);
261                         }
262                 }
263         }
264 #endif
265 }
266
267 #endif
268
269 CCL_NAMESPACE_END
270