Cycles: Remove few function arguments needed only for the split kernel
[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__)
20
21 /* branched path tracing: connect path directly to position on one or more lights and add it to L */
22 ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RNG *rng,
23         ShaderData *sd, PathState *state, float3 throughput, float num_samples_adjust, PathRadiance *L, bool sample_all_lights)
24 {
25 #ifdef __EMISSION__
26         /* sample illumination from lights to find path contribution */
27         if(!(ccl_fetch(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 = ccl_fetch(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                         if(kernel_data.integrator.pdf_triangles != 0.0f)
49                                 num_samples_inv *= 0.5f;
50
51                         for(int j = 0; j < num_samples; j++) {
52                                 float light_u, light_v;
53                                 path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
54
55                                 LightSample ls;
56                                 lamp_light_sample(kg, i, light_u, light_v, ccl_fetch(sd, P), &ls);
57
58                                 if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) {
59                                         /* trace shadow ray */
60                                         float3 shadow;
61
62                                         if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
63                                                 /* accumulate */
64                                                 path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
65                                         }
66                                 }
67                         }
68                 }
69
70                 /* mesh light sampling */
71                 if(kernel_data.integrator.pdf_triangles != 0.0f) {
72                         int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples);
73                         float num_samples_inv = num_samples_adjust/num_samples;
74
75                         if(kernel_data.integrator.num_all_lights)
76                                 num_samples_inv *= 0.5f;
77
78                         for(int j = 0; j < num_samples; j++) {
79                                 float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT);
80                                 float light_u, light_v;
81                                 path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
82
83                                 /* only sample triangle lights */
84                                 if(kernel_data.integrator.num_all_lights)
85                                         light_t = 0.5f*light_t;
86
87                                 LightSample ls;
88                                 light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls);
89
90                                 if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) {
91                                         /* trace shadow ray */
92                                         float3 shadow;
93
94                                         if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
95                                                 /* accumulate */
96                                                 path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp);
97                                         }
98                                 }
99                         }
100                 }
101         }
102         else {
103                 /* sample one light at random */
104                 float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
105                 float light_u, light_v;
106                 path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
107
108                 LightSample ls;
109                 light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls);
110
111                 /* sample random light */
112                 if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) {
113                         /* trace shadow ray */
114                         float3 shadow;
115
116                         if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
117                                 /* accumulate */
118                                 path_radiance_accum_light(L, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, state->bounce, is_lamp);
119                         }
120                 }
121         }
122 #endif
123 }
124
125 /* branched path tracing: bounce off or through surface to with new direction stored in ray */
126 ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg, RNG *rng,
127         ShaderData *sd, const ShaderClosure *sc, int sample, int num_samples,
128         float3 *throughput, PathState *state, PathRadiance *L, Ray *ray)
129 {
130         /* sample BSDF */
131         float bsdf_pdf;
132         BsdfEval bsdf_eval;
133         float3 bsdf_omega_in;
134         differential3 bsdf_domega_in;
135         float bsdf_u, bsdf_v;
136         path_branched_rng_2D(kg, rng, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
137         int label;
138
139         label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval,
140                 &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
141
142         if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
143                 return false;
144
145         /* modify throughput */
146         path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
147
148         /* modify path state */
149         path_state_next(kg, state, label);
150
151         /* setup ray */
152         ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng));
153         ray->D = normalize(bsdf_omega_in);
154         ray->t = FLT_MAX;
155 #ifdef __RAY_DIFFERENTIALS__
156         ray->dP = ccl_fetch(sd, dP);
157         ray->dD = bsdf_domega_in;
158 #endif
159 #ifdef __OBJECT_MOTION__
160         ray->time = ccl_fetch(sd, time);
161 #endif
162
163 #ifdef __VOLUME__
164         /* enter/exit volume */
165         if(label & LABEL_TRANSMIT)
166                 kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
167 #endif
168
169         /* branch RNG state */
170         path_state_branch(state, sample, num_samples);
171
172         /* set MIS state */
173         state->min_ray_pdf = fminf(bsdf_pdf, FLT_MAX);
174         state->ray_pdf = bsdf_pdf;
175 #ifdef __LAMP_MIS__
176         state->ray_t = 0.0f;
177 #endif
178
179         return true;
180 }
181
182 #endif
183
184 #ifndef __SPLIT_KERNEL__
185 /* path tracing: connect path directly to position on a light and add it to L */
186 ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, ccl_addr_space RNG *rng,
187         ShaderData *sd, float3 throughput, ccl_addr_space PathState *state, PathRadiance *L)
188 {
189 #ifdef __EMISSION__
190         if(!(kernel_data.integrator.use_direct_light && (ccl_fetch(sd, flag) & SD_BSDF_HAS_EVAL)))
191                 return;
192
193         /* sample illumination from lights to find path contribution */
194         float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
195         float light_u, light_v;
196         path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
197
198         Ray light_ray;
199         BsdfEval L_light;
200         bool is_lamp;
201
202 #ifdef __OBJECT_MOTION__
203         light_ray.time = ccl_fetch(sd, time);
204 #endif
205
206         LightSample ls;
207         light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls);
208
209         if(direct_emission(kg, sd, &ls, state, &light_ray, &L_light, &is_lamp)) {
210                 /* trace shadow ray */
211                 float3 shadow;
212
213                 if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
214                         /* accumulate */
215                         path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp);
216                 }
217         }
218 #endif
219 }
220 #endif
221
222 /* path tracing: bounce off or through surface to with new direction stored in ray */
223 ccl_device_inline bool kernel_path_surface_bounce(KernelGlobals *kg, ccl_addr_space RNG *rng,
224         ShaderData *sd, ccl_addr_space float3 *throughput, ccl_addr_space PathState *state, PathRadiance *L, ccl_addr_space Ray *ray)
225 {
226         /* no BSDF? we can stop here */
227         if(ccl_fetch(sd, flag) & SD_BSDF) {
228                 /* sample BSDF */
229                 float bsdf_pdf;
230                 BsdfEval bsdf_eval;
231                 float3 bsdf_omega_in;
232                 differential3 bsdf_domega_in;
233                 float bsdf_u, bsdf_v;
234                 path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
235                 int label;
236
237                 label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval,
238                         &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
239
240                 if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
241                         return false;
242
243                 /* modify throughput */
244                 path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
245
246                 /* set labels */
247                 if(!(label & LABEL_TRANSPARENT)) {
248                         state->ray_pdf = bsdf_pdf;
249 #ifdef __LAMP_MIS__
250                         state->ray_t = 0.0f;
251 #endif
252                         state->min_ray_pdf = fminf(bsdf_pdf, state->min_ray_pdf);
253                 }
254
255                 /* update path state */
256                 path_state_next(kg, state, label);
257
258                 /* setup ray */
259                 ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng));
260                 ray->D = normalize(bsdf_omega_in);
261
262                 if(state->bounce == 0)
263                         ray->t -= ccl_fetch(sd, ray_length); /* clipping works through transparent */
264                 else
265                         ray->t = FLT_MAX;
266
267 #ifdef __RAY_DIFFERENTIALS__
268                 ray->dP = ccl_fetch(sd, dP);
269                 ray->dD = bsdf_domega_in;
270 #endif
271
272 #ifdef __VOLUME__
273                 /* enter/exit volume */
274                 if(label & LABEL_TRANSMIT)
275                         kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
276 #endif
277                 return true;
278         }
279 #ifdef __VOLUME__
280         else if(ccl_fetch(sd, flag) & SD_HAS_ONLY_VOLUME) {
281                 /* no surface shader but have a volume shader? act transparent */
282
283                 /* update path state, count as transparent */
284                 path_state_next(kg, state, LABEL_TRANSPARENT);
285
286                 if(state->bounce == 0)
287                         ray->t -= ccl_fetch(sd, ray_length); /* clipping works through transparent */
288                 else
289                         ray->t = FLT_MAX;
290
291                 /* setup ray position, direction stays unchanged */
292                 ray->P = ray_offset(ccl_fetch(sd, P), -ccl_fetch(sd, Ng));
293 #ifdef __RAY_DIFFERENTIALS__
294                 ray->dP = ccl_fetch(sd, dP);
295 #endif
296
297                 /* enter/exit volume */
298                 kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
299                 return true;
300         }
301 #endif
302         else {
303                 /* no bsdf or volume? */
304                 return false;
305         }
306 }
307
308 CCL_NAMESPACE_END
309