BRDF और गोलाकार किरण अनुरेखण में समन्वय करते हैं


9

मैंने एक किरण अनुरेखक विकसित किया जो मानक फोंग / ब्लिन फोंग प्रकाश मॉडल का उपयोग करता है। अब मैं इसे शारीरिक रूप से आधारित प्रतिपादन का समर्थन करने के लिए संशोधित कर रहा हूं, इसलिए मैं विभिन्न बीआरडीएफ मॉडल लागू कर रहा हूं। फिलहाल मैं ऑरेन-नायर और टोरेंस-स्पैरो मॉडल पर ध्यान केंद्रित कर रहा हूं। इनमें से हर एक घटना निर्देशांक पर आधारित है, जिसका उपयोग घटना wi और आउटगोइंग wo प्रकाश दिशा को व्यक्त करने के लिए किया जाता है।

मेरा सवाल यह है कि कौन सा तरीका सही है जो वाई और वू को कार्टेशियन समन्वय से गोलाकार समन्वय में परिवर्तित करता है?

मैं मानक सूत्र यहाँ रिपोर्ट को लागू करने कर रहा हूँ https://en.wikipedia.org/wiki/Spherical_coordinate_system#Coordinate_system_conversions लेकिन मुझे नहीं यकीन है कि मैं सही काम कर रहा हूँ कर रहा हूँ, क्योंकि मेरे वेक्टर पूंछ के साथ की उत्पत्ति पर नहीं हैं कार्टेशियन समन्वय प्रणाली, लेकिन ऑब्जेक्ट के साथ किरण के प्रतिच्छेदन बिंदु पर केंद्रित है।

यहाँ आप मेरे वर्तमान कार्यान्वयन पा सकते हैं:

क्या कोई मुझे कार्टियर से गोलाकार समन्वय के लिए वाई और वू वेक्टर को बदलने के सही तरीके की व्याख्या देने में मदद कर सकता है?

अपडेट करें

मैं यहां कोड के प्रासंगिक भाग की प्रतिलिपि बनाता हूं:

गोलाकार समन्वय गणना

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;
}

Torrance-गौरैया

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;
}

अद्यतन २

कुछ खोज के बाद मुझे ओरेन-नायर बीआरडीएफ का यह कार्यान्वयन मिला ।

Wi और wo के लिए थीटा के ऊपर कार्यान्वयन में केवल arccos (wo.dotProduct (सामान्य)) और arccos (wi.dotProduct (सामान्य)) कर रहे हैं। यह मेरे लिए उचित लगता है, क्योंकि हम अपने गोलाकार समन्वय प्रणाली के लिए चौराहे के बिंदु को सामान्य दिशा के रूप में उपयोग कर सकते हैं और गणना कर सकते हैं। गामा = cos (phi_wi - phi_wo) की गणना कुछ प्रकार के वाई और वू के प्रक्षेपण को करती है जिसे "स्पर्शरेखा स्थान" कहते हैं। इस कार्यान्वयन में सबकुछ सही होने पर, क्या मैं केवल सूत्रों का उपयोग कर सकता हूं? देखें - सामान्य x (View.dotProduct (सामान्य))) और | प्रकाश - सामान्य x (Light.dotProduct (सामान्य)) | phi निर्देशांक प्राप्त करने के लिए (arctan ("कुछ" का उपयोग करने के बजाय))?


कोई भी मेरी मदद कर सकता है?
फाब्रीजियो डुरोनी

क्या आप सटीक कोड स्निपेट दिखा सकते हैं, संपूर्ण रेपो नहीं?
concept3d

ऐसा लगता है कि यह समय के रे अनुरेखण के बारे में सबसे रहस्यमय प्रश्न में से एक है: D
Fabrizio Duroni 12

मैं आपको प्रोत्साहित करता हूं कि आप यहां computergraphics.stackexchange.com
concept3d

हो गया @ concept3d। आप इसे यहां पा सकते हैं computergraphics.stackexchange.com/questions/1799/…
Fabrizio Duroni

जवाबों:


2

बीआरडीएफ को लागू करने के लिए वास्तव में गोलाकार निर्देशांक (या उस मामले के किसी भी कोण) का उपयोग नहीं करना बेहतर है , बल्कि कार्टेशियन समन्वय प्रणाली में सीधे काम करते हैं और वैक्टर के बीच कोण के कोसाइन का उपयोग करते हैं, जो यूनिट डॉक्टरों के बीच सादा डॉट उत्पाद है जैसा कि आप जानते हैं। यह अधिक मजबूत और कुशल दोनों है।

ओरेन-नायर के लिए आप सोच सकते हैं कि आपको कोण (न्यूनतम / अधिकतम कोणों के कारण) का उपयोग करना होगा, लेकिन आप सीधे बीआरडीएफ को कार्टेशियन अंतरिक्ष में लागू कर सकते हैं: https://fgiesen.wordpress.com/2010/10/21 / खत्म-your-derivations-कृपया

टोरेंस-स्पैरो या कुक-टोरेंस माइक्रोफेट बीआरडीएफ के लिए आपको गोलाकार निर्देशांक का उपयोग करने की आवश्यकता नहीं है। इन BRDF में कोण को D / F / G शब्दों और BRDF भाजक में एक त्रिकोणमितीय (आमतौर पर cosine) फ़ंक्शन में पास किया जाता है, इसलिए आप गोलाकार निर्देशांक से गुजरे बिना डॉट उत्पाद को सीधे या त्रिकोणमितीय पहचान का उपयोग कर सकते हैं ।


1

आप सामान्य एन और एक अन्य वेक्टर को देखते हुए एक समन्वय प्रणाली निर्दिष्ट कर सकते हैं। हम वाई चुनेंगे। तो किसी भी सदिश कि स्पर्शरेखा विमान पर प्रक्षेपित वाई के रूप में एक ही दिशा है 0 का एक अज़ीमुथ होगा

सबसे पहले, हम स्पर्शरेखा विमान पर वाई प्रोजेक्ट करते हैं: (यह मानते हुए कि वाई पहले से ही सामान्यीकृत है)

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

अब, हम wo के साथ भी ऐसा ही कर सकते हैं:

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

अब, बुद्धि और प्लॉट दोनों एक विमान पर झूठ बोलते हैं जो कि एन के लिए ऑर्थोगोनल है, और चौराहे के बिंदु तक स्पर्शरेखा है।

अब हम दोनों के बीच के कोण की गणना कर सकते हैं:

azimuth = arcos ( dot(wit, wot) )

स्पर्शरेखा तल पर प्रक्षेपित होने पर बुद्धि के संबंध में वात का अज़ीमुथ वास्तव में है।


0

यदि आप चौराहे के बिंदु और मूल बिंदु को जानते हैं, तो क्या यह सिर्फ एक को दूसरे से घटाने का सवाल नहीं होगा ताकि आपको परिणाम ऐसा मिले जैसे कि यह मूल से था?

यदि आप परिणाम पर विश्वास नहीं करते हैं, और लंबे रास्ते से वहां जाना चाहते हैं, तो आप लुकअट मैट्रिक्स के माध्यम से एक बिंदु से दूसरे बिंदु तक प्राप्त करने के लिए रोटेशन परिवर्तन भी प्राप्त कर सकते हैं, और फिर घूर्णी घटक प्राप्त करने के लिए इसे विघटित कर सकते हैं। आप चाहें तो इससे एक क्वाटर्नियन भी प्राप्त कर सकते हैं।

परिणाम बराबर हैं। प्रमाण थोड़ा लंबा है, लेकिन जटिल नहीं है, और पाठक पर छोड़ दिया जाता है।


हाय @ पांडा पाजामा आपके उत्तर के लिए धन्यवाद, लेकिन मैं आपके उत्तर को नहीं समझ सकता। मैं स्पष्ट करने की कोशिश करता हूं: अगर मेरे पास चौराहा बिंदु था और देखने का बिंदु मैं वाई और वू की गणना कर सकता हूं। तब मैं गणना करने के लिए अपने आंचल दिशा के रूप में सामान्य का उपयोग कर सकता हूं, लेकिन मैं ज़ीनिथ के लिए एक विमान ऑर्थोगोनल पर अज़िमुथ कोण को खोजने के लिए आवश्यक अन्य अक्ष को खोजने में सक्षम नहीं हूं। ऊपर के स्निप में मैंने केवल विश्व समन्वय प्रणाली में दिए गए wi और wo पर गोलाकार समन्वय के लिए रूपांतरण सूत्र लागू किए, लेकिन मुझे नहीं लगता कि यह थीटा और phi की गणना करने का सही तरीका है।
Fabrizio Duroni
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.