রে ট্রেসিংয়ে বিআরডিএফ এবং গোলাকৃতির সমন্বয়


9

আমি একটি রশ্মির ট্রেসার তৈরি করেছি যা স্ট্যান্ডার্ড ফোং / ব্লিন ফং লাইটিং মডেল ব্যবহার করে। শারীরিক ভিত্তিক রেন্ডারিং সমর্থন করার জন্য এখন আমি এটিকে সংশোধন করছি, তাই আমি বিআরডিএফের বিভিন্ন মডেল বাস্তবায়ন করছি। এই মুহুর্তে আমি ওরেেন-নায়ার এবং টরেন্স-স্প্যারো মডেলের দিকে দৃষ্টি নিবদ্ধ করছি। এর প্রত্যেকটি ঘটনার ডাব্লু এবং আউটগোয়িং ওয়া হালকা নির্দেশকে প্রকাশ করতে ব্যবহৃত গোলাকার স্থানাঙ্কের উপর ভিত্তি করে।

আমার প্রশ্নটি হল: কোনটি সঠিকভাবে ডাব্লুআইআই এবং ডাব্লু কার্টেসিয়ান স্থানাঙ্ক থেকে গোলাকার স্থানাঙ্কে রূপান্তরিত?

আমি এখানে উল্লিখিত স্ট্যান্ডার্ড সূত্রটি প্রয়োগ করছি https://en.wikedia.org/wiki/Sphanical_coordinate_system#Coordinate_system_conversions তবে আমি নিশ্চিত নই যে আমি সঠিক জিনিসটি করছি, কারণ আমার ভেক্টরটি মূলটির সাথে লেজের সাথে নেই কার্টেসিয়ান সমন্বয় ব্যবস্থা, তবে বস্তুর সাথে রশ্মির ছেদ বিন্দুকে কেন্দ্র করে are

এখানে আপনি আমার বর্তমান প্রয়োগটি পেতে পারেন:

কার্টেসিয়ান থেকে গোলাকৃতির স্থানাঙ্কে ডাব্লুআইআই এবং ডাব্লু ভেক্টরকে রূপান্তর করার সঠিক উপায়ের ব্যাখ্যা দিতে আমাকে কেউ সাহায্য করতে পারেন?

হালনাগাদ

আমি কোডের সম্পর্কিত অংশটি এখানে অনুলিপি করছি:

গোলাকার স্থানাঙ্ক গণনা

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 (সাধারণ)) | এবং | হালকা - সাধারণ এক্স (লাইট.ডটপ্রডাক্ট (সাধারণ)) | ফাই সমন্বয় (আর্টিকান ব্যবহার না করে ("কিছু")) পেতে?


কেউ আমাকে সাহায্য করতে পারে?
ফ্যাবরিজিও দুরোনি

আপনি পুরো কোডটি নয়, সঠিক কোড স্নিপেট দেখাতে পারবেন?
ধারণাগুলি

দেখে মনে হচ্ছে এটি আল কালের রশ্মি সম্পর্কিত সবচেয়ে রহস্যজনক প্রশ্ন: ডি
ফ্যাব্রিজিও ডুরনি


সম্পন্ন হয়েছে @ ধারণা3 ডি। আপনি এটি এখানে কম্পিউটারগ্রাফিক্স.সটেকেক্সচেঞ্জ
প্রশ্নগুলি / 1799/…

উত্তর:


2

বিআরডিএফ এর বাস্তবায়নের জন্য গোলাকার স্থানাঙ্ক (বা কোনও বিষয়ে কোনও কোণ) ব্যবহার না করা ভাল , বরং কার্টেসিয়ান সমন্বয় ব্যবস্থায় সরাসরি কাজ করুন এবং ভেক্টরগুলির মধ্যে কোণটির কোসাইন ব্যবহার করুন, যা ইউনিট ভেক্টরগুলির মধ্যে স্পষ্ট বিন্দু পণ্য হিসাবে আপনি জানেন। এটি উভয়ই আরও দৃust় এবং দক্ষ।

ওরেন-নায়ারের জন্য আপনি হয়ত ভাবতে পারেন যে আপনাকে কোণ ব্যবহার করতে হবে (কমপক্ষে / কমের বেশি কোণে) তবে আপনি কেবল কার্টেসিয়ান স্পেসে সরাসরি বিআরডিএফ প্রয়োগ করতে পারেন: https://fgiesen.wordpress.com/2010/10/21 / ফিনিস-আপনার-derivations দয়া করে

