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