Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "kernel_differential.h" 00020 #include "kernel_montecarlo.h" 00021 #include "kernel_triangle.h" 00022 #include "kernel_object.h" 00023 #ifdef __QBVH__ 00024 #include "kernel_qbvh.h" 00025 #else 00026 #include "kernel_bvh.h" 00027 #endif 00028 #include "kernel_camera.h" 00029 #include "kernel_shader.h" 00030 #include "kernel_light.h" 00031 #include "kernel_emission.h" 00032 #include "kernel_random.h" 00033 00034 CCL_NAMESPACE_BEGIN 00035 00036 #ifdef __MODIFY_TP__ 00037 __device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int offset, int stride, int sample) 00038 { 00039 /* modify throughput to influence path termination probability, to avoid 00040 darker regions receiving fewer samples than lighter regions. also RGB 00041 are weighted differently. proper validation still remains to be done. */ 00042 const float3 weights = make_float3(1.0f, 1.33f, 0.66f); 00043 const float3 one = make_float3(1.0f, 1.0f, 1.0f); 00044 const int minsample = 5; 00045 const float minL = 0.1f; 00046 00047 if(sample >= minsample) { 00048 float3 L = buffer[offset + x + y*stride]; 00049 float3 Lmin = make_float3(minL, minL, minL); 00050 float correct = (float)(sample+1)/(float)sample; 00051 00052 L = film_map(L*correct, sample); 00053 00054 return weights/clamp(L, Lmin, one); 00055 } 00056 00057 return weights; 00058 } 00059 #endif 00060 00061 typedef struct PathState { 00062 uint flag; 00063 int bounce; 00064 00065 int diffuse_bounce; 00066 int glossy_bounce; 00067 int transmission_bounce; 00068 int transparent_bounce; 00069 } PathState; 00070 00071 __device_inline void path_state_init(PathState *state) 00072 { 00073 state->flag = PATH_RAY_CAMERA|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP; 00074 state->bounce = 0; 00075 state->diffuse_bounce = 0; 00076 state->glossy_bounce = 0; 00077 state->transmission_bounce = 0; 00078 state->transparent_bounce = 0; 00079 } 00080 00081 __device_inline void path_state_next(KernelGlobals *kg, PathState *state, int label) 00082 { 00083 /* ray through transparent keeps same flags from previous ray and is 00084 not counted as a regular bounce, transparent has separate max */ 00085 if(label & LABEL_TRANSPARENT) { 00086 state->flag |= PATH_RAY_TRANSPARENT; 00087 state->transparent_bounce++; 00088 00089 if(!kernel_data.integrator.transparent_shadows) 00090 state->flag |= PATH_RAY_MIS_SKIP; 00091 00092 return; 00093 } 00094 00095 state->bounce++; 00096 00097 /* reflection/transmission */ 00098 if(label & LABEL_REFLECT) { 00099 state->flag |= PATH_RAY_REFLECT; 00100 state->flag &= ~(PATH_RAY_TRANSMIT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT); 00101 00102 if(label & LABEL_DIFFUSE) 00103 state->diffuse_bounce++; 00104 else 00105 state->glossy_bounce++; 00106 } 00107 else { 00108 kernel_assert(label & LABEL_TRANSMIT); 00109 00110 state->flag |= PATH_RAY_TRANSMIT; 00111 state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT); 00112 00113 state->transmission_bounce++; 00114 } 00115 00116 /* diffuse/glossy/singular */ 00117 if(label & LABEL_DIFFUSE) { 00118 state->flag |= PATH_RAY_DIFFUSE; 00119 state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP); 00120 } 00121 else if(label & LABEL_GLOSSY) { 00122 state->flag |= PATH_RAY_GLOSSY; 00123 state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP); 00124 } 00125 else { 00126 kernel_assert(label & LABEL_SINGULAR); 00127 00128 state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP; 00129 state->flag &= ~PATH_RAY_DIFFUSE; 00130 } 00131 } 00132 00133 __device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state) 00134 { 00135 uint flag = state->flag; 00136 00137 /* for visibility, diffuse/glossy are for reflection only */ 00138 if(flag & PATH_RAY_TRANSMIT) 00139 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY); 00140 /* for camera visibility, use render layer flags */ 00141 if(flag & PATH_RAY_CAMERA) 00142 flag |= kernel_data.integrator.layer_flag; 00143 00144 return flag; 00145 } 00146 00147 __device_inline float path_state_terminate_probability(KernelGlobals *kg, PathState *state, const float3 throughput) 00148 { 00149 if(state->flag & PATH_RAY_TRANSPARENT) { 00150 /* transparent rays treated separately */ 00151 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce) 00152 return 0.0f; 00153 else if(state->transparent_bounce <= kernel_data.integrator.transparent_min_bounce) 00154 return 1.0f; 00155 } 00156 else { 00157 /* other rays */ 00158 if((state->bounce >= kernel_data.integrator.max_bounce) || 00159 (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) || 00160 (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) || 00161 (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce)) 00162 return 0.0f; 00163 else if(state->bounce <= kernel_data.integrator.min_bounce) 00164 return 1.0f; 00165 } 00166 00167 /* probalistic termination */ 00168 return average(throughput); 00169 } 00170 00171 __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, float3 *light_L) 00172 { 00173 if(ray->t == 0.0f) 00174 return false; 00175 00176 bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, isect); 00177 00178 #ifdef __TRANSPARENT_SHADOWS__ 00179 if(result && kernel_data.integrator.transparent_shadows) { 00180 /* transparent shadows work in such a way to try to minimize overhead 00181 in cases where we don't need them. after a regular shadow ray is 00182 cast we check if the hit primitive was potentially transparent, and 00183 only in that case start marching. this gives on extra ray cast for 00184 the cases were we do want transparency. 00185 00186 also note that for this to work correct, multi close sampling must 00187 be used, since we don't pass a random number to shader_eval_surface */ 00188 if(shader_transparent_shadow(kg, isect)) { 00189 float3 throughput = make_float3(1.0f, 1.0f, 1.0f); 00190 float3 Pend = ray->P + ray->D*ray->t; 00191 int bounce = state->transparent_bounce; 00192 00193 for(;;) { 00194 if(bounce >= kernel_data.integrator.transparent_max_bounce) { 00195 return true; 00196 } 00197 else if(bounce >= kernel_data.integrator.transparent_min_bounce) { 00198 /* todo: get random number somewhere for probabilistic terminate */ 00199 #if 0 00200 float probability = average(throughput); 00201 float terminate = 0.0f; 00202 00203 if(terminate >= probability) 00204 return true; 00205 00206 throughput /= probability; 00207 #endif 00208 } 00209 00210 if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, isect)) { 00211 *light_L *= throughput; 00212 return false; 00213 } 00214 00215 if(!shader_transparent_shadow(kg, isect)) 00216 return true; 00217 00218 ShaderData sd; 00219 shader_setup_from_ray(kg, &sd, isect, ray); 00220 shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW); 00221 00222 throughput *= shader_bsdf_transparency(kg, &sd); 00223 00224 ray->P = ray_offset(sd.P, -sd.Ng); 00225 if(ray->t != FLT_MAX) 00226 ray->D = normalize_len(Pend - ray->P, &ray->t); 00227 00228 bounce++; 00229 } 00230 } 00231 } 00232 #endif 00233 00234 return result; 00235 } 00236 00237 __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, float3 throughput) 00238 { 00239 /* initialize */ 00240 float3 L = make_float3(0.0f, 0.0f, 0.0f); 00241 float Ltransparent = 0.0f; 00242 00243 #ifdef __EMISSION__ 00244 float ray_pdf = 0.0f; 00245 #endif 00246 PathState state; 00247 int rng_offset = PRNG_BASE_NUM; 00248 00249 path_state_init(&state); 00250 00251 /* path iteration */ 00252 for(;; rng_offset += PRNG_BOUNCE_NUM) { 00253 /* intersect scene */ 00254 Intersection isect; 00255 uint visibility = path_state_ray_visibility(kg, &state); 00256 00257 if(!scene_intersect(kg, &ray, visibility, &isect)) { 00258 /* eval background shader if nothing hit */ 00259 if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) { 00260 Ltransparent += average(throughput); 00261 } 00262 else { 00263 #ifdef __BACKGROUND__ 00264 ShaderData sd; 00265 shader_setup_from_background(kg, &sd, &ray); 00266 L += throughput*shader_eval_background(kg, &sd, state.flag); 00267 shader_release(kg, &sd); 00268 #else 00269 L += throughput*make_float3(0.8f, 0.8f, 0.8f); 00270 #endif 00271 } 00272 00273 break; 00274 } 00275 00276 /* setup shading */ 00277 ShaderData sd; 00278 shader_setup_from_ray(kg, &sd, &isect, &ray); 00279 float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); 00280 shader_eval_surface(kg, &sd, rbsdf, state.flag); 00281 00282 #ifdef __HOLDOUT__ 00283 if((sd.flag & SD_HOLDOUT) && (state.flag & PATH_RAY_CAMERA)) { 00284 float3 holdout_weight = shader_holdout_eval(kg, &sd); 00285 00286 if(kernel_data.background.transparent) 00287 Ltransparent += average(holdout_weight*throughput); 00288 } 00289 #endif 00290 00291 #ifdef __EMISSION__ 00292 /* emission */ 00293 if(sd.flag & SD_EMISSION) 00294 L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); 00295 #endif 00296 00297 /* path termination. this is a strange place to put the termination, it's 00298 mainly due to the mixed in MIS that we use. gives too many unneeded 00299 shader evaluations, only need emission if we are going to terminate */ 00300 float probability = path_state_terminate_probability(kg, &state, throughput); 00301 float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE); 00302 00303 if(terminate >= probability) 00304 break; 00305 00306 throughput /= probability; 00307 00308 #ifdef __EMISSION__ 00309 if(kernel_data.integrator.use_direct_light) { 00310 /* sample illumination from lights to find path contribution */ 00311 if(sd.flag & SD_BSDF_HAS_EVAL) { 00312 float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT); 00313 float light_o = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_F); 00314 float light_u = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_U); 00315 float light_v = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT_V); 00316 00317 Ray light_ray; 00318 float3 light_L; 00319 00320 #ifdef __MULTI_LIGHT__ 00321 /* index -1 means randomly sample from distribution */ 00322 int i = (kernel_data.integrator.num_distribution)? -1: 0; 00323 00324 for(; i < kernel_data.integrator.num_all_lights; i++) { 00325 #else 00326 const int i = -1; 00327 #endif 00328 if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &light_L)) { 00329 /* trace shadow ray */ 00330 if(!shadow_blocked(kg, &state, &light_ray, &isect, &light_L)) 00331 L += throughput*light_L; 00332 } 00333 #ifdef __MULTI_LIGHT__ 00334 } 00335 #endif 00336 } 00337 } 00338 #endif 00339 00340 /* no BSDF? we can stop here */ 00341 if(!(sd.flag & SD_BSDF)) 00342 break; 00343 00344 /* sample BSDF */ 00345 float bsdf_pdf; 00346 float3 bsdf_eval; 00347 float3 bsdf_omega_in; 00348 differential3 bsdf_domega_in; 00349 float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U); 00350 float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V); 00351 int label; 00352 00353 label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval, 00354 &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); 00355 00356 shader_release(kg, &sd); 00357 00358 if(bsdf_pdf == 0.0f || is_zero(bsdf_eval)) 00359 break; 00360 00361 /* modify throughput */ 00362 throughput *= bsdf_eval/bsdf_pdf; 00363 00364 /* set labels */ 00365 #ifdef __EMISSION__ 00366 ray_pdf = bsdf_pdf; 00367 #endif 00368 00369 /* update path state */ 00370 path_state_next(kg, &state, label); 00371 00372 /* setup ray */ 00373 ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng); 00374 ray.D = bsdf_omega_in; 00375 ray.t = FLT_MAX; 00376 #ifdef __RAY_DIFFERENTIALS__ 00377 ray.dP = sd.dP; 00378 ray.dD = bsdf_domega_in; 00379 #endif 00380 } 00381 00382 return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent); 00383 } 00384 00385 __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y, int offset, int stride) 00386 { 00387 /* initialize random numbers */ 00388 RNG rng; 00389 00390 float filter_u; 00391 float filter_v; 00392 00393 path_rng_init(kg, rng_state, sample, &rng, x, y, offset, stride, &filter_u, &filter_v); 00394 00395 /* sample camera ray */ 00396 Ray ray; 00397 00398 float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U); 00399 float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V); 00400 00401 camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray); 00402 00403 /* integrate */ 00404 #ifdef __MODIFY_TP__ 00405 float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, offset, stride, sample); 00406 float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput; 00407 #else 00408 float3 throughput = make_float3(1.0f, 1.0f, 1.0f); 00409 float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput); 00410 #endif 00411 00412 /* accumulate result in output buffer */ 00413 int index = offset + x + y*stride; 00414 00415 if(sample == 0) 00416 buffer[index] = L; 00417 else 00418 buffer[index] += L; 00419 00420 path_rng_end(kg, rng_state, rng, x, y, offset, stride); 00421 } 00422 00423 CCL_NAMESPACE_END 00424