From b5a9c98e04fa9bd347ebb8bc4728559a13eb58e0 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 23 Jan 2024 01:20:12 +0100 Subject: [PATCH] Fix #117081: Wrong Roughness when baking Principled BSDF The pre-4.0 Principled BSDF had a special diffuse BSDF that contained the roughness value from the node. Since 4.0, the regular Diffuse BSDF is used, so we need to ignore it when determining the roughness value for baking. --- intern/cycles/kernel/closure/bsdf.h | 10 +++++----- intern/cycles/kernel/integrator/surface_shader.h | 11 +++++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 052d92f4f97..fd00b78ec5d 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -40,18 +40,18 @@ ccl_device_inline float bsdf_get_specular_roughness_squared(ccl_private const Sh return 1.0f; } -ccl_device_inline float bsdf_get_roughness_squared(ccl_private const ShaderClosure *sc) +ccl_device_inline float bsdf_get_roughness_pass_squared(ccl_private const ShaderClosure *sc) { - /* This version includes diffuse, mainly for baking Principled BSDF - * where specular and metallic zero otherwise does not bake the - * specified roughness parameter. */ if (sc->type == CLOSURE_BSDF_OREN_NAYAR_ID) { ccl_private OrenNayarBsdf *bsdf = (ccl_private OrenNayarBsdf *)sc; return sqr(sqr(bsdf->roughness)); } + /* For the Principled BSDF, we want the Roughness pass to return the value that + * was set in the node. However, this value doesn't affect all closures (e.g. + * diffuse), so skip those that don't really have a concept of roughness. */ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) { - return 0.0f; + return -1.0f; } return bsdf_get_specular_roughness_squared(sc); diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h index 22e2a56b8b7..2840b1f27bb 100644 --- a/intern/cycles/kernel/integrator/surface_shader.h +++ b/intern/cycles/kernel/integrator/surface_shader.h @@ -930,13 +930,16 @@ ccl_device float surface_shader_average_roughness(ccl_private const ShaderData * if (CLOSURE_IS_BSDF(sc->type)) { /* sqrt once to undo the squaring from multiplying roughness on the * two axes, and once for the squared roughness convention. */ - float weight = fabsf(average(sc->weight)); - roughness += weight * sqrtf(safe_sqrtf(bsdf_get_roughness_squared(sc))); - sum_weight += weight; + float value = bsdf_get_roughness_pass_squared(sc); + if (value >= 0.0f) { + float weight = fabsf(average(sc->weight)); + roughness += weight * sqrtf(sqrtf(value)); + sum_weight += weight; + } } } - return (sum_weight > 0.0f) ? roughness / sum_weight : 0.0f; + return (sum_weight > 0.0f) ? roughness / sum_weight : 1.0f; } ccl_device Spectrum surface_shader_transparency(KernelGlobals kg, ccl_private const ShaderData *sd)