मैं अपनी किरण में एक माइक्रोफेट बीआरडीएफ को लागू करने की कोशिश कर रहा हूं, लेकिन मैं कुछ मुद्दों में भाग रहा हूं। बहुत सारे कागजात और लेख जो मैंने पढ़े हैं, वे आंशिक ज्यामिति शब्द को देखने और आधे वैक्टर के कार्य के रूप में परिभाषित करते हैं: G1 (v, h)। हालाँकि, इसे लागू करते समय मुझे निम्नलिखित परिणाम मिले:
(नीचे पंक्ति खुरदरापन 1.0 - 0.0 के साथ ढांकता हुआ है, शीर्ष पंक्ति खुरदरापन 1.0 - 0.0 के साथ धात्विक है)
किनारों के चारों ओर एक अजीब आकर्षण है और nl == के आसपास एक कट-ऑफ है। 0. मैं वास्तव में यह पता नहीं लगा सका कि यह कहां से आता है। मैं अपने रेंडर को जांचने के लिए एक संदर्भ के रूप में यूनिटी का उपयोग कर रहा हूं, इसलिए मैंने उनके शेडर स्रोत की जांच की कि वे क्या उपयोग करते हैं और जो मैं बता सकता हूं कि उनका ज्यामिति शब्द अर्ध वेक्टर द्वारा पैराट्राइज्ड नहीं है! इसलिए मैंने एक ही कोड की कोशिश की, लेकिन आधे वेक्टर के बजाय सामान्य सतह का उपयोग किया और निम्न परिणाम प्राप्त किया:
मेरी अप्रशिक्षित आंख के लिए यह वांछित परिणाम के करीब लगता है। लेकिन मुझे लग रहा है कि यह सही नहीं है? मेरे द्वारा पढ़े गए अधिकांश लेखों में आधे वेक्टर का उपयोग होता है, लेकिन उन सभी का नहीं। क्या इस अंतर का कोई कारण है?
मैं अपने ज्यामिति शब्द के रूप में निम्नलिखित कोड का उपयोग करता हूं:
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);
}
और संदर्भ के लिए, यह मेरा सामान्य वितरण कार्य है:
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);
}