[Bf-blender-cvs] [94af4326e3f] gsoc-2018-many-light-sampling: Cycles: Light tree: volume and MIS fixes
Erik Englesson
noreply at git.blender.org
Fri Aug 3 17:32:10 CEST 2018
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. @@
More information about the Bf-blender-cvs
mailing list