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