আমি আমার রেট্রেসারে একটি মাইক্রোফেসেট বিআরডিএফ বাস্তবায়নের চেষ্টা করছি তবে আমি কিছু সমস্যা নিয়ে চলেছি। আমি যে অনেকগুলি কাগজপত্র এবং নিবন্ধ পড়েছি সেগুলি আংশিক জ্যামিতি শব্দটি সংজ্ঞা এবং অর্ধ ভেক্টরগুলির ফাংশন হিসাবে সংজ্ঞায়িত করে: জি 1 (ভি, এইচ)। যাইহোক, এটি বাস্তবায়ন করার সময় আমি নিম্নলিখিত ফলাফল পেয়েছি:
(নীচের সারিটি রুক্ষতার সাথে ডাইলেট্রিক 1.0.০ - ০.০, শীর্ষ সারিটি রুক্ষতার সাথে ধাতব হয় 1.0 - 0.0)
প্রান্তের চারপাশে একটি অদ্ভুত হাইলাইট এবং এনএল == 0 এর কাছাকাছি একটি কাটা বন্ধ রয়েছে I আমি আমার রেন্ডারগুলি যাচাই করার জন্য !ক্যকে একটি রেফারেন্স হিসাবে ব্যবহার করছি তাই আমি তাদের শেডার উত্সটি যা তারা ব্যবহার করে তা যাচাই করেছিলাম এবং যা থেকে আমি তাদের জ্যামিতি শব্দটি বলতে পারি তা অর্ধেক ভেক্টর দ্বারা একেবারেই প্যারামিটারাইজড হয় না! সুতরাং আমি একই কোডটি ব্যবহার করে চেষ্টা করেছি তবে অর্ধেক ভেক্টরের পরিবর্তে ম্যাক্রো পৃষ্ঠকে স্বাভাবিক হিসাবে ব্যবহার করেছি এবং নিম্নলিখিত ফলাফল পেয়েছি:
আমার প্রশিক্ষণপ্রাপ্ত চোখের কাছে এটি কাঙ্ক্ষিত ফলাফলের কাছাকাছি মনে হয়। তবে আমার অনুভূতিটি কি এটি সঠিক নয়? আমি যে নিবন্ধগুলি পড়েছি সেগুলির বেশিরভাগটি অর্ধ ভেক্টর ব্যবহার করে তবে সেগুলি সবগুলিই নয়। এই পার্থক্যের কোনও কারণ আছে কি?
আমি নিম্নলিখিত কোডটি আমার জ্যামিতি শব্দ হিসাবে ব্যবহার করি:
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);
}