2 * Copyright 2011, Blender Foundation.
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.
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.
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.
19 #include "kernel_differential.h"
20 #include "kernel_montecarlo.h"
21 #include "kernel_triangle.h"
22 #include "kernel_object.h"
24 #include "kernel_qbvh.h"
26 #include "kernel_bvh.h"
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"
37 __device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int sample)
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;
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;
52 L = film_map(L*correct, sample);
54 return weights/clamp(L, Lmin, one);
61 typedef struct PathState {
67 int transmission_bounce;
68 int transparent_bounce;
71 __device_inline void path_state_init(PathState *state)
73 state->flag = PATH_RAY_CAMERA|PATH_RAY_SINGULAR;
75 state->diffuse_bounce = 0;
76 state->glossy_bounce = 0;
77 state->transmission_bounce = 0;
78 state->transparent_bounce = 0;
81 __device_inline void path_state_next(PathState *state, int label)
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++;
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);
99 if(label & LABEL_DIFFUSE)
100 state->diffuse_bounce++;
102 state->glossy_bounce++;
105 kernel_assert(label & LABEL_TRANSMIT);
107 state->flag |= PATH_RAY_TRANSMIT;
108 state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
110 state->transmission_bounce++;
113 /* diffuse/glossy/singular */
114 if(label & LABEL_DIFFUSE) {
115 state->flag |= PATH_RAY_DIFFUSE;
116 state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR);
118 else if(label & LABEL_GLOSSY) {
119 state->flag |= PATH_RAY_GLOSSY;
120 state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR);
123 kernel_assert(label & LABEL_SINGULAR);
125 state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR;
126 state->flag &= ~PATH_RAY_DIFFUSE;
130 __device_inline uint path_state_ray_visibility(PathState *state)
132 uint flag = state->flag;
134 /* for visibility, diffuse/glossy are for reflection only */
135 if(flag & PATH_RAY_TRANSMIT)
136 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
141 __device_inline float path_state_terminate_probability(KernelGlobals *kg, PathState *state, const float3 throughput)
143 if(state->flag & PATH_RAY_TRANSPARENT) {
144 /* transparent rays treated separately */
145 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce)
147 else if(state->transparent_bounce <= kernel_data.integrator.transparent_min_bounce)
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))
157 else if(state->bounce <= kernel_data.integrator.min_bounce)
161 /* probalistic termination */
162 return average(throughput);
165 #ifdef __TRANSPARENT_SHADOWS__
166 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
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);
172 /* todo: add shader flag to check this */
178 __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, float3 *light_L)
183 bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW, isect);
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)) */
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;
201 if(bounce >= kernel_data.integrator.transparent_max_bounce) {
204 else if(bounce >= kernel_data.integrator.transparent_min_bounce) {
205 /* todo: get random number somewhere for probabilistic terminate */
207 float probability = average(throughput);
208 float terminate = 0.0f; /* todo: get this random number */
210 if(terminate >= probability)
213 throughput /= probability;
217 /* todo: fix it so we get first hit */
218 if(!scene_intersect(kg, ray, PATH_RAY_SHADOW, isect)) {
219 *light_L *= throughput;
222 if(!shader_transparent_shadow(kg, isect))
226 shader_setup_from_ray(kg, &sd, isect, ray);
227 shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW); /* todo: state flag? */
229 throughput *= shader_bsdf_transparency(kg, &sd);
231 ray->P = ray_offset(sd.P, -sd.Ng);
232 ray->t = len(Pend - ray->P);
245 __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, float3 throughput)
248 float3 L = make_float3(0.0f, 0.0f, 0.0f);
249 float Ltransparent = 0.0f;
252 float ray_pdf = 0.0f;
255 int rng_offset = PRNG_BASE_NUM;
257 path_state_init(&state);
260 for(;; rng_offset += PRNG_BOUNCE_NUM) {
261 /* intersect scene */
263 uint visibility = path_state_ray_visibility(&state);
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);
271 #ifdef __BACKGROUND__
273 shader_setup_from_background(kg, &sd, &ray);
274 L += throughput*shader_eval_background(kg, &sd, state.flag);
275 shader_release(kg, &sd);
277 L += throughput*make_float3(0.8f, 0.8f, 0.8f);
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);
291 if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) {
292 float3 holdout_weight = shader_holdout_eval(kg, &sd);
294 if(kernel_data.background.transparent)
295 Ltransparent += average(holdout_weight*throughput);
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);
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);
313 if(terminate >= probability)
316 throughput /= probability;
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);
330 #ifdef __MULTI_LIGHT__
331 /* index -1 means randomly sample from distribution */
332 int i = (kernel_data.integrator.num_distribution)? -1: 0;
334 for(; i < kernel_data.integrator.num_all_lights; i++) {
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;
343 #ifdef __MULTI_LIGHT__
350 /* no BSDF? we can stop here */
351 if(!(sd.flag & SD_BSDF))
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);
363 label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval,
364 &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
366 shader_release(kg, &sd);
368 if(bsdf_pdf == 0.0f || is_zero(bsdf_eval))
371 /* modify throughput */
372 throughput *= bsdf_eval/bsdf_pdf;
379 /* update path state */
380 path_state_next(&state, label);
383 ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
384 ray.D = bsdf_omega_in;
386 #ifdef __RAY_DIFFERENTIALS__
388 ray.dD = bsdf_domega_in;
392 return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent);
395 __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y)
397 /* initialize random numbers */
403 path_rng_init(kg, rng_state, sample, &rng, x, y, &filter_u, &filter_v);
405 /* sample camera ray */
408 float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
409 float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
411 camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
415 float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, sample);
416 float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput;
418 float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
419 float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput);
422 /* accumulate result in output buffer */
423 int index = x + y*kernel_data.cam.width;
430 path_rng_end(kg, rng_state, rng, x, y);