Cycles: svn merge -r41225:41232 ^/trunk/blender
[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 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[x + y*kernel_data.cam.width];
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(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
141         return flag;
142 }
143
144 __device_inline float path_state_terminate_probability(KernelGlobals *kg, PathState *state, const float3 throughput)
145 {
146         if(state->flag & PATH_RAY_TRANSPARENT) {
147                 /* transparent rays treated separately */
148                 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce)
149                         return 0.0f;
150                 else if(state->transparent_bounce <= kernel_data.integrator.transparent_min_bounce)
151                         return 1.0f;
152         }
153         else {
154                 /* other rays */
155                 if((state->bounce >= kernel_data.integrator.max_bounce) ||
156                    (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) ||
157                    (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) ||
158                    (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce))
159                         return 0.0f;
160                 else if(state->bounce <= kernel_data.integrator.min_bounce)
161                         return 1.0f;
162         }
163
164         /* probalistic termination */
165         return average(throughput);
166 }
167
168 __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, float3 *light_L)
169 {
170         if(ray->t == 0.0f)
171                 return false;
172         
173         bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, isect);
174
175 #ifdef __TRANSPARENT_SHADOWS__
176         if(result && kernel_data.integrator.transparent_shadows) {
177                 /* transparent shadows work in such a way to try to minimize overhead
178                    in cases where we don't need them. after a regular shadow ray is
179                    cast we check if the hit primitive was potentially transparent, and
180                    only in that case start marching. this gives on extra ray cast for
181                    the cases were we do want transparency.
182                    
183                    also note that for this to work correct, multi close sampling must
184                    be used, since we don't pass a random number to shader_eval_surface */
185                 if(shader_transparent_shadow(kg, isect)) {
186                         float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
187                         float3 Pend = ray->P + ray->D*ray->t;
188                         int bounce = state->transparent_bounce;
189
190                         for(;;) {
191                                 if(bounce >= kernel_data.integrator.transparent_max_bounce) {
192                                         return true;
193                                 }
194                                 else if(bounce >= kernel_data.integrator.transparent_min_bounce) {
195                                         /* todo: get random number somewhere for probabilistic terminate */
196 #if 0
197                                         float probability = average(throughput);
198                                         float terminate = 0.0f;
199
200                                         if(terminate >= probability)
201                                                 return true;
202
203                                         throughput /= probability;
204 #endif
205                                 }
206
207                                 if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, isect)) {
208                                         *light_L *= throughput;
209                                         return false;
210                                 }
211
212                                 if(!shader_transparent_shadow(kg, isect))
213                                         return true;
214
215                                 ShaderData sd;
216                                 shader_setup_from_ray(kg, &sd, isect, ray);
217                                 shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW);
218
219                                 throughput *= shader_bsdf_transparency(kg, &sd);
220
221                                 ray->P = ray_offset(sd.P, -sd.Ng);
222                                 if(ray->t != FLT_MAX)
223                                         ray->D = normalize_len(Pend - ray->P, &ray->t);
224
225                                 bounce++;
226                         }
227                 }
228         }
229 #endif
230
231         return result;
232 }
233
234 __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, float3 throughput)
235 {
236         /* initialize */
237         float3 L = make_float3(0.0f, 0.0f, 0.0f);
238         float Ltransparent = 0.0f;
239
240 #ifdef __EMISSION__
241         float ray_pdf = 0.0f;
242 #endif
243         PathState state;
244         int rng_offset = PRNG_BASE_NUM;
245
246         path_state_init(&state);
247
248         /* path iteration */
249         for(;; rng_offset += PRNG_BOUNCE_NUM) {
250                 /* intersect scene */
251                 Intersection isect;
252                 uint visibility = path_state_ray_visibility(&state);
253
254                 if(!scene_intersect(kg, &ray, visibility, &isect)) {
255                         /* eval background shader if nothing hit */
256                         if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
257                                 Ltransparent += average(throughput);
258                         }
259                         else {
260 #ifdef __BACKGROUND__
261                                 ShaderData sd;
262                                 shader_setup_from_background(kg, &sd, &ray);
263                                 L += throughput*shader_eval_background(kg, &sd, state.flag);
264                                 shader_release(kg, &sd);
265 #else
266                                 L += throughput*make_float3(0.8f, 0.8f, 0.8f);
267 #endif
268                         }
269
270                         break;
271                 }
272
273                 /* setup shading */
274                 ShaderData sd;
275                 shader_setup_from_ray(kg, &sd, &isect, &ray);
276                 float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
277                 shader_eval_surface(kg, &sd, rbsdf, state.flag);
278
279 #ifdef __HOLDOUT__
280                 if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) {
281                         float3 holdout_weight = shader_holdout_eval(kg, &sd);
282
283                         if(kernel_data.background.transparent)
284                                 Ltransparent += average(holdout_weight*throughput);
285                 }
286 #endif
287
288 #ifdef __EMISSION__
289                 /* emission */
290                 if(sd.flag & SD_EMISSION)
291                         L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
292 #endif
293
294                 /* path termination. this is a strange place to put the termination, it's
295                    mainly due to the mixed in MIS that we use. gives too many unneeded
296                    shader evaluations, only need emission if we are going to terminate */
297                 float probability = path_state_terminate_probability(kg, &state, throughput);
298                 float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
299
300                 if(terminate >= probability)
301                         break;
302
303                 throughput /= probability;
304
305 #ifdef __EMISSION__
306                 if(kernel_data.integrator.use_direct_light) {
307                         /* sample illumination from lights to find path contribution */
308                         if(sd.flag & SD_BSDF_HAS_EVAL) {
309                                 float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
310                                 float light_o = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_F);
311                                 float light_u = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_U);
312                                 float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V);
313
314                                 Ray light_ray;
315                                 float3 light_L;
316
317 #ifdef __MULTI_LIGHT__
318                                 /* index -1 means randomly sample from distribution */
319                                 int i = (kernel_data.integrator.num_distribution)? -1: 0;
320
321                                 for(; i < kernel_data.integrator.num_all_lights; i++) {
322 #else
323                                 const int i = -1;
324 #endif
325                                         if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &light_L)) {
326                                                 /* trace shadow ray */
327                                                 if(!shadow_blocked(kg, &state, &light_ray, &isect, &light_L))
328                                                         L += throughput*light_L;
329                                         }
330 #ifdef __MULTI_LIGHT__
331                                 }
332 #endif
333                         }
334                 }
335 #endif
336
337                 /* no BSDF? we can stop here */
338                 if(!(sd.flag & SD_BSDF))
339                         break;
340
341                 /* sample BSDF */
342                 float bsdf_pdf;
343                 float3 bsdf_eval;
344                 float3 bsdf_omega_in;
345                 differential3 bsdf_domega_in;
346                 float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
347                 float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
348                 int label;
349
350                 label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval,
351                         &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
352
353                 shader_release(kg, &sd);
354
355                 if(bsdf_pdf == 0.0f || is_zero(bsdf_eval))
356                         break;
357
358                 /* modify throughput */
359                 throughput *= bsdf_eval/bsdf_pdf;
360
361                 /* set labels */
362 #ifdef __EMISSION__
363                 ray_pdf = bsdf_pdf;
364 #endif
365
366                 /* update path state */
367                 path_state_next(kg, &state, label);
368
369                 /* setup ray */
370                 ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
371                 ray.D = bsdf_omega_in;
372                 ray.t = FLT_MAX;
373 #ifdef __RAY_DIFFERENTIALS__
374                 ray.dP = sd.dP;
375                 ray.dD = bsdf_domega_in;
376 #endif
377         }
378
379         return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent);
380 }
381
382 __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y)
383 {
384         /* initialize random numbers */
385         RNG rng;
386
387         float filter_u;
388         float filter_v;
389
390         path_rng_init(kg, rng_state, sample, &rng, x, y, &filter_u, &filter_v);
391
392         /* sample camera ray */
393         Ray ray;
394
395         float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
396         float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
397
398         camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
399
400         /* integrate */
401 #ifdef __MODIFY_TP__
402         float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, sample);
403         float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput;
404 #else
405         float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
406         float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput);
407 #endif
408
409         /* accumulate result in output buffer */
410         int index = x + y*kernel_data.cam.width;
411
412         if(sample == 0)
413                 buffer[index] = L;
414         else
415                 buffer[index] += L;
416
417         path_rng_end(kg, rng_state, rng, x, y);
418 }
419
420 CCL_NAMESPACE_END
421