টরেন্স-স্প্যারো বা কুক-টরেন্স মাইক্রোফেসেট বিআরডিএফের জন্য আপনাকে কোনও গোলাকার স্থানাঙ্ক ব্যবহার করার দরকার নেই। এই বিআরডিএফ-এর কোণটি ডি / এফ / জি পদ এবং বিআরডিএফ ডিনোমিনেটরে একটি ট্রিগনোমেট্রিক (সাধারণত কোসাইন) ফাংশনে প্রেরণ করা হয়, সুতরাং আপনি গোলাকার স্থানাঙ্কের মধ্য দিয়ে না গিয়ে ডট পণ্যটি সরাসরি বা ত্রিকোণমিতিক পরিচয় ব্যবহার করতে পারেন ।


1

আপনি সাধারণ এন এবং অন্য ভেক্টর প্রদত্ত একটি সমন্বয় ব্যবস্থা নির্দিষ্ট করতে পারেন। আমরা WI নির্বাচন করব। সুতরাং যে কোনও ভেক্টরের স্পর্শক সমতলে যখন প্রাইভেট করা হয় তখন ডাব্লুআইয়ের সমান দিকের একটি অজিমুথ থাকবে

প্রথমে, আমরা ট্যানজেন্ট প্লেনে WI প্রজেক্ট করি: (ধরে নিলাম ডাব্লুআই ইতিমধ্যে স্বাভাবিক করা হয়েছে)

wit = normalize(wi - N * dot(wi, N))

এখন, আমরা ওও দিয়ে একই কাজ করতে পারি:

wot = normalize(wo - N * dot(wo, N))

এখন, বুদ্ধিমান এবং বুদ্ধিমান উভয়ই একটি বিমানের উপরে পড়ে যা N এর সাথে অর্থেগোনাল এবং ছেদ বিন্দুতে স্পর্শকাতর।

আমরা এখন দুজনের মধ্যে কোণটি গণনা করতে পারি:

azimuth = arcos ( dot(wit, wot) )

স্পর্শকাতর বিমানে যখন অভিক্ষেপ করা হয় তখন বুদ্ধি সম্পর্কে সত্যিকার অর্থে ওয়াটের আজিমুথ।


0

যদি আপনি ছেদ বিন্দু এবং উত্সের বিন্দুটি জানেন, তবে এটি কেবল একে অপরের থেকে বিয়োগ করার প্রশ্ন হবে না যাতে আপনি ফলাফলটি উত্স থেকেই পেয়েছেন কিনা?

আপনি যদি ফলাফলটি বিশ্বাস না করেন এবং দীর্ঘ পথ পাড়ি দিতে চান তবে আপনি একটি দৃষ্টিকোণ থেকে লুকেএট ম্যাট্রিক্সের মাধ্যমে অন্য বিন্দুতে ঘোরার রূপান্তরটি পেতে পারেন, এবং তারপরে ঘূর্ণন উপাদানটি পেতে এটি পচন করতে পারেন। আপনি চাইলে এটি থেকে একটি চতুর্থাংশও পেতে পারেন।

ফলাফল সমান। প্রমাণটি কিছুটা দীর্ঘ, তবে জটিল নয় এবং এটি পাঠকের কাছে ছেড়ে দেওয়া হয়েছে।


হাই @ পান্ডা পাজামা আপনার উত্তরের জন্য আপনাকে ধন্যবাদ, তবে আমি আপনার উত্তর বুঝতে পারি না। আমি স্পষ্ট করার চেষ্টা করি: আমার যদি ছেদ করার জায়গা এবং দৃষ্টিকোণটি থাকে তবে আমি উই এবং ডু হিসাব করতে পারি। তারপরে আমি গণনা করার জন্য আমার জেনিথ দিক হিসাবে স্বাভাবিকটি ব্যবহার করতে পারি তবে জেনিথের অরথোগোনালটিতে অ্যাসিমুথ কোণটি খুঁজে পাওয়ার জন্য প্রয়োজনীয় অন্যান্য অক্ষটি আমি খুঁজে পেতে সক্ষম নই। উপরের টুকরো টুকরো করে আমি কেবল ওয়ার্ল্ড কোঅর্ডিনেট সিস্টেমে ডাব্লুআইও এবং ডাব্লু এর উপর গোলাকার স্থানাঙ্কের জন্য রূপান্তর সূত্রগুলি প্রয়োগ করেছি, তবে থিয়েটা এবং ফাই গণনা করার জন্য এটি সঠিক উপায় বলে আমি মনে করি না।
ফ্যাবরিজিও দুরোনি 14
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.