From 3c553fe0b3b8225686a689f830f98f9cb88c092f Mon Sep 17 00:00:00 2001 From: Tomas Davidovic Date: Mon, 24 Aug 2026 18:16:50 +0200 Subject: [PATCH] Fix ADD accumulation in testrender closure walkers Assisted-by: OpenAI Codex / GPT-5 Signed-off-by: Tomas Davidovic --- src/testrender/shading.cpp | 50 +++++++++++++--------- testsuite/render-background/envmap.osl | 3 +- testsuite/render-mx-layer/layer_add.osl | 18 ++++++++ testsuite/render-mx-layer/ref/out_add.exr | Bin 0 -> 37548 bytes testsuite/render-mx-layer/run.py | 3 +- testsuite/render-mx-layer/scene_add.xml | 20 +++++++++ 6 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 testsuite/render-mx-layer/layer_add.osl create mode 100644 testsuite/render-mx-layer/ref/out_add.exr create mode 100644 testsuite/render-mx-layer/scene_add.xml diff --git a/src/testrender/shading.cpp b/src/testrender/shading.cpp index 113721554..28d1b7c3d 100644 --- a/src/testrender/shading.cpp +++ b/src/testrender/shading.cpp @@ -1208,17 +1208,19 @@ evaluate_layer_opacity(const ShaderGlobalsType& sg, float path_roughness, int stack_idx = 0; const ClosureColor* ptr_stack[STACK_SIZE]; Color3 weight_stack[STACK_SIZE]; - Color3 weight = Color3(1.0f); + // Track the active branch separately from completed branch contributions. + Color3 branch_weight = Color3(1.0f); + Color3 accumulated_weight = Color3(0.0f); while (closure) { switch (closure->id) { case ClosureColor::MUL: - weight *= closure->as_mul()->weight; + branch_weight *= closure->as_mul()->weight; closure = closure->as_mul()->closure; break; case ClosureColor::ADD: ptr_stack[stack_idx] = closure->as_add()->closureB; - weight_stack[stack_idx++] = weight; + weight_stack[stack_idx++] = branch_weight; closure = closure->as_add()->closureA; break; default: { @@ -1229,13 +1231,13 @@ evaluate_layer_opacity(const ShaderGlobalsType& sg, float path_roughness, const MxLayerParams* srcparams = comp->as(); closure = srcparams->top; ptr_stack[stack_idx] = srcparams->base; - weight_stack[stack_idx++] = weight * w; + weight_stack[stack_idx++] = branch_weight * w; break; } case REFLECTION_ID: case FRESNEL_REFLECTION_ID: { Reflection bsdf(*comp->as()); - weight *= w * bsdf.get_albedo(-sg.I); + branch_weight *= w * bsdf.get_albedo(-sg.I); closure = nullptr; break; } @@ -1243,7 +1245,7 @@ evaluate_layer_opacity(const ShaderGlobalsType& sg, float path_roughness, const MxDielectric::Data& params = *comp->as(); MxDielectric d(params, -sg.I, sg.backfacing, path_roughness); - weight *= w * (Color3(1) - d.filter_o(-sg.I).toRGB(0)); + branch_weight *= w * (Color3(1) - d.filter_o(-sg.I).toRGB(0)); closure = nullptr; break; } @@ -1257,13 +1259,13 @@ evaluate_layer_opacity(const ShaderGlobalsType& sg, float path_roughness, } MxGeneralizedSchlick d(params, -sg.I, sg.backfacing, path_roughness); - weight *= w * (Color3(1) - d.filter_o(-sg.I).toRGB(0)); + branch_weight *= w * (Color3(1) - d.filter_o(-sg.I).toRGB(0)); break; } case MxSheen::closureid(): { const MxSheen::Data& params = *comp->as(); MxSheen d(params, -sg.I, sg.backfacing, path_roughness); - weight *= w * (Color3(1) - d.filter_o(-sg.I).toRGB(0)); + branch_weight *= w * (Color3(1) - d.filter_o(-sg.I).toRGB(0)); closure = nullptr; break; } @@ -1273,12 +1275,15 @@ evaluate_layer_opacity(const ShaderGlobalsType& sg, float path_roughness, } } } - if (closure == nullptr && stack_idx > 0) { - closure = ptr_stack[--stack_idx]; - weight = weight_stack[stack_idx]; + if (closure == nullptr) { + accumulated_weight += branch_weight; + if (stack_idx > 0) { + closure = ptr_stack[--stack_idx]; + branch_weight = weight_stack[stack_idx]; + } } } - return weight; + return accumulated_weight; } OSL_HOSTDEVICE void @@ -1716,33 +1721,38 @@ process_background_closure(const ClosureColor* closure) int stack_idx = 0; const ClosureColor* ptr_stack[STACK_SIZE]; Color3 weight_stack[STACK_SIZE]; - Color3 weight = Color3(1.0f); + // Track the active branch separately from completed branch contributions. + Color3 branch_weight = Color3(1.0f); + Color3 accumulated_weight = Color3(0.0f); while (closure) { switch (closure->id) { case ClosureColor::MUL: { - weight *= closure->as_mul()->weight; + branch_weight *= closure->as_mul()->weight; closure = closure->as_mul()->closure; break; } case ClosureColor::ADD: { ptr_stack[stack_idx] = closure->as_add()->closureB; - weight_stack[stack_idx++] = weight; + weight_stack[stack_idx++] = branch_weight; closure = closure->as_add()->closureA; break; } case BACKGROUND_ID: { - weight *= closure->as_comp()->w; + branch_weight *= closure->as_comp()->w; closure = nullptr; break; } } - if (closure == nullptr && stack_idx > 0) { - closure = ptr_stack[--stack_idx]; - weight = weight_stack[stack_idx]; + if (closure == nullptr) { + accumulated_weight += branch_weight; + if (stack_idx > 0) { + closure = ptr_stack[--stack_idx]; + branch_weight = weight_stack[stack_idx]; + } } } - return weight; + return accumulated_weight; } OSL_HOSTDEVICE Color3 diff --git a/testsuite/render-background/envmap.osl b/testsuite/render-background/envmap.osl index 7e5906f05..11528a7a0 100644 --- a/testsuite/render-background/envmap.osl +++ b/testsuite/render-background/envmap.osl @@ -11,5 +11,6 @@ shader envmap(float Kb = 1, string filename = "") float tu = 0.5 + r * cos(radial); float tv = 0.5 - r * sin(radial); color c = texture(filename, tu, tv); - Ci = Kb * c * background(); + Ci = Kb * c * color(1, 1, 0) * background() + + Kb * c * color(0, 0, 1) * background(); } diff --git a/testsuite/render-mx-layer/layer_add.osl b/testsuite/render-mx-layer/layer_add.osl new file mode 100644 index 000000000..50ea7a7cf --- /dev/null +++ b/testsuite/render-mx-layer/layer_add.osl @@ -0,0 +1,18 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +surface layer_add(int distributed = 0) +{ + closure color red + = oren_nayar_diffuse_bsdf(N, color(1, 0, 0), 0.3); + closure color blue + = oren_nayar_diffuse_bsdf(N, color(0, 0, 1), 0.3); + closure color green + = oren_nayar_diffuse_bsdf(N, color(0, 1, 0), 0.3); + + if (distributed) + Ci = 0.5 * layer(red, green) + 0.5 * layer(blue, green); + else + Ci = layer(0.5 * red + 0.5 * blue, green); +} diff --git a/testsuite/render-mx-layer/ref/out_add.exr b/testsuite/render-mx-layer/ref/out_add.exr new file mode 100644 index 0000000000000000000000000000000000000000..f74cdfbc85db129fc46f89c32d9921aea2c32149 GIT binary patch literal 37548 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

pQ!DMQP$CwrKbhE-skm8i*j|&xiyOwv$l9?^(Vr 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 EmeT9f-v9sr literal 0 HcmV?d00001 diff --git a/testsuite/render-mx-layer/run.py b/testsuite/render-mx-layer/run.py index 5e7591b97..51d5915b9 100755 --- a/testsuite/render-mx-layer/run.py +++ b/testsuite/render-mx-layer/run.py @@ -8,5 +8,6 @@ hardfail = 0.05 idiff_program = "idiff" -outputs = [ "out.exr" ] +outputs = [ "out.exr", "out_add.exr" ] command = testrender("-r 160 120 -aa 6 scene.xml out.exr") +command += testrender("-r 160 120 -aa 6 scene_add.xml out_add.exr") diff --git a/testsuite/render-mx-layer/scene_add.xml b/testsuite/render-mx-layer/scene_add.xml new file mode 100644 index 000000000..0d6b0160c --- /dev/null +++ b/testsuite/render-mx-layer/scene_add.xml @@ -0,0 +1,20 @@ + + + + + shader envmap layer1; + + + + + param int distributed 0; + shader layer_add layer1; + + + + + param int distributed 1; + shader layer_add layer1; + + +