আমি একটি রশ্মির ট্রেসার তৈরি করেছি যা স্ট্যান্ডার্ড ফোং / ব্লিন ফং লাইটিং মডেল ব্যবহার করে। শারীরিক ভিত্তিক রেন্ডারিং সমর্থন করার জন্য এখন আমি এটিকে সংশোধন করছি, তাই আমি বিআরডিএফের বিভিন্ন মডেল বাস্তবায়ন করছি। এই মুহুর্তে আমি ওরেেন-নায়ার এবং টরেন্স-স্প্যারো মডেলের দিকে দৃষ্টি নিবদ্ধ করছি। এর প্রত্যেকটি ঘটনার ডাব্লু এবং আউটগোয়িং ওয়া হালকা নির্দেশকে প্রকাশ করতে ব্যবহৃত গোলাকার স্থানাঙ্কের উপর ভিত্তি করে।
আমার প্রশ্নটি হল: কোনটি সঠিকভাবে ডাব্লুআইআই এবং ডাব্লু কার্টেসিয়ান স্থানাঙ্ক থেকে গোলাকার স্থানাঙ্কে রূপান্তরিত?
আমি এখানে উল্লিখিত স্ট্যান্ডার্ড সূত্রটি প্রয়োগ করছি https://en.wikedia.org/wiki/Sphanical_coordinate_system#Coordinate_system_conversions তবে আমি নিশ্চিত নই যে আমি সঠিক জিনিসটি করছি, কারণ আমার ভেক্টরটি মূলটির সাথে লেজের সাথে নেই কার্টেসিয়ান সমন্বয় ব্যবস্থা, তবে বস্তুর সাথে রশ্মির ছেদ বিন্দুকে কেন্দ্র করে are
এখানে আপনি আমার বর্তমান প্রয়োগটি পেতে পারেন:
https://github.com/chicio/Multispectral-Ray-tracing/tree/brdf/RayTracing/RayTracer/Objects/BRDF
https://github.com/chicio/Multispectral-Ray-tracing/blob/brdf/RayTracing/RayTracer/Math/Vector3D.cpp
কার্টেসিয়ান থেকে গোলাকৃতির স্থানাঙ্কে ডাব্লুআইআই এবং ডাব্লু ভেক্টরকে রূপান্তর করার সঠিক উপায়ের ব্যাখ্যা দিতে আমাকে কেউ সাহায্য করতে পারেন?
হালনাগাদ
আমি কোডের সম্পর্কিত অংশটি এখানে অনুলিপি করছি:
গোলাকার স্থানাঙ্ক গণনা
float Vector3D::sphericalTheta() const {
float sphericalTheta = acosf(Utils::clamp(y, -1.f, 1.f));
return sphericalTheta;
}
float Vector3D::sphericalPhi() const {
float phi = atan2f(z, x);
return (phi < 0.f) ? phi + 2.f * M_PI : phi;
}
ওরেন নায়ার
OrenNayar::OrenNayar(Spectrum<constant::spectrumSamples> reflectanceSpectrum, float degree) : reflectanceSpectrum{reflectanceSpectrum} {
float sigma = Utils::degreeToRadian(degree);
float sigmaPowerTwo = sigma * sigma;
A = 1.0f - (sigmaPowerTwo / 2.0f * (sigmaPowerTwo + 0.33f));
B = 0.45f * sigmaPowerTwo / (sigmaPowerTwo + 0.09f);
};
Spectrum<constant::spectrumSamples> OrenNayar::f(const Vector3D& wi, const Vector3D& wo, const Intersection* intersection) const {
float thetaI = wi.sphericalTheta();
float phiI = wi.sphericalPhi();
float thetaO = wo.sphericalTheta();
float phiO = wo.sphericalPhi();
float alpha = std::fmaxf(thetaI, thetaO);
float beta = std::fminf(thetaI, thetaO);
Spectrum<constant::spectrumSamples> orenNayar = reflectanceSpectrum * constant::inversePi * (A + B * std::fmaxf(0, cosf(phiI - phiO) * sinf(alpha) * tanf(beta)));
return orenNayar;
}
টোরেন্স-চড়ুই
float TorranceSparrow::G(const Vector3D& wi, const Vector3D& wo, const Vector3D& wh, const Intersection* intersection) const {
Vector3D normal = intersection->normal;
normal.normalize();
float normalDotWh = fabsf(normal.dot(wh));
float normalDotWo = fabsf(normal.dot(wo));
float normalDotWi = fabsf(normal.dot(wi));
float woDotWh = fabsf(wo.dot(wh));
float G = fminf(1.0f, std::fminf((2.0f * normalDotWh * normalDotWo)/woDotWh, (2.0f * normalDotWh * normalDotWi)/woDotWh));
return G;
}
float TorranceSparrow::D(const Vector3D& wh, const Intersection* intersection) const {
Vector3D normal = intersection->normal;
normal.normalize();
float cosThetaH = fabsf(wh.dot(normal));
float Dd = (exponent + 2) * constant::inverseTwoPi * powf(cosThetaH, exponent);
return Dd;
}
Spectrum<constant::spectrumSamples> TorranceSparrow::f(const Vector3D& wi, const Vector3D& wo, const Intersection* intersection) const {
Vector3D normal = intersection->normal;
normal.normalize();
float thetaI = wi.sphericalTheta();
float thetaO = wo.sphericalTheta();
float cosThetaO = fabsf(cosf(thetaO));
float cosThetaI = fabsf(cosf(thetaI));
if(cosThetaI == 0 || cosThetaO == 0) {
return reflectanceSpectrum * 0.0f;
}
Vector3D wh = (wi + wo);
wh.normalize();
float cosThetaH = wi.dot(wh);
float F = Fresnel::dieletricFresnel(cosThetaH, refractiveIndex);
float g = G(wi, wo, wh, intersection);
float d = D(wh, intersection);
printf("f %f g %f d %f \n", F, g, d);
printf("result %f \n", ((d * g * F) / (4.0f * cosThetaI * cosThetaO)));
Spectrum<constant::spectrumSamples> torranceSparrow = reflectanceSpectrum * ((d * g * F) / (4.0f * cosThetaI * cosThetaO));
return torranceSparrow;
}
আপডেট 2
কিছু অনুসন্ধানের পরে আমি ওরেেন-নায়ার বিআরডিএফের এই বাস্তবায়নটি পেয়েছি ।
ডাব্লুআই ও ওও এর উপরের থিটা বাস্তবায়নে কেবল আরকোস (ডাব্লু ডটপ্রডাক্ট (নরমাল)) এবং আরসিকোস (ডাব্লিউ.ইডটপ্রোডাক্ট (নরমাল)) করে পাওয়া যায়। এটি আমার পক্ষে যুক্তিসঙ্গত বলে মনে হচ্ছে, কারণ আমরা আমাদের গোলাকার স্থানাঙ্ক ব্যবস্থার জেনিথ দিক হিসাবে ছেদ বিন্দুর স্বাভাবিকটি ব্যবহার করতে পারি এবং গণনাটি করতে পারি। গামার গণনা = কোস (ফাই_উইইউ - ফাই_ও) এক ধরণের উই এর প্রক্ষেপণ করে এবং আফসোস যেটিকে "স্পর্শকাতর স্থান" বলে ডাকে। এই বাস্তবায়নে সবকিছু সঠিক বলে ধরে নিচ্ছি, আমি কি কেবল সূত্রগুলি ব্যবহার করতে পারি | দেখুন - সাধারণ x (View.dotProduct (সাধারণ)) | এবং | হালকা - সাধারণ এক্স (লাইট.ডটপ্রডাক্ট (সাধারণ)) | ফাই সমন্বয় (আর্টিকান ব্যবহার না করে ("কিছু")) পেতে?