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|PATH_RAY_MIS_SKIP;
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(KernelGlobals *kg, 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++;
89 if(!kernel_data.integrator.transparent_shadows)
90 state->flag |= PATH_RAY_MIS_SKIP;
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);
102 if(label & LABEL_DIFFUSE)
103 state->diffuse_bounce++;
105 state->glossy_bounce++;
108 kernel_assert(label & LABEL_TRANSMIT);
110 state->flag |= PATH_RAY_TRANSMIT;
111 state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
113 state->transmission_bounce++;
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);
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);
126 kernel_assert(label & LABEL_SINGULAR);
128 state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
129 state->flag &= ~PATH_RAY_DIFFUSE;
133 __device_inline uint path_state_ray_visibility(PathState *state)
135 uint flag = state->flag;
137 /* for visibility, diffuse/glossy are for reflection only */
138 if(flag & PATH_RAY_TRANSMIT)
139 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
144 __device_inline float path_state_terminate_probability(KernelGlobals *kg, PathState *state, const float3 throughput)
146 if(state->flag & PATH_RAY_TRANSPARENT) {
147 /* transparent rays treated separately */
148 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce)
150 else if(state->transparent_bounce <= kernel_data.integrator.transparent_min_bounce)
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))
160 else if(state->bounce <= kernel_data.integrator.min_bounce)
164 /* probalistic termination */
165 return average(throughput);
168 __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, float3 *light_L)
173 bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, isect);
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.
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;
191 if(bounce >= kernel_data.integrator.transparent_max_bounce) {
194 else if(bounce >= kernel_data.integrator.transparent_min_bounce) {
195 /* todo: get random number somewhere for probabilistic terminate */
197 float probability = average(throughput);
198 float terminate = 0.0f;
200 if(terminate >= probability)
203 throughput /= probability;
207 if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, isect)) {
208 *light_L *= throughput;
212 if(!shader_transparent_shadow(kg, isect))
216 shader_setup_from_ray(kg, &sd, isect, ray);
217 shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW);
219 throughput *= shader_bsdf_transparency(kg, &sd);
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);
234 __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, float3 throughput)
237 float3 L = make_float3(0.0f, 0.0f, 0.0f);
238 float Ltransparent = 0.0f;
241 float ray_pdf = 0.0f;
244 int rng_offset = PRNG_BASE_NUM;
246 path_state_init(&state);
249 for(;; rng_offset += PRNG_BOUNCE_NUM) {
250 /* intersect scene */
252 uint visibility = path_state_ray_visibility(&state);
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);
260 #ifdef __BACKGROUND__
262 shader_setup_from_background(kg, &sd, &ray);
263 L += throughput*shader_eval_background(kg, &sd, state.flag);
264 shader_release(kg, &sd);
266 L += throughput*make_float3(0.8f, 0.8f, 0.8f);
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);
280 if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) {
281 float3 holdout_weight = shader_holdout_eval(kg, &sd);
283 if(kernel_data.background.transparent)
284 Ltransparent += average(holdout_weight*throughput);
290 if(sd.flag & SD_EMISSION)
291 L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
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);
300 if(terminate >= probability)
303 throughput /= probability;
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);
317 #ifdef __MULTI_LIGHT__
318 /* index -1 means randomly sample from distribution */
319 int i = (kernel_data.integrator.num_distribution)? -1: 0;
321 for(; i < kernel_data.integrator.num_all_lights; i++) {
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;
330 #ifdef __MULTI_LIGHT__
337 /* no BSDF? we can stop here */
338 if(!(sd.flag & SD_BSDF))
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);
350 label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval,
351 &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
353 shader_release(kg, &sd);
355 if(bsdf_pdf == 0.0f || is_zero(bsdf_eval))
358 /* modify throughput */
359 throughput *= bsdf_eval/bsdf_pdf;
366 /* update path state */
367 path_state_next(kg, &state, label);
370 ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
371 ray.D = bsdf_omega_in;
373 #ifdef __RAY_DIFFERENTIALS__
375 ray.dD = bsdf_domega_in;
379 return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent);
382 __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y)
384 /* initialize random numbers */
390 path_rng_init(kg, rng_state, sample, &rng, x, y, &filter_u, &filter_v);
392 /* sample camera ray */
395 float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
396 float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
398 camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
402 float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, sample);
403 float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput;
405 float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
406 float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput);
409 /* accumulate result in output buffer */
410 int index = x + y*kernel_data.cam.width;
417 path_rng_end(kg, rng_state, rng, x, y);