From 0007c7a6b2203b9831153808fb57305d9376696b Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Thu, 22 Feb 2024 12:24:12 +0100 Subject: [PATCH] Fix #115997: Emission sampling setting ignored when not using light tree if emission sampling is not set, we do not use MIS weight when sampling from the BSDF, but we were still drawing samples from the light, resulting in double contribution. Pull Request: https://projects.blender.org/blender/blender/pulls/118534 --- intern/cycles/kernel/light/triangle.h | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/intern/cycles/kernel/light/triangle.h b/intern/cycles/kernel/light/triangle.h index 50475b223eb..d3549358e60 100644 --- a/intern/cycles/kernel/light/triangle.h +++ b/intern/cycles/kernel/light/triangle.h @@ -135,18 +135,26 @@ ccl_device_forceinline bool triangle_light_sample(KernelGlobals kg, const float3 e1 = V[2] - V[0]; const float3 e2 = V[2] - V[1]; const float longest_edge_squared = max(len_squared(e0), max(len_squared(e1), len_squared(e2))); - const float3 N0 = cross(e0, e1); + float3 N0 = cross(e0, e1); + /* Flip normal if necessary. */ + const int object_flag = kernel_data_fetch(object_flag, object); + if (object_flag & SD_OBJECT_NEGATIVE_SCALE) { + N0 = -N0; + } + + /* Do not draw samples from the side without MIS. */ + ls->shader = kernel_data_fetch(tri_shader, prim); + const float distance_to_plane = dot(N0, V[0] - P) / dot(N0, N0); + const int ls_shader_flag = kernel_data_fetch(shaders, ls->shader & SHADER_MASK).flags; + if (!(ls_shader_flag & (distance_to_plane > 0 ? SD_MIS_BACK : SD_MIS_FRONT))) { + return false; + } + float Nl = 0.0f; ls->Ng = safe_normalize_len(N0, &Nl); const float area = 0.5f * Nl; - /* flip normal if necessary */ - const int object_flag = kernel_data_fetch(object_flag, object); - if (object_flag & SD_OBJECT_NEGATIVE_SCALE) { - ls->Ng = -ls->Ng; - } ls->eval_fac = 1.0f; - ls->shader = kernel_data_fetch(tri_shader, prim); ls->object = object; ls->prim = prim; ls->lamp = LAMP_NONE; @@ -154,8 +162,6 @@ ccl_device_forceinline bool triangle_light_sample(KernelGlobals kg, ls->type = LIGHT_TRIANGLE; ls->group = object_lightgroup(kg, object); - float distance_to_plane = fabsf(dot(N0, V[0] - P) / dot(N0, N0)); - if (!in_volume_segment && (longest_edge_squared > distance_to_plane * distance_to_plane)) { /* A modified version of James Arvo, "Stratified Sampling of Spherical Triangles" * http://www.graphics.cornell.edu/pubs/1995/Arv95c.pdf */