Cycles: Fix OSL layering in combination with emission evaluation
When evaluating emission, no closures can be allocated, so the existing code would end up returning albedo 1.0, which then caused the layering code to set the weight of lower layers to zero.
This commit is contained in:
@@ -31,6 +31,17 @@ struct ccl_align(8) LayerClosure
|
||||
ccl_private const OSLClosure *top;
|
||||
};
|
||||
|
||||
/* If we failed to allocate a layerable closure, we need to zero out the albedo
|
||||
* so that lower layers aren't falsely blocked.
|
||||
* Therefore, to keep the code clean, set it to zero at the start and overwrite
|
||||
* later if it succeeded. */
|
||||
ccl_device_forceinline void osl_zero_albedo(float3 *layer_albedo)
|
||||
{
|
||||
if (layer_albedo != NULL) {
|
||||
*layer_albedo = zero_float3();
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_forceinline bool osl_closure_skip(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
@@ -182,6 +193,8 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
|
||||
ccl_private const DielectricBSDFClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
osl_zero_albedo(layer_albedo);
|
||||
|
||||
const bool has_reflection = !is_zero(closure->reflection_tint);
|
||||
const bool has_transmission = !is_zero(closure->transmission_tint);
|
||||
|
||||
@@ -240,8 +253,13 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
|
||||
fresnel->transmission_tint = rgb_to_spectrum(closure->transmission_tint);
|
||||
bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, preserve_energy);
|
||||
|
||||
if (layer_albedo != NULL && has_reflection && !has_transmission) {
|
||||
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
if (layer_albedo != NULL) {
|
||||
if (has_reflection && !has_transmission) {
|
||||
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
}
|
||||
else {
|
||||
*layer_albedo = one_float3();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,6 +317,8 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
|
||||
ccl_private const GeneralizedSchlickBSDFClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
osl_zero_albedo(layer_albedo);
|
||||
|
||||
const bool has_reflection = !is_zero(closure->reflection_tint);
|
||||
const bool has_transmission = !is_zero(closure->transmission_tint);
|
||||
|
||||
@@ -370,8 +390,13 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
|
||||
fresnel->exponent = closure->exponent;
|
||||
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy);
|
||||
|
||||
if (layer_albedo != NULL && has_reflection && !has_transmission) {
|
||||
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
if (layer_albedo != NULL) {
|
||||
if (has_reflection && !has_transmission) {
|
||||
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
}
|
||||
else {
|
||||
*layer_albedo = one_float3();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,6 +409,8 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
|
||||
ccl_private const MicrofacetClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
osl_zero_albedo(layer_albedo);
|
||||
|
||||
const int label = (closure->refract) ? LABEL_TRANSMIT : LABEL_REFLECT;
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | label)) {
|
||||
return;
|
||||
@@ -435,8 +462,13 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
|
||||
}
|
||||
}
|
||||
|
||||
if (layer_albedo != NULL && closure->refract == 0) {
|
||||
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
if (layer_albedo != NULL) {
|
||||
if (closure->refract == 0) {
|
||||
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
}
|
||||
else {
|
||||
*layer_albedo = one_float3();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,6 +514,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
|
||||
ccl_private const MicrofacetMultiGGXClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
osl_zero_albedo(layer_albedo);
|
||||
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
|
||||
return;
|
||||
}
|
||||
@@ -542,6 +576,8 @@ ccl_device void osl_closure_sheen_setup(KernelGlobals kg,
|
||||
ccl_private const SheenClosure *closure,
|
||||
float3 *layer_albedo)
|
||||
{
|
||||
osl_zero_albedo(layer_albedo);
|
||||
|
||||
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user