Fix: Cycles: wrong refractive index in path guiding
should be the relative IOR of the outgoing media to the incoming media, depending on `bsdf->ior` and whether the interaction is refraction. Reference paper: [Robust Fitting of Parallax-Aware Mixtures for Path Guiding](https://uni-tuebingen.de/fakultaeten/mathematisch-naturwissenschaftliche-fakultaet/fachbereiche/informatik/lehrstuehle/computergrafik/lehrstuhl/veroeffentlichungen/robust-fitting-of-parallax-aware-mixtures-for-path-guiding/) Eq (35) Pull Request: https://projects.blender.org/blender/blender/pulls/112157
This commit is contained in:
parent
c951464b8a
commit
e894e6a411
|
@ -196,10 +196,12 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
|||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_CHIANG_ID:
|
||||
label = bsdf_hair_chiang_sample(kg, sc, sd, rand, eval, wo, pdf, sampled_roughness, eta);
|
||||
label = bsdf_hair_chiang_sample(kg, sc, sd, rand, eval, wo, pdf, sampled_roughness);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_HUANG_ID:
|
||||
label = bsdf_hair_huang_sample(kg, sc, sd, rand, eval, wo, pdf, sampled_roughness, eta);
|
||||
label = bsdf_hair_huang_sample(kg, sc, sd, rand, eval, wo, pdf, sampled_roughness);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_SHEEN_ID:
|
||||
label = bsdf_sheen_sample(sc, Ng, sd->wi, rand_xy, eval, wo, pdf);
|
||||
|
@ -247,6 +249,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
|||
|
||||
ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
||||
ccl_private const ShaderClosure *sc,
|
||||
const float3 wo,
|
||||
ccl_private float2 *roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
|
@ -290,12 +293,7 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
|||
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
if (CLOSURE_IS_REFRACTION(bsdf->type) || CLOSURE_IS_GLASS(bsdf->type)) {
|
||||
*eta = 1.0f / bsdf->ior;
|
||||
}
|
||||
else {
|
||||
*eta = bsdf->ior;
|
||||
}
|
||||
*eta = (bsdf_is_transmission(sc, wo)) ? bsdf->ior : 1.0f;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
|
||||
|
@ -330,12 +328,12 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
|||
case CLOSURE_BSDF_HAIR_CHIANG_ID:
|
||||
alpha = ((ccl_private ChiangHairBSDF *)sc)->m0_roughness;
|
||||
*roughness = make_float2(alpha, alpha);
|
||||
*eta = ((ccl_private ChiangHairBSDF *)sc)->eta;
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_HUANG_ID:
|
||||
alpha = ((ccl_private HuangHairBSDF *)sc)->roughness;
|
||||
*roughness = make_float2(alpha, alpha);
|
||||
*eta = ((ccl_private HuangHairBSDF *)sc)->eta;
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_SHEEN_ID:
|
||||
alpha = ((ccl_private SheenBsdf *)sc)->roughness;
|
||||
|
|
|
@ -683,7 +683,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
|
|||
}
|
||||
|
||||
*sampled_roughness = make_float2(alpha_x, alpha_y);
|
||||
*eta = do_refract ? m_inv_eta : m_eta;
|
||||
*eta = do_refract ? m_eta : 1.0f;
|
||||
|
||||
return (do_refract ? LABEL_TRANSMIT : LABEL_REFLECT) |
|
||||
(m_singular ? LABEL_SINGULAR : LABEL_GLOSSY);
|
||||
|
|
|
@ -335,13 +335,11 @@ ccl_device int bsdf_hair_chiang_sample(KernelGlobals kg,
|
|||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *wo,
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
ccl_private float2 *sampled_roughness)
|
||||
{
|
||||
ccl_private ChiangHairBSDF *bsdf = (ccl_private ChiangHairBSDF *)sc;
|
||||
|
||||
*sampled_roughness = make_float2(bsdf->m0_roughness, bsdf->m0_roughness);
|
||||
*eta = bsdf->eta;
|
||||
|
||||
const float3 Y = bsdf->N;
|
||||
|
||||
|
|
|
@ -614,14 +614,12 @@ ccl_device int bsdf_hair_huang_sample(const KernelGlobals kg,
|
|||
ccl_private Spectrum *eval,
|
||||
ccl_private float3 *wo,
|
||||
ccl_private float *pdf,
|
||||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
ccl_private float2 *sampled_roughness)
|
||||
{
|
||||
ccl_private HuangHairBSDF *bsdf = (ccl_private HuangHairBSDF *)sc;
|
||||
|
||||
const float roughness = bsdf->roughness;
|
||||
*sampled_roughness = make_float2(roughness, roughness);
|
||||
*eta = bsdf->eta;
|
||||
|
||||
kernel_assert(fabsf(bsdf->h) < bsdf->extra->radius);
|
||||
|
||||
|
@ -680,7 +678,7 @@ ccl_device int bsdf_hair_huang_sample(const KernelGlobals kg,
|
|||
}
|
||||
|
||||
float cos_theta_t1;
|
||||
const float R1 = fresnel_dielectric(dot(wi, wh1), *eta, &cos_theta_t1);
|
||||
const float R1 = fresnel_dielectric(dot(wi, wh1), bsdf->eta, &cos_theta_t1);
|
||||
const float scale1 = bsdf_hair_huang_energy_scale(kg, cos_mi1, sqrt_roughness, bsdf->eta);
|
||||
const float R = bsdf->extra->R * R1 * scale1 * microfacet_visible(wr, wmi_, wh1) *
|
||||
bsdf_Go(roughness2, cos_mi1, dot(wmi, wr));
|
||||
|
@ -717,7 +715,7 @@ ccl_device int bsdf_hair_huang_sample(const KernelGlobals kg,
|
|||
const float T2 = 1.0f - R2;
|
||||
const float scale2 = bsdf_hair_huang_energy_scale(kg, cos_mi2, sqrt_roughness, inv_eta);
|
||||
|
||||
wtt = refract_angle(-wt, wh2, cos_theta_t2, *eta);
|
||||
wtt = refract_angle(-wt, wh2, cos_theta_t2, bsdf->eta);
|
||||
|
||||
if (dot(wmt, -wtt) > 0.0f && cos_theta_t2 != 0.0f && microfacet_visible(-wtt, wmt_, wh2)) {
|
||||
TT = bsdf->extra->TT * T1 * A_t * T2 * scale2 * bsdf_Go(roughness2, cos_mi2, dot(wmt, -wtt));
|
||||
|
@ -733,7 +731,7 @@ ccl_device int bsdf_hair_huang_sample(const KernelGlobals kg,
|
|||
float cos_theta_t3;
|
||||
const float R3 = fresnel_dielectric(dot(wtr, wh3), inv_eta, &cos_theta_t3);
|
||||
|
||||
wtrt = refract_angle(wtr, wh3, cos_theta_t3, *eta);
|
||||
wtrt = refract_angle(wtr, wh3, cos_theta_t3, bsdf->eta);
|
||||
|
||||
const float cos_mi3 = dot(wmtr, wtr);
|
||||
if (cos_mi3 > 0.0f) {
|
||||
|
|
|
@ -15,6 +15,7 @@ CCL_NAMESPACE_BEGIN
|
|||
struct GuidingRISSample {
|
||||
float3 rand;
|
||||
float2 sampled_roughness;
|
||||
/* The relative ior of the outgoing media and the incoming media. */
|
||||
float eta{1.0f};
|
||||
int label;
|
||||
float3 wo;
|
||||
|
|
|
@ -209,7 +209,7 @@ ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg,
|
|||
}
|
||||
|
||||
/* BSDF */
|
||||
#if 0
|
||||
#ifdef WITH_CYCLES_DEBUG
|
||||
ccl_device_inline void surface_shader_validate_bsdf_sample(const KernelGlobals kg,
|
||||
const ShaderClosure *sc,
|
||||
const float3 wo,
|
||||
|
@ -224,7 +224,7 @@ ccl_device_inline void surface_shader_validate_bsdf_sample(const KernelGlobals k
|
|||
|
||||
float2 comp_roughness;
|
||||
float comp_eta;
|
||||
bsdf_roughness_eta(kg, sc, &comp_roughness, &comp_eta);
|
||||
bsdf_roughness_eta(kg, sc, wo, &comp_roughness, &comp_eta);
|
||||
kernel_assert(org_eta == comp_eta);
|
||||
kernel_assert(org_roughness.x == comp_roughness.x);
|
||||
kernel_assert(org_roughness.y == comp_roughness.y);
|
||||
|
@ -550,10 +550,10 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_mis(KernelGlobals kg,
|
|||
unguided_bsdf_pdf,
|
||||
sampled_roughness,
|
||||
eta);
|
||||
# if 0
|
||||
// Code path to validate the estimation of the label, sampled roughness and eta
|
||||
// This should be activated from time to time when the BSDFs change to check if everything
|
||||
// is still working correctly.
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
/* Code path to validate the estimation of the label, sampled roughness and eta. This should be
|
||||
* activated from time to time when the BSDFs change to check if everything is still working
|
||||
* correctly. */
|
||||
if (*unguided_bsdf_pdf > 0.0f) {
|
||||
surface_shader_validate_bsdf_sample(kg, sc, *wo, label, *sampled_roughness, *eta);
|
||||
}
|
||||
|
@ -773,7 +773,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg,
|
|||
idx = (rnd > sum_pdfs) ? sd->num_closure - 1 : idx;
|
||||
|
||||
label = bsdf_label(kg, &sd->closure[idx], *wo);
|
||||
bsdf_roughness_eta(kg, &sd->closure[idx], sampled_roughness, eta);
|
||||
bsdf_roughness_eta(kg, &sd->closure[idx], *wo, sampled_roughness, eta);
|
||||
}
|
||||
|
||||
kernel_assert(isfinite_safe(*bsdf_pdf));
|
||||
|
@ -793,7 +793,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg,
|
|||
unguided_bsdf_pdf,
|
||||
sampled_roughness,
|
||||
eta);
|
||||
# if 0
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
// Code path to validate the estimation of the label, sampled roughness and eta
|
||||
// This should be activated from time to time when the BSDFs change to check if everything
|
||||
// is still working correctly.
|
||||
|
|
Loading…
Reference in New Issue