svn merge ^/trunk/blender -r43676:43685
[blender.git] / intern / cycles / kernel / kernel_path.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include "kernel_differential.h"
20 #include "kernel_montecarlo.h"
21 #include "kernel_triangle.h"
22 #include "kernel_object.h"
23 #ifdef __QBVH__
24 #include "kernel_qbvh.h"
25 #else
26 #include "kernel_bvh.h"
27 #endif
28 #include "kernel_camera.h"
29 #include "kernel_shader.h"
30 #include "kernel_light.h"
31 #include "kernel_emission.h"
32 #include "kernel_random.h"
33
34 CCL_NAMESPACE_BEGIN
35
36 #ifdef __MODIFY_TP__
37 __device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int offset, int stride, int sample)
38 {
39         /* modify throughput to influence path termination probability, to avoid
40            darker regions receiving fewer samples than lighter regions. also RGB
41            are weighted differently. proper validation still remains to be done. */
42         const float3 weights = make_float3(1.0f, 1.33f, 0.66f);
43         const float3 one = make_float3(1.0f, 1.0f, 1.0f);
44         const int minsample = 5;
45         const float minL = 0.1f;
46
47         if(sample >= minsample) {
48                 float3 L = buffer[offset + x + y*stride];
49                 float3 Lmin = make_float3(minL, minL, minL);
50                 float correct = (float)(sample+1)/(float)sample;
51
52                 L = film_map(L*correct, sample);
53
54                 return weights/clamp(L, Lmin, one);
55         }
56
57         return weights;
58 }
59 #endif
60
61 typedef struct PathState {
62         uint flag;
63         int bounce;
64
65         int diffuse_bounce;
66         int glossy_bounce;
67         int transmission_bounce;
68         int transparent_bounce;
69 } PathState;
70
71 __device_inline void path_state_init(PathState *state)
72 {
73         state->flag = PATH_RAY_CAMERA|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
74         state->bounce = 0;
75         state->diffuse_bounce = 0;
76         state->glossy_bounce = 0;
77         state->transmission_bounce = 0;
78         state->transparent_bounce = 0;
79 }
80
81 __device_inline void path_state_next(KernelGlobals *kg, PathState *state, int label)
82 {
83         /* ray through transparent keeps same flags from previous ray and is
84            not counted as a regular bounce, transparent has separate max */
85         if(label & LABEL_TRANSPARENT) {
86                 state->flag |= PATH_RAY_TRANSPARENT;
87                 state->transparent_bounce++;
88
89                 if(!kernel_data.integrator.transparent_shadows)
90                         state->flag |= PATH_RAY_MIS_SKIP;
91
92                 return;
93         }
94
95         state->bounce++;
96
97         /* reflection/transmission */
98         if(label & LABEL_REFLECT) {
99                 state->flag |= PATH_RAY_REFLECT;
100                 state->flag &= ~(PATH_RAY_TRANSMIT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
101
102                 if(label & LABEL_DIFFUSE)
103                         state->diffuse_bounce++;
104                 else
105                         state->glossy_bounce++;
106         }
107         else {
108                 kernel_assert(label & LABEL_TRANSMIT);
109
110                 state->flag |= PATH_RAY_TRANSMIT;
111                 state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
112
113                 state->transmission_bounce++;
114         }
115
116         /* diffuse/glossy/singular */
117         if(label & LABEL_DIFFUSE) {
118                 state->flag |= PATH_RAY_DIFFUSE;
119                 state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
120         }
121         else if(label & LABEL_GLOSSY) {
122                 state->flag |= PATH_RAY_GLOSSY;
123                 state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
124         }
125         else {
126                 kernel_assert(label & LABEL_SINGULAR);
127
128                 state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
129                 state->flag &= ~PATH_RAY_DIFFUSE;
130         }
131 }
132
133 __device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state)
134 {
135         uint flag = state->flag;
136
137         /* for visibility, diffuse/glossy are for reflection only */
138         if(flag & PATH_RAY_TRANSMIT)
139                 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
140         /* for camera visibility, use render layer flags */
141         if(flag & PATH_RAY_CAMERA)
142                 flag |= kernel_data.integrator.layer_flag;
143
144         return flag;
145 }
146
147 __device_inline float path_state_terminate_probability(KernelGlobals *kg, PathState *state, const float3 throughput)
148 {
149         if(state->flag & PATH_RAY_TRANSPARENT) {
150                 /* transparent rays treated separately */
151                 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce)
152                         return 0.0f;
153                 else if(state->transparent_bounce <= kernel_data.integrator.transparent_min_bounce)
154                         return 1.0f;
155         }
156         else {
157                 /* other rays */
158                 if((state->bounce >= kernel_data.integrator.max_bounce) ||
159                    (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) ||
160                    (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) ||
161                    (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce))
162                         return 0.0f;
163                 else if(state->bounce <= kernel_data.integrator.min_bounce)
164                         return 1.0f;
165         }
166
167         /* probalistic termination */
168         return average(throughput);
169 }
170
171 __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, float3 *light_L)
172 {
173         if(ray->t == 0.0f)
174                 return false;
175         
176         bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, isect);
177
178 #ifdef __TRANSPARENT_SHADOWS__
179         if(result && kernel_data.integrator.transparent_shadows) {
180                 /* transparent shadows work in such a way to try to minimize overhead
181                    in cases where we don't need them. after a regular shadow ray is
182                    cast we check if the hit primitive was potentially transparent, and
183                    only in that case start marching. this gives on extra ray cast for
184                    the cases were we do want transparency.
185                    
186                    also note that for this to work correct, multi close sampling must
187                    be used, since we don't pass a random number to shader_eval_surface */
188                 if(shader_transparent_shadow(kg, isect)) {
189                         float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
190                         float3 Pend = ray->P + ray->D*ray->t;
191                         int bounce = state->transparent_bounce;
192
193                         for(;;) {
194                                 if(bounce >= kernel_data.integrator.transparent_max_bounce) {
195                                         return true;
196                                 }
197                                 else if(bounce >= kernel_data.integrator.transparent_min_bounce) {
198                                         /* todo: get random number somewhere for probabilistic terminate */
199 #if 0
200                                         float probability = average(throughput);
201                                         float terminate = 0.0f;
202
203                                         if(terminate >= probability)
204                                                 return true;
205
206                                         throughput /= probability;
207 #endif
208                                 }
209
210                                 if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, isect)) {
211                                         *light_L *= throughput;
212                                         return false;
213                                 }
214
215                                 if(!shader_transparent_shadow(kg, isect))
216                                         return true;
217
218                                 ShaderData sd;
219                                 shader_setup_from_ray(kg, &sd, isect, ray);
220                                 shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW);
221
222                                 throughput *= shader_bsdf_transparency(kg, &sd);
223
224                                 ray->P = ray_offset(sd.P, -sd.Ng);
225                                 if(ray->t != FLT_MAX)
226                                         ray->D = normalize_len(Pend - ray->P, &ray->t);
227
228                                 bounce++;
229                         }
230                 }
231         }
232 #endif
233
234         return result;
235 }
236
237 __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, float3 throughput)
238 {
239         /* initialize */
240         float3 L = make_float3(0.0f, 0.0f, 0.0f);
241         float Ltransparent = 0.0f;
242
243 #ifdef __EMISSION__
244         float ray_pdf = 0.0f;
245 #endif
246         PathState state;
247         int rng_offset = PRNG_BASE_NUM;
248
249         path_state_init(&state);
250
251         /* path iteration */
252         for(;; rng_offset += PRNG_BOUNCE_NUM) {
253                 /* intersect scene */
254                 Intersection isect;
255                 uint visibility = path_state_ray_visibility(kg, &state);
256
257                 if(!scene_intersect(kg, &ray, visibility, &isect)) {
258                         /* eval background shader if nothing hit */
259                         if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
260                                 Ltransparent += average(throughput);
261                         }
262                         else {
263                                 /* sample background shader */
264                                 float3 background_L = indirect_background(kg, &ray, state.flag, ray_pdf);
265                                 L += throughput*background_L;
266                         }
267
268                         break;
269                 }
270
271                 /* setup shading */
272                 ShaderData sd;
273                 shader_setup_from_ray(kg, &sd, &isect, &ray);
274                 float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
275                 shader_eval_surface(kg, &sd, rbsdf, state.flag);
276
277 #ifdef __HOLDOUT__
278                 if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) {
279                         float3 holdout_weight = shader_holdout_eval(kg, &sd);
280
281                         if(kernel_data.background.transparent)
282                                 Ltransparent += average(holdout_weight*throughput);
283                 }
284 #endif
285
286 #ifdef __EMISSION__
287                 /* emission */
288                 if(sd.flag & SD_EMISSION)
289                         L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
290 #endif
291
292                 /* path termination. this is a strange place to put the termination, it's
293                    mainly due to the mixed in MIS that we use. gives too many unneeded
294                    shader evaluations, only need emission if we are going to terminate */
295                 float probability = path_state_terminate_probability(kg, &state, throughput);
296                 float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
297
298                 if(terminate >= probability)
299                         break;
300
301                 throughput /= probability;
302
303 #ifdef __EMISSION__
304                 if(kernel_data.integrator.use_direct_light) {
305                         /* sample illumination from lights to find path contribution */
306                         if(sd.flag & SD_BSDF_HAS_EVAL) {
307                                 float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
308                                 float light_o = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_F);
309                                 float light_u = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_U);
310                                 float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V);
311
312                                 Ray light_ray;
313                                 float3 light_L;
314
315 #ifdef __MULTI_LIGHT__
316                                 /* index -1 means randomly sample from distribution */
317                                 int i = (kernel_data.integrator.num_distribution)? -1: 0;
318
319                                 for(; i < kernel_data.integrator.num_all_lights; i++) {
320 #else
321                                 const int i = -1;
322 #endif
323                                         if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &light_L)) {
324                                                 /* trace shadow ray */
325                                                 if(!shadow_blocked(kg, &state, &light_ray, &isect, &light_L))
326                                                         L += throughput*light_L;
327                                         }
328 #ifdef __MULTI_LIGHT__
329                                 }
330 #endif
331                         }
332                 }
333 #endif
334
335                 /* no BSDF? we can stop here */
336                 if(!(sd.flag & SD_BSDF))
337                         break;
338
339                 /* sample BSDF */
340                 float bsdf_pdf;
341                 float3 bsdf_eval;
342                 float3 bsdf_omega_in;
343                 differential3 bsdf_domega_in;
344                 float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
345                 float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
346                 int label;
347
348                 label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval,
349                         &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
350
351                 shader_release(kg, &sd);
352
353                 if(bsdf_pdf == 0.0f || is_zero(bsdf_eval))
354                         break;
355
356                 /* modify throughput */
357                 throughput *= bsdf_eval/bsdf_pdf;
358
359                 /* set labels */
360 #if defined(__EMISSION__) || defined(__BACKGROUND__)
361                 ray_pdf = bsdf_pdf;
362 #endif
363
364                 /* update path state */
365                 path_state_next(kg, &state, label);
366
367                 /* setup ray */
368                 ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
369                 ray.D = bsdf_omega_in;
370                 ray.t = FLT_MAX;
371 #ifdef __RAY_DIFFERENTIALS__
372                 ray.dP = sd.dP;
373                 ray.dD = bsdf_domega_in;
374 #endif
375         }
376
377         return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent);
378 }
379
380 __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y, int offset, int stride)
381 {
382         /* initialize random numbers */
383         RNG rng;
384
385         float filter_u;
386         float filter_v;
387
388         path_rng_init(kg, rng_state, sample, &rng, x, y, offset, stride, &filter_u, &filter_v);
389
390         /* sample camera ray */
391         Ray ray;
392
393         float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
394         float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
395
396         camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
397
398         /* integrate */
399 #ifdef __MODIFY_TP__
400         float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, offset, stride, sample);
401         float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput;
402 #else
403         float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
404         float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput);
405 #endif
406
407         /* accumulate result in output buffer */
408         int index = offset + x + y*stride;
409
410         if(sample == 0)
411                 buffer[index] = L;
412         else
413                 buffer[index] += L;
414
415         path_rng_end(kg, rng_state, rng, x, y, offset, stride);
416 }
417
418 CCL_NAMESPACE_END
419