2012-12-17 31 views
5

मैं एक व्यक्तिगत शिक्षण परियोजना (Enlight) के रूप में एक 3 डी रेट्रेटर लिख रहा हूं और एक किरण और वस्तुओं के दृश्य के बीच छेड़छाड़ परीक्षण करने से संबंधित एक दिलचस्प समस्या में भाग गया हूं।कुशल रेट्रैसिंग के लिए डेटा संरचना/दृष्टिकोण

स्थिति है:

  • मैं पुरातन कि रे (क्षेत्रों, बक्से, विमानों, आदि) और समूहों उसके साथ एक दूसरे को काटना कर सकते हैं की एक संख्या है। सामूहिक रूप से मैं इन दृश्य वस्तुओं को बुला रहा हूँ।
  • मैं Transform ऑब्जेक्ट में उन्हें लपेटकर मनमानी एफ़िन ट्रांसफॉर्मेशन के साथ ऑब्जेक्ट प्राइमेटिव्स को देखने में सक्षम होना चाहता हूं (महत्वपूर्ण रूप से, यह दृश्य में विभिन्न स्थितियों में उपयोग किए जाने वाले समान आदिम के कई उदाहरणों को सक्षम करेगा क्योंकि प्राइमेटिव हैं अपरिवर्तनीय)
  • दृश्य वस्तुओं बाउंडिंग मात्रा पदानुक्रम में संग्रहित किया जा सकता (यानी मैं स्थानिक विभाजन कर रहा हूँ)
  • मेरे चौराहे परीक्षण Ray वस्तुओं है कि एक आंशिक रे खंड प्रतिनिधित्व करते हैं के साथ काम (वेक्टर, सामान्यीकृत दिशा वेक्टर शुरू करते हैं, दूरी शुरू , अंत दूरी)

समस्या यह है कि जब एक किरण एक ट्रांसफॉर्म ऑब्जेक्ट के बाउंडिंग बॉक्स को हिट करती है, तो ऐसा लगता है कि इसमें परिवर्तित ट्रांसफॉर्म किए गए प्राइमेटिव्स के साथ एक चौराहे परीक्षण करने का एकमात्र तरीका है, Ray को परिवर्तित समन्वय स्थान में बदलना है। यह काफी आसान है, लेकिन फिर यदि किरण किसी भी रूपांतरित वस्तुओं को हिट नहीं करती है तो मुझे ट्रेस जारी रखने के लिए मूल Ray पर वापस गिरने की आवश्यकता है। चूंकि ट्रांसफॉर्म को घोंसला दिया जा सकता है, इसका मतलब है कि मुझे प्रत्येक छेड़छाड़ के निशान के लिए Ray एस का पूरा ढेर बनाए रखना है।

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

क्या नया Ray एस आवंटित करने से बचने के लिए एक चालाक तरीका है/Ray स्टैक रखें?

या क्या यह पूरी तरह से करने का एक चालाक तरीका है?

+1

मुझे यकीन नहीं है कि यह स्मृति आवंटन से तेज़ होगा, लेकिन आप एक कुशल ट्रांसफॉर्म इनवर्जन एल्गोरिदम के साथ आने का प्रयास कर सकते हैं और फिर मौजूदा ऑब्जेक्ट से बैक अप करते समय मौजूदा रे को उलटा परिवर्तन के साथ गुणा कर सकते हैं। –

+0

@Ivan - दिलचस्प विचार। मुझे लगता है कि यह मामूली तेजी से हो सकता है, हालांकि मैं संख्यात्मक परिशुद्धता समस्याओं को जोड़कर चिंतित हूं ..... – mikera

+0

आप प्रत्येक ऑब्जेक्ट के साथ एक रूपांतरण और उलटा परिवर्तन (आईई एक मैट्रिक्स ऑब्जेक्ट) की गणना और कैश कर सकते हैं (साथ ही साथ समूह में वस्तुओं) जो वैश्विक फ्रेम में और से परिवर्तित हो जाएगा। इस तरह आपको घोंसले पदानुक्रम की आवश्यकता नहीं है क्योंकि आप प्रत्येक वस्तु पर सीधे हिट टेस्ट कर सकते हैं। अर्थात। वस्तु को फ्रेम के रूप में संशोधित करें, फिर वैश्विक फ्रेम में हिट पॉइंट प्राप्त करने के लिए वापस बदलें। मैं इसे अपने ट्रेसर में करता हूं: http://github.com/danieljfarrell/pvtrace –

उत्तर

2

रे-ट्रेसिंग में अधिकांश समय आपके पास कुछ (सौ, हजार) वस्तुएं और कुछ और किरणें होती हैं। शायद लाखों किरणें। यह मामला यह है कि यह देखने के लिए समझ में आता है कि किरणों के साथ बातचीत करने के लिए इसे तेजी से/आसान बनाने के लिए आप वस्तुओं पर किस प्रकार की गणना कर सकते हैं।

लड़के के सुझाव के रूप में एक कैश बहुत मददगार होगा। यह न केवल उन वस्तुओं पर आगे बढ़ने और रिवर्स ट्रांसफॉर्म बनाने का अर्थ हो सकता है जो उन्हें वैश्विक फ्रेम पर या उससे आगे ले जाएंगे, बल्कि वैश्विक फ्रेम में ऑब्जेक्ट की एक प्रति रखने के लिए भी। यह ऑब्जेक्ट्स बनाने या उन्हें स्थानांतरित करने के लिए अधिक महंगा बनाता है (क्योंकि परिवर्तन परिवर्तन और कैश्ड वैश्विक फ्रेम प्रतियां भी करते हैं) लेकिन यह शायद ठीक है।

यदि आप एन किरणें डालते हैं और एम ऑब्जेक्ट्स और एन >> एम है तो इसका कारण यह है कि प्रत्येक ऑब्जेक्ट में कई किरणें होंगी। अगर हम मानते हैं कि प्रत्येक किरण किसी ऑब्जेक्ट को हिट करती है तो प्रत्येक ऑब्जेक्ट में एन/एम किरणें होती हैं जो इसे हड़ताल करती हैं। इसका मतलब है कि प्रत्येक ऑब्जेक्ट में एन/एम किरणों को बदलना, हिट परीक्षण करना, और संभवतः इसे पीछे हटाना। या एन/एम प्रति ऑब्जेक्ट को कम से कम बदलता है। लेकिन अगर हम परिवर्तित ऑब्जेक्ट को कैश करते हैं तो हम ग्लोबल फ्रेम पर जाने के लिए प्रति ऑब्जेक्ट में एक ट्रांसफॉर्म कर सकते हैं और फिर किसी अतिरिक्त की आवश्यकता नहीं है। कम से कम हिट-परीक्षण के लिए।

1

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

यह आपको सरलीकृत गणित का उपयोग करके हिट का परीक्षण करने की क्षमता देगा (आप ऑब्जेक्ट स्पेस में किरण को बदल सकते हैं और बेस फॉर्म ऑब्जेक्ट के साथ हिट की गणना कर सकते हैं) और उसके बाद हिट प्वाइंट और संभावित प्रतिबिंब वेक्टर को दूसरे ट्रांसफॉर्म का उपयोग करके असली दुनिया की जगह में बदल दें।

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