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.
This commit is contained in:
Lukas Stockner 2024-01-23 01:20:12 +01:00
parent a4a8683788
commit b5a9c98e04
2 changed files with 12 additions and 9 deletions

@ -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);

@ -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)