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