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