[Bf-blender-cvs] [66c7d43a9e0] soc-2022-many-lights-sampling: Optimize light tree importance based on transmissive properties of materials
Brecht Van Lommel
noreply at git.blender.org
Fri Oct 7 14:46:38 CEST 2022
Commit: 66c7d43a9e0932ae5050678bc5908204545aa393
Author: Brecht Van Lommel
Date: Fri Oct 7 14:39:25 2022 +0200
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB66c7d43a9e0932ae5050678bc5908204545aa393
Optimize light tree importance based on transmissive properties of materials
If a light is guaranteed to be behind the surface we're sampling,
then we give it an importance of 0.
However, if the material we're sampling is transmissive/translucent,
then we don't apply this optimization as it introduces artifacts.
Still not 100% correct, see TODO comment.
https://developer.blender.org/D16097
===================================================================
M intern/cycles/kernel/closure/bsdf_diffuse.h
M intern/cycles/kernel/closure/bsdf_hair.h
M intern/cycles/kernel/closure/bsdf_hair_principled.h
M intern/cycles/kernel/closure/bsdf_microfacet.h
M intern/cycles/kernel/closure/bsdf_microfacet_multi.h
M intern/cycles/kernel/integrator/shade_background.h
M intern/cycles/kernel/integrator/shade_light.h
M intern/cycles/kernel/integrator/shade_surface.h
M intern/cycles/kernel/light/light_tree.h
M intern/cycles/kernel/types.h
===================================================================
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index c9c26754651..827b762f4c7 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -69,7 +69,7 @@ ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf)
{
bsdf->type = CLOSURE_BSDF_TRANSLUCENT_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device Spectrum bsdf_translucent_eval(ccl_private const ShaderClosure *sc,
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index a8ba4044758..989714bd695 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -34,7 +34,7 @@ ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
bsdf->type = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
bsdf->roughness1 = clamp(bsdf->roughness1, 0.001f, 1.0f);
bsdf->roughness2 = clamp(bsdf->roughness2, 0.001f, 1.0f);
- return SD_BSDF | SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *sc,
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
index 857b3fbf3a6..5a6465c7af6 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_principled.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -196,7 +196,7 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
- return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
}
#endif /* __HAIR__ */
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 4eb7cd5df22..39d0fb8f5f5 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -346,7 +346,7 @@ ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf *
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float roughness)
@@ -776,7 +776,7 @@ ccl_device int bsdf_microfacet_beckmann_refraction_setup(ccl_private MicrofacetB
bsdf->alpha_y = bsdf->alpha_x;
bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device void bsdf_microfacet_beckmann_blur(ccl_private ShaderClosure *sc, float roughness)
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index 73cc0d292a1..73bbe80b2d4 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -559,7 +559,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_setup(ccl_private MicrofacetBsdf
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private MicrofacetBsdf *bsdf,
diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index 84ea3f62dbd..e16f283b442 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -69,9 +69,9 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
bool eval_background = true;
float transparent = 0.0f;
+ int path_flag = INTEGRATOR_STATE(state, path, flag);
const bool is_transparent_background_ray = kernel_data.background.transparent &&
- (INTEGRATOR_STATE(state, path, flag) &
- PATH_RAY_TRANSPARENT_BACKGROUND);
+ (path_flag & PATH_RAY_TRANSPARENT_BACKGROUND);
if (is_transparent_background_ray) {
transparent = average(INTEGRATOR_STATE(state, path, throughput));
@@ -125,7 +125,7 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
float pdf = background_light_pdf(kg, ray_P, ray_D);
if (kernel_data.integrator.use_light_tree) {
const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
- pdf *= distant_lights_pdf(kg, ray_P, N, kernel_data.background.light_index);
+ pdf *= distant_lights_pdf(kg, ray_P, N, path_flag, kernel_data.background.light_index);
}
mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
}
@@ -191,7 +191,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
if (kernel_data.integrator.use_light_tree) {
const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
- ls.pdf *= distant_lights_pdf(kg, ray_P, N, lamp);
+ ls.pdf *= distant_lights_pdf(kg, ray_P, N, path_flag, lamp);
}
mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
}
diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h
index 177dcaa1aee..23ec965902f 100644
--- a/intern/cycles/kernel/integrator/shade_light.h
+++ b/intern/cycles/kernel/integrator/shade_light.h
@@ -66,7 +66,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
if (kernel_data.integrator.use_light_tree) {
const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
- ls.pdf *= light_tree_pdf(kg, state, ray_P, N, ~ls.lamp);
+ ls.pdf *= light_tree_pdf(kg, state, ray_P, N, path_flag, ~ls.lamp);
}
mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
}
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index 7cca49ba2b8..5d707cfe9ac 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -132,7 +132,8 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
const float3 N = INTEGRATOR_STATE(state, path, mis_origin_n);
uint lookup_offset = kernel_data_fetch(object_lookup_offset, sd->object);
uint prim_offset = kernel_data_fetch(object_prim_offset, sd->object);
- pdf *= light_tree_pdf(kg, state, ray_P, N, sd->prim - prim_offset + lookup_offset);
+ pdf *= light_tree_pdf(
+ kg, state, ray_P, N, path_flag, sd->prim - prim_offset + lookup_offset);
}
mis_weight = light_sample_mis_weight_forward(kg, bsdf_pdf, pdf);
}
@@ -170,6 +171,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
sd->time,
sd->P,
sd->N,
+ sd->flag,
bounce,
path_flag,
&ls)) {
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index dfd552e95e9..5ab9dfac254 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -35,6 +35,7 @@ ccl_device float light_tree_bounding_box_angle(const float3 bbox_min,
* Both of the specialized functions obtain the necessary data before calling this function. */
ccl_device float light_tree_node_importance(const float3 P,
const float3 N,
+ const bool has_transmission,
const float3 bbox_min,
const float3 bbox_max,
const float3 bcone_axis,
@@ -50,13 +51,8 @@ ccl_device float light_tree_node_importance(const float3 P,
const float distance_squared = fmaxf(0.25f * len_squared(centroid - bbox_max),
len_squared(centroid - P));
- /* to-do: should there be a different importance calculations for different surfaces?
- * opaque surfaces could just return 0 importance in this case. */
const float theta = fast_acosf(dot(bcone_axis, -point_to_centroid));
float theta_i = fast_acosf(dot(point_to_centroid, N));
- if (theta_i > M_PI_2_F) {
- theta_i = M_PI_F - theta_i;
- }
const float theta_u = light_tree_bounding_box_angle(bbox_min, bbox_max, P, point_to_centroid);
/* Avoid using cosine until needed. */
@@ -64,8 +60,18 @@ ccl_device float light_tree_node_importance(const float3 P,
if (theta_prime >= theta_e) {
return 0.0f;
}
- const float cos_theta_prime = fast_cosf(theta_prime);
+ /* If the node is guaranteed to be behind the surface we're sampling, and the surface is opaque,
+ * then we can give the node an importance of 0 as it contributes nothing to the surface. */
+ if (!has_transmission && (theta_i - theta_u > M_PI_2_F)) {
+ return 0.0f;
+ }
+
+ if (theta_i > M_PI_2_F) {
+ theta_i = M_PI_F - theta_i;
+ }
+
+ const float cos_theta_prime = fast_cosf(theta_prime);
float cos_theta_i_prime = 1.0f;
if (theta_i - theta_u > 0.0f) {
cos_theta_i_prime = fabsf(fast_cosf(theta_i - theta_u));
@@ -147,6 +153,7 @@ ccl_device float light_tree_emitter_reservoir_weight(KernelGlobals kg,
ccl_device float light_tree_emitter_importance(KernelGlobals kg,
const float3 P,
const float3 N,
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list