Revert "Cycles: Fix inconsistency in Ng handling between Microfacets and other closures"

This reverts commit a6015e1411 in the
blender-v4.5-release branch to work around HIP compiler issues. It will
remain in the main branch.

Ref blender/blender#139836
This commit is contained in:
Brecht Van Lommel
2025-06-04 15:13:43 +02:00
parent 04e325029f
commit 34838a9531
6 changed files with 35 additions and 30 deletions

View File

@@ -532,15 +532,18 @@ ccl_device_inline
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
eval = bsdf_microfacet_ggx_eval(kg, sc, sd->wi, wo, pdf);
/* For consistency with eval() this should be using sd->Ng, but that causes
* artifacts (see shadow_terminator_metal test). Needs deeper investigation
* for how to solve this. */
eval = bsdf_microfacet_ggx_eval(kg, sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID:
eval = bsdf_microfacet_beckmann_eval(kg, sc, sd->wi, wo, pdf);
eval = bsdf_microfacet_beckmann_eval(kg, sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
eval = bsdf_ashikhmin_shirley_eval(sc, sd->wi, wo, pdf);
eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
eval = bsdf_ashikhmin_velvet_eval(sc, sd->wi, wo, pdf);

View File

@@ -46,11 +46,13 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(const float
}
ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(const ccl_private ShaderClosure *sc,
const float3 Ng,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
const ccl_private MicrofacetBsdf *bsdf = (const ccl_private MicrofacetBsdf *)sc;
const float cosNgO = dot(Ng, wo);
const float3 N = bsdf->N;
float NdotI = dot(N, wi);
@@ -58,7 +60,9 @@ ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(const ccl_private Sh
float out = 0.0f;
if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f || (NdotI < 0.0f) || (NdotO < 0.0f)) {
if ((cosNgO < 0.0f) || fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f ||
!(NdotI > 0.0f && NdotO > 0.0f))
{
*pdf = 0.0f;
return zero_spectrum();
}
@@ -204,13 +208,6 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ccl_private ShaderClosure *sc
/* reflect wi on H to get wo */
*wo = -wi + (2.0f * HdotI) * H;
/* Check hemisphere. */
if (dot(Ng, *wo) < 0.0f) {
*pdf = 0.0f;
*eval = zero_spectrum();
return LABEL_NONE;
}
if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
/* Some high number for MIS. */
*pdf = 1e6f;
@@ -219,7 +216,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ccl_private ShaderClosure *sc
}
else {
/* leave the rest to eval */
*eval = bsdf_ashikhmin_shirley_eval(sc, wi, *wo, pdf);
*eval = bsdf_ashikhmin_shirley_eval(sc, Ng, wi, *wo, pdf);
}
return label;

View File

@@ -564,6 +564,7 @@ ccl_device_forceinline int bsdf_microfacet_eval_flag(const ccl_private Microface
template<MicrofacetType m_type>
ccl_device Spectrum bsdf_microfacet_eval(KernelGlobals kg,
const ccl_private ShaderClosure *sc,
const float3 Ng,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
@@ -577,6 +578,7 @@ ccl_device Spectrum bsdf_microfacet_eval(KernelGlobals kg,
const float3 N = bsdf->N;
const float cos_NI = dot(N, wi);
const float cos_NO = dot(N, wo);
const float cos_NgO = dot(Ng, wo);
const float alpha_x = bsdf->alpha_x;
const float alpha_y = bsdf->alpha_y;
@@ -586,10 +588,11 @@ ccl_device Spectrum bsdf_microfacet_eval(KernelGlobals kg,
/* Check whether the pair of directions is valid for evaluation:
* - Incoming direction has to be in the upper hemisphere (Cycles convention)
* - Specular cases can't be evaluated, only sampled.
* - The outgoing direction has to be the in the same hemisphere w.r.t. both normals.
* - Purely reflective closures can't have refraction.
* - Purely refractive closures can't have reflection.
*/
if ((cos_NI <= 0) || !bsdf_microfacet_eval_flag(bsdf) ||
if ((cos_NI <= 0) || !bsdf_microfacet_eval_flag(bsdf) || ((cos_NgO < 0.0f) != is_transmission) ||
(is_transmission && !has_transmission) || (!is_transmission && !has_reflection))
{
return zero_spectrum();
@@ -729,16 +732,7 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg,
/* Compute actual reflected or refracted direction. */
*wo = do_refract ? refract_angle(wi, H, cos_HO, m_inv_eta) : 2.0f * cos_HI * H - wi;
/* Ensure that the sampled direction lies in the correct hemisphere.
* Note that the check against Ng is only performed in the sampling code, not the evaluation.
* This is technically inconsistent, but required in order to avoid shadow terminator artifacts
* on smooth geometry (which we'd get if we checked Ng in evaluation) while ensuring that
* sampling doesn't return supposed reflection rays going into the geometry and vice versa.
* The same is done for other closures as well. */
const float cos_NO = dot(N, *wo);
const float cos_NgO = dot(Ng, *wo);
if ((cos_NgO < 0) != do_refract || (cos_NO < 0) != do_refract) {
if ((dot(Ng, *wo) < 0) != do_refract) {
return LABEL_NONE;
}
@@ -982,12 +976,13 @@ ccl_device void bsdf_microfacet_blur(ccl_private ShaderClosure *sc, const float
ccl_device Spectrum bsdf_microfacet_ggx_eval(KernelGlobals kg,
const ccl_private ShaderClosure *sc,
const float3 Ng,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
const ccl_private MicrofacetBsdf *bsdf = (const ccl_private MicrofacetBsdf *)sc;
return bsdf->energy_scale * bsdf_microfacet_eval<MicrofacetType::GGX>(kg, sc, wi, wo, pdf);
return bsdf->energy_scale * bsdf_microfacet_eval<MicrofacetType::GGX>(kg, sc, Ng, wi, wo, pdf);
}
ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
@@ -1048,11 +1043,12 @@ ccl_device int bsdf_microfacet_beckmann_glass_setup(ccl_private MicrofacetBsdf *
ccl_device Spectrum bsdf_microfacet_beckmann_eval(KernelGlobals kg,
const ccl_private ShaderClosure *sc,
const float3 Ng,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
return bsdf_microfacet_eval<MicrofacetType::BECKMANN>(kg, sc, wi, wo, pdf);
return bsdf_microfacet_eval<MicrofacetType::BECKMANN>(kg, sc, Ng, wi, wo, pdf);
}
ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,

View File

@@ -65,10 +65,19 @@ ccl_device Spectrum bsdf_sheen_eval(const ccl_private ShaderClosure *sc,
const float a = bsdf->transformA;
const float b = bsdf->transformB;
if (dot(N, wo) <= 0.0f) {
*pdf = 0.0f;
return zero_spectrum();
}
const float3 localO = to_local(wo, T, B, N);
if (localO.z <= 0.0f) {
*pdf = 0.0f;
return zero_spectrum();
}
const float lenSqr = sqr(a * localO.x + b * localO.z) + sqr(a * localO.y) + sqr(localO.z);
const float val = M_1_PI_F * fmaxf(localO.z, 0.0f) * sqr(a / lenSqr);
const float val = M_1_PI_F * localO.z * sqr(a / lenSqr);
*pdf = val;
return make_spectrum(val);

Binary file not shown.

Binary file not shown.