Cycles: code refactoring, to do render layer visibility test a bit different,
[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 #ifdef __BACKGROUND__
264                                 ShaderData sd;
265                                 shader_setup_from_background(kg, &sd, &ray);
266                                 L += throughput*shader_eval_background(kg, &sd, state.flag);
267                                 shader_release(kg, &sd);
268 #else
269                                 L += throughput*make_float3(0.8f, 0.8f, 0.8f);
270 #endif
271                         }
272
273                         break;
274                 }
275
276                 /* setup shading */
277                 ShaderData sd;
278                 shader_setup_from_ray(kg, &sd, &isect, &ray);
279                 float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
280                 shader_eval_surface(kg, &sd, rbsdf, state.flag);
281
282 #ifdef __HOLDOUT__
283                 if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) {
284                         float3 holdout_weight = shader_holdout_eval(kg, &sd);
285
286                         if(kernel_data.background.transparent)
287                                 Ltransparent += average(holdout_weight*throughput);
288                 }
289 #endif
290
291 #ifdef __EMISSION__
292                 /* emission */
293                 if(sd.flag & SD_EMISSION)
294                         L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
295 #endif
296
297                 /* path termination. this is a strange place to put the termination, it's
298                    mainly due to the mixed in MIS that we use. gives too many unneeded
299                    shader evaluations, only need emission if we are going to terminate */
300                 float probability = path_state_terminate_probability(kg, &state, throughput);
301                 float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
302
303                 if(terminate >= probability)
304                         break;
305
306                 throughput /= probability;
307
308 #ifdef __EMISSION__
309                 if(kernel_data.integrator.use_direct_light) {
310                         /* sample illumination from lights to find path contribution */
311                         if(sd.flag & SD_BSDF_HAS_EVAL) {
312                                 float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
313                                 float light_o = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_F);
314                                 float light_u = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_U);
315                                 float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V);
316
317                                 Ray light_ray;
318                                 float3 light_L;
319
320 #ifdef __MULTI_LIGHT__
321                                 /* index -1 means randomly sample from distribution */
322                                 int i = (kernel_data.integrator.num_distribution)? -1: 0;
323
324                                 for(; i < kernel_data.integrator.num_all_lights; i++) {
325 #else
326                                 const int i = -1;
327 #endif
328                                         if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &light_L)) {
329                                                 /* trace shadow ray */
330                                                 if(!shadow_blocked(kg, &state, &light_ray, &isect, &light_L))
331                                                         L += throughput*light_L;
332                                         }
333 #ifdef __MULTI_LIGHT__
334                                 }
335 #endif
336                         }
337                 }
338 #endif
339
340                 /* no BSDF? we can stop here */
341                 if(!(sd.flag & SD_BSDF))
342                         break;
343
344                 /* sample BSDF */
345                 float bsdf_pdf;
346                 float3 bsdf_eval;
347                 float3 bsdf_omega_in;
348                 differential3 bsdf_domega_in;
349                 float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
350                 float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
351                 int label;
352
353                 label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval,
354                         &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
355
356                 shader_release(kg, &sd);
357
358                 if(bsdf_pdf == 0.0f || is_zero(bsdf_eval))
359                         break;
360
361                 /* modify throughput */
362                 throughput *= bsdf_eval/bsdf_pdf;
363
364                 /* set labels */
365 #ifdef __EMISSION__
366                 ray_pdf = bsdf_pdf;
367 #endif
368
369                 /* update path state */
370                 path_state_next(kg, &state, label);
371
372                 /* setup ray */
373                 ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
374                 ray.D = bsdf_omega_in;
375                 ray.t = FLT_MAX;
376 #ifdef __RAY_DIFFERENTIALS__
377                 ray.dP = sd.dP;
378                 ray.dD = bsdf_domega_in;
379 #endif
380         }
381
382         return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent);
383 }
384
385 __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y, int offset, int stride)
386 {
387         /* initialize random numbers */
388         RNG rng;
389
390         float filter_u;
391         float filter_v;
392
393         path_rng_init(kg, rng_state, sample, &rng, x, y, offset, stride, &filter_u, &filter_v);
394
395         /* sample camera ray */
396         Ray ray;
397
398         float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
399         float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
400
401         camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
402
403         /* integrate */
404 #ifdef __MODIFY_TP__
405         float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, offset, stride, sample);
406         float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput;
407 #else
408         float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
409         float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput);
410 #endif
411
412         /* accumulate result in output buffer */
413         int index = offset + x + y*stride;
414
415         if(sample == 0)
416                 buffer[index] = L;
417         else
418                 buffer[index] += L;
419
420         path_rng_end(kg, rng_state, rng, x, y, offset, stride);
421 }
422
423 CCL_NAMESPACE_END
424