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. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
