Işın izleyicime bir mikrofacet BRDF uygulamaya çalışıyorum ama bazı sorunlarla karşılaşıyorum. Okuduğum birçok makale ve makale, kısmi geometri terimini görünüm ve yarım vektörlerin bir fonksiyonu olarak tanımlamaktadır: G1 (v, h). Ancak, bunu uygularken aşağıdaki sonucu aldım:
(Alt sıra 1.0 - 0.0 pürüzlü dielektrik, Üst sıra 1.0 - 0.0 pürüzlü metalik)
Kenarlarda garip bir vurgu ve nl == 0 civarında bir kesim var. Bunun nereden geldiğini gerçekten anlayamadım. Ben onların render ve kontrol etmek için bir referans olarak Unity kullanıyorum ne kullandıklarını görmek için gölgelendirici kaynak kontrol ve geometri terim hiç yarım vektör tarafından parametreleştirilmiş değil ne söyleyebilirim! Bu yüzden aynı kodu denedim ama yarım vektör yerine normal makro yüzeyine kullanılır ve aşağıdaki sonucu elde ettim:
Eğitimsiz gözüme göre bu istenen sonuca çok daha yakın görünüyor. Ama bunun doğru olmadığını hissediyorum? Okuduğum makalelerin çoğunda yarım vektör kullanılıyor, ancak hepsi kullanılmıyor. Bu farkın bir nedeni var mı?
Geometri terimi olarak aşağıdaki kodu kullanıyorum:
float RayTracer::GeometryGGX(const Vector3& v, const Vector3& l, const Vector3& n, const Vector3& h, float a)
{
return G1GGX(v, h, a) * G1GGX(l, h, a);
}
float RayTracer::G1GGX(const Vector3& v, const Vector3& h, float a)
{
float NoV = Util::Clamp01(cml::dot(v, h));
float a2 = a * a;
return (2.0f * NoV) / std::max(NoV + sqrt(a2 + (1.0f - a2) * NoV * NoV), 1e-7f);
}
Ve referans olarak, bu benim normal dağıtım fonksiyonum:
float RayTracer::DistributionGGX(const Vector3& n, const Vector3& h, float alpha)
{
float alpha2 = alpha * alpha;
float NoH = Util::Clamp01(cml::dot(n, h));
float denom = (NoH * NoH * (alpha2 - 1.0f)) + 1.0f;
return alpha2 / std::max((float)PI * denom * denom, 1e-7f);
}