efa23038089a1c4f4484545e798f51b071459518
[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__)) && !defined(__SPLIT_KERNEL__)
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 /* path tracing: connect path directly to position on a light and add it to L */
192 ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, ccl_addr_space RNG *rng,
193         ShaderData *sd, ShaderData *emission_sd, float3 throughput, ccl_addr_space PathState *state,
194         PathRadiance *L)
195 {
196 #ifdef __EMISSION__
197         if(!(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)))
198                 return;
199
200         /* sample illumination from lights to find path contribution */
201         float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
202         float light_u, light_v;
203         path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
204
205         Ray light_ray;
206         BsdfEval L_light;
207         bool is_lamp;
208
209 #ifdef __OBJECT_MOTION__
210         light_ray.time = sd->time;
211 #endif
212
213         LightSample ls;
214         if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
215                 float terminate = path_state_rng_light_termination(kg, rng, state);
216                 if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
217                         /* trace shadow ray */
218                         float3 shadow;
219
220                         if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) {
221                                 /* accumulate */
222                                 path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp);
223                         }
224                 }
225         }
226 #endif
227 }
228
229 /* path tracing: bounce off or through surface to with new direction stored in ray */
230 ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
231                                            ccl_addr_space RNG *rng,
232                                            ShaderData *sd,
233                                            ccl_addr_space float3 *throughput,
234                                            ccl_addr_space PathState *state,
235                                            PathRadiance *L,
236                                            ccl_addr_space Ray *ray)
237 {
238         /* no BSDF? we can stop here */
239         if(sd->flag & SD_BSDF) {
240                 /* sample BSDF */
241                 float bsdf_pdf;
242                 BsdfEval bsdf_eval;
243                 float3 bsdf_omega_in;
244                 differential3 bsdf_domega_in;
245                 float bsdf_u, bsdf_v;
246                 path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
247                 int label;
248
249                 label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval,
250                         &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
251
252                 if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
253                         return false;
254
255                 /* modify throughput */
256                 path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
257
258                 /* set labels */
259                 if(!(label & LABEL_TRANSPARENT)) {
260                         state->ray_pdf = bsdf_pdf;
261 #ifdef __LAMP_MIS__
262                         state->ray_t = 0.0f;
263 #endif
264                         state->min_ray_pdf = fminf(bsdf_pdf, state->min_ray_pdf);
265                 }
266
267                 /* update path state */
268                 path_state_next(kg, state, label);
269
270                 /* setup ray */
271                 ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng);
272                 ray->D = normalize(bsdf_omega_in);
273
274                 if(state->bounce == 0)
275                         ray->t -= sd->ray_length; /* clipping works through transparent */
276                 else
277                         ray->t = FLT_MAX;
278
279 #ifdef __RAY_DIFFERENTIALS__
280                 ray->dP = sd->dP;
281                 ray->dD = bsdf_domega_in;
282 #endif
283
284 #ifdef __VOLUME__
285                 /* enter/exit volume */
286                 if(label & LABEL_TRANSMIT)
287                         kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
288 #endif
289                 return true;
290         }
291 #ifdef __VOLUME__
292         else if(sd->flag & SD_HAS_ONLY_VOLUME) {
293                 /* no surface shader but have a volume shader? act transparent */
294
295                 /* update path state, count as transparent */
296                 path_state_next(kg, state, LABEL_TRANSPARENT);
297
298                 if(state->bounce == 0)
299                         ray->t -= sd->ray_length; /* clipping works through transparent */
300                 else
301                         ray->t = FLT_MAX;
302
303                 /* setup ray position, direction stays unchanged */
304                 ray->P = ray_offset(sd->P, -sd->Ng);
305 #ifdef __RAY_DIFFERENTIALS__
306                 ray->dP = sd->dP;
307 #endif
308
309                 /* enter/exit volume */
310                 kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
311                 return true;
312         }
313 #endif
314         else {
315                 /* no bsdf or volume? */
316                 return false;
317         }
318 }
319
320 CCL_NAMESPACE_END
321