Commit: 94af4326e3fc22fe1b229a3e2435fb6ccfe36ce9 Author: Erik Englesson Date: Thu Aug 2 19:21:01 2018 +0200 Branches: gsoc-2018-many-light-sampling https://developer.blender.org/rB94af4326e3fc22fe1b229a3e2435fb6ccfe36ce9
Cycles: Light tree: volume and MIS fixes Now using a more reliable way of knowing if a shading point is inside or on the boundary of a volume. Fixed a bug in light_background_sample() that used an index into the lights array as an index into the distribution array. =================================================================== M intern/cycles/kernel/kernel_emission.h M intern/cycles/kernel/kernel_light.h M intern/cycles/kernel/kernel_path.h M intern/cycles/kernel/kernel_path_branched.h M intern/cycles/kernel/kernel_path_surface.h M intern/cycles/kernel/kernel_path_volume.h M intern/cycles/kernel/kernel_types.h M intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h =================================================================== diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 8fe773f5a4b..95aebe1246f 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -198,7 +198,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, /* Indirect Primitive Emission */ -ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, float3 P, float3 N, int path_flag, float bsdf_pdf, bool is_volume_boundary) +ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, float3 P, float3 N, int path_flag, float bsdf_pdf, bool has_volume) { /* evaluate emissive closure */ float3 L = shader_emissive_eval(kg, sd); @@ -212,7 +212,7 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader /* multiple importance sampling, get triangle light pdf, * and compute weight with respect to BSDF pdf */ float pdf = triangle_light_pdf(kg, sd, t); - pdf *= light_distribution_pdf(kg, P, N, sd->prim, sd->object, is_volume_boundary); + pdf *= light_distribution_pdf(kg, P, N, sd->prim, sd->object, has_volume); float mis_weight = power_heuristic(bsdf_pdf, pdf); return L*mis_weight; @@ -260,7 +260,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, ls.t, ray->time); - bool is_inside_volume = false; + bool has_volume = false; #ifdef __VOLUME__ if(state->volume_stack[0].shader != SHADER_NONE) { /* shadow attenuation */ @@ -271,9 +271,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, L *= volume_tp; } - if((state->volume_bounce > 0 || (state->volume_bounds_bounce > 0)) && (emission_sd->flag & SD_HAS_VOLUME)) { - is_inside_volume = true; - } + has_volume = ((emission_sd->flag & SD_HAS_VOLUME) != 0); #endif if(!(state->flag & PATH_RAY_MIS_SKIP)) { @@ -281,7 +279,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, * and compute weight with respect to BSDF pdf */ /* multiply with light picking probablity to pdf */ - ls.pdf *= light_distribution_pdf(kg, ray->P, N, ~ls.lamp, -1, is_inside_volume); + ls.pdf *= light_distribution_pdf(kg, ray->P, N, ~ls.lamp, -1, has_volume); float mis_weight = power_heuristic(state->ray_pdf, ls.pdf); L *= mis_weight; } @@ -315,6 +313,11 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, return make_float3(0.0f, 0.0f, 0.0f); } + bool has_volume = false; +#if defined(__BACKGROUND_MIS__) && defined(__VOLUME__) + /* This has to be done before shader_setup_* below. */ + has_volume = ((emission_sd->flag & SD_HAS_VOLUME) != 0); +#endif /* evaluate background closure */ # ifdef __SPLIT_KERNEL__ Ray priv_ray = *ray; @@ -340,15 +343,6 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, N_pick = state->ray_N; } - /* todo: looks like this only happens for volume boundaries and not inside. - * is this expected? */ - bool is_on_volume_boundary = false; -#ifdef __VOLUME__ - if((state->volume_bounce > 0) || (state->volume_bounds_bounce > 0)) { - is_on_volume_boundary = true; - } -#endif - /* check if background light exists or if we should skip pdf */ int res_x = kernel_data.integrator.pdf_background_res_x; @@ -357,7 +351,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, * direction, and compute weight with respect to BSDF pdf */ float pdf = background_light_pdf(kg, P_pick, ray->D); int background_index = kernel_data.integrator.background_light_index; - pdf *= light_distribution_pdf(kg, P_pick, N_pick, ~background_index, -1, is_on_volume_boundary); + pdf *= light_distribution_pdf(kg, P_pick, N_pick, ~background_index, -1, has_volume); float mis_weight = power_heuristic(state->ray_pdf, pdf); return L*mis_weight; diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 409831081ae..26f93aba12a 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -1256,7 +1256,7 @@ ccl_device void light_distant_sample(KernelGlobals *kg, float3 P, float *randu, /* picks one of the background lights and computes the probability of picking it */ ccl_device void light_background_sample(KernelGlobals *kg, float3 P, float *randu, int *index, float *pdf){ - *index = kernel_data.integrator.background_light_index; + *index = kernel_tex_fetch(__lamp_to_distribution, kernel_data.integrator.background_light_index); *pdf = 1.0f; } @@ -1464,7 +1464,7 @@ ccl_device float light_bvh_pdf(KernelGlobals *kg, float3 P, float3 N, /* computes the the probability of picking the given light out of all lights */ ccl_device float light_distribution_pdf(KernelGlobals *kg, float3 P, float3 N, int prim_id, int object_id, - bool is_inside_volume) + bool has_volume) { /* convert from triangle/lamp to light distribution */ int distribution_id; @@ -1479,7 +1479,7 @@ ccl_device float light_distribution_pdf(KernelGlobals *kg, float3 P, float3 N, (distribution_id < kernel_data.integrator.num_distribution)); /* compute picking pdf for this light */ - if (kernel_data.integrator.use_light_bvh && !is_inside_volume){ + if (kernel_data.integrator.use_light_bvh && !has_volume){ /* find out which group of lights to sample */ int group; if(prim_id >= 0){ @@ -1520,10 +1520,10 @@ ccl_device float light_distribution_pdf(KernelGlobals *kg, float3 P, float3 N, /* picks a light and returns its index and the probability of picking it */ ccl_device void light_distribution_sample(KernelGlobals *kg, float3 P, float3 N, - bool is_in_volume, float *randu, + bool has_volume, float *randu, int *index, float *pdf) { - if (kernel_data.integrator.use_light_bvh && !is_in_volume){ + if (kernel_data.integrator.use_light_bvh && !has_volume){ /* sample light type distribution */ int group = light_group_distribution_sample(kg, randu); float group_prob = kernel_tex_fetch(__light_group_sample_prob, group); @@ -1592,12 +1592,12 @@ ccl_device_noinline bool light_sample(KernelGlobals *kg, float3 N, int bounce, LightSample *ls, - bool is_in_volume) + bool has_volume) { /* sample index and compute light picking pdf */ float pdf_factor = 0.0f; int index = -1; - light_distribution_sample(kg, P, N, is_in_volume, &randu, &index, &pdf_factor); + light_distribution_sample(kg, P, N, has_volume, &randu, &index, &pdf_factor); if(pdf_factor == 0.0f){ return false; diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 097c5640f54..83283247483 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -286,7 +286,8 @@ ccl_device_forceinline bool kernel_path_shader_apply( float3 throughput, ShaderData *emission_sd, PathRadiance *L, - ccl_global float *buffer) + ccl_global float *buffer, + bool has_volume) { #ifdef __SHADOW_TRICKS__ if((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) { @@ -363,8 +364,7 @@ ccl_device_forceinline bool kernel_path_shader_apply( float ray_length = state->ray_t + sd->ray_length; - bool is_volume_boundary = (state->volume_bounce > 0) || (state->volume_bounds_bounce > 0); - float3 emission = indirect_primitive_emission(kg, sd, ray_length, P_pick, N_pick, state->flag, state->ray_pdf, is_volume_boundary); + float3 emission = indirect_primitive_emission(kg, sd, ray_length, P_pick, N_pick, state->flag, state->ray_pdf, has_volume); path_radiance_accum_emission(L, state, throughput, emission); } #endif /* __EMISSION__ */ @@ -477,6 +477,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, } /* Setup shader data. */ + bool has_volume = (sd->flag & SD_HAS_VOLUME) != 0; shader_setup_from_ray(kg, sd, &isect, ray); /* Skip most work for volume bounding surface. */ @@ -496,7 +497,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, throughput, emission_sd, L, - NULL)) + NULL, + has_volume)) { break; } @@ -651,6 +653,7 @@ ccl_device_forceinline void kernel_path_integrate( } /* Setup shader data. */ + bool has_volume = (sd.flag & SD_HAS_VOLUME) != 0; shader_setup_from_ray(kg, &sd, &isect, ray); /* Skip most work for volume bounding surface. */ @@ -670,7 +673,8 @@ ccl_device_forceinline void kernel_path_integrate( throughput, emission_sd, L, - buffer)) + buffer, + has_volume)) { break; } diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index d9e1433acda..b1c815b6a15 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -463,6 +463,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, * Indirect bounces are handled in kernel_branched_path_surface_indirect_light(). */ for(;;) { + /* Find intersection with objects in scene. */ Intersection isect; bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L); @@ -488,6 +489,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, } /* Setup and evaluate shader. */ + bool has_volume = (sd.flag & SD_HAS_VOLUME) != 0; shader_setup_from_ray(kg, &sd, &isect, &ray); /* Skip most work for volume bounding surface. */ @@ -50 @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs