इलाके की पीढ़ी के लिए एक ऑक्ट्री का निर्माण


9

IsoSurface को रेंडर करने के लिए मैंने पहले मार्चिंग क्यूब्स / टेट्राहेड्रा लागू किया है। इसने ( YouTube ) काम किया , लेकिन प्रदर्शन भीषण था क्योंकि मुझे देखने की दूरी (या यहां तक ​​कि पुराने, दूर के टुकड़े को हटाने) के आधार पर चर के स्तर को लागू करने के लिए कभी नहीं मिला।

मैंने इस बार एक और जाने और इसे ठीक से करने का फैसला किया। मैंने एक OctreeNode बनाकर शुरू किया है जो इस प्रकार काम करता है जब Build()कहा जाता है।

  • यदि चंक निर्माण करने के लिए बहुत छोटा है, तो तुरंत वापस लौटें।
  • अगर सतह इस चंक की मात्रा से गुजरती है तो काम करें।
  • यदि ऐसा है, तो तय करें कि क्या हम LOD उठाना चाहते हैं (क्योंकि कैमरा बंद है)
  • यदि ऐसा है, तो 8 बच्चों को स्पॉन करें और उसी प्रक्रिया को उन पर कॉल करें
  • यदि नहीं, तो वर्तमान नोड के आयामों का उपयोग करके मेष का निर्माण करें

कुछ छद्म कोड:

OctNode Build() {
    if(this.ChunkSize < minChunkSize) {
        return null;
    }
    densityRange = densitySource¹.GetDensityRange(this.bounds);
    if(densityRange.min < surface < densityRange.max) {
        if(loDProvider.DesiredLod(bounds > currentLoD) {
            for(i 1 to 8) {
                if(children[i] == null) {
                    children[i] = new OctNode(...)
                }
                children[i] = children[i].Build();
            }
        } else {
            BuildMesh();
        }
        return this;
    }
}

Returning एक बिंदु पर घनत्व लौटने के साथ-साथ, घनत्व स्रोत किसी दिए गए आयतन के लिए संभव घनत्व सीमा निर्धारित कर सकता है।

Returns LoD प्रदाता एक बाउंडिंग बॉक्स लेता है और अधिकतम वांछित LoD को कैमरा पोजीशन / फ्रूटम, उपयोगकर्ता सेटिंग्स, आदि के आधार पर देता है।

तो ... यह सब काफी अच्छी तरह से काम करता है। घनत्व स्रोत के रूप में एक साधारण क्षेत्र का उपयोग करना, और सभी नोड्स दिखाना:

फुल ऑक्टी

और सिर्फ पत्ते:

ओक्ट्री केवल पत्ते दिखाती है

हालाँकि, कुछ मुद्दे हैं:

  • मुझे शुरुआती बाउंडिंग वॉल्यूम को परिभाषित करना होगा (और यह जितना बड़ा होगा, उतना अधिक प्रसंस्करण मुझे करना होगा)
  • पेड़ की जड़ में, मुझे नहीं पता कि पत्ते कितने गहरे होंगे, इसलिए मेरी LoD की संख्या सबसे कम गुणवत्ता (मूल) से शुरू होती है और बढ़ जाती है क्योंकि चूजे छोटे हो जाते हैं। क्योंकि एलओडी अब प्रारंभिक मात्रा के सापेक्ष है, जब मैं विशिष्ट आकारों / गुणों पर चीजें करना चाहता हूं तो इसका ज्यादा उपयोग नहीं होता है।

मैंने कुछ विकल्पों के बारे में सोचा है लेकिन दोनों त्रुटिपूर्ण हैं:

  • अक्टूबर के संग्रह को बनाए रखें और दूरी के आधार पर जोड़ें / निकालें। यह नहीं देख पा रहा हूं कि मैं पूरी तरह से कैसे घूमूंगा, साथ ही मुझे ज्ञात-रिक्त नोड्स की एक सूची की आवश्यकता होगी, खासकर अगर मुझे 3 डी सतहों की मनमानी चाहिए (बार-बार खाली वॉल्यूम की पुन: गणना करने से बचने के लिए)
  • वर्तमान रूट में एक मूल नोड जोड़ें, फिर मूल नोड के लिए सात भाई-बहन जोड़ें। यह काम करेगा और ऑन-डिमांड होगा, लेकिन खिलाड़ी के परिदृश्य से हटते ही यह समझदारी से सिकुड़ जाना जटिल है। यह LoD नंबर को और भी कम सार्थक बना देगा।

¹ [क्यू के नीचे स्पष्टीकरण में] वर्तमान में, अगर पेड़ में 2 शारीरिक रूप से आसन्न नोड्स अलग-अलग एलओडी पर हैं, तो मेरे पास कुछ कोड हैं ताकि वे इस तरह के कगार को समतल कर सकें, जब मेश उत्पन्न नहीं होते हैं। मैं आसपास के कई नोड्स के घनत्व को जानकर ऐसा करने में सक्षम हूं। ऐसे परिदृश्य में, जहां मेरे पास 2 स्वतंत्र ऑक्ट्रीज़ हैं, मैं इस जानकारी को प्राप्त करने का कोई आसान तरीका नहीं है, जिसके परिणामस्वरूप सीम।

यह दृष्टिकोण करने का एक इष्टतम तरीका क्या है?

जवाबों:


1

मुझे यकीन नहीं है कि मैं सटीक प्रश्न का उत्तर दे रहा हूं, इसलिए मैं खंडों में उत्तर जा रहा हूं, और टिप्पणियों में जवाब देने के लिए स्वतंत्र महसूस कर रहा हूं यदि किसी विशिष्ट प्रश्न के विवरण के बारे में गलतफहमी है।

मुझे शुरुआती बाउंडिंग वॉल्यूम को परिभाषित करना होगा (और यह जितना बड़ा होगा, उतना अधिक प्रसंस्करण मुझे करना होगा)

ऐसा प्रतीत नहीं होता कि ऐसा होना चाहिए। चूंकि ऑक्ट्री ग्रैन्युलैरिटी में तेजी से वृद्धि होती है, इसलिए शीर्ष पर कुछ स्तरों को जोड़कर प्रदर्शन हिट में बहुत कम शुद्ध वृद्धि होनी चाहिए।

पेड़ की जड़ में, मुझे नहीं पता कि पत्ते कितने गहरे होंगे, इसलिए मेरी LoD की संख्या सबसे कम गुणवत्ता (मूल) से शुरू होती है और बढ़ जाती है क्योंकि चूजे छोटे हो जाते हैं। क्योंकि एलओडी अब प्रारंभिक मात्रा के सापेक्ष है, जब मैं विशिष्ट आकारों / गुणों पर चीजें करना चाहता हूं तो इसका ज्यादा उपयोग नहीं होता है।

यदि आप अपनी रूट ऑक्ट्री को कुछ "बड़े पर्याप्त मूल्य" के लिए ठीक करते हैं, तो "प्रारंभिक मात्रा के सापेक्ष LoD" एक मुद्दा नहीं होना चाहिए। और जैसा कि ऊपर उल्लेख किया गया है, मुझे नहीं लगता कि शीर्ष पर अतिरिक्त स्तर होने से समग्र प्रदर्शन प्रभावित होगा।

अक्टूबर के संग्रह को बनाए रखें और दूरी के आधार पर जोड़ें / निकालें। यह नहीं देख पा रहा हूं कि मैं पूरी तरह से कैसे फंसा रहूंगा, साथ ही मुझे ज्ञात-खाली नोड्स की एक सूची की आवश्यकता होगी, खासकर अगर मुझे 3 डी सतहों की मनमानी चाहिए (बार-बार खाली वॉल्यूम की फिर से गणना करने से)

जैसा कि मैंने इसे समझा, यह प्रस्तावित समाधान LoD को कम करने के बारे में है जब पहले विस्तृत क्षेत्र से दूर जा रहा है। मुझे लगता है कि इसे "बढ़ते LoD" कोड पथ के समान दिखना चाहिए:

if (loDProvider.DesiredLod(bounds) <(is a lot less than)< currentLoD) { 
    for(i = 1 to 8) { 
        children[i].Destroy();
    }
    BuildMesh();
}

फिर, आप बहुत अधिक समय दूर के नोड्स की जाँच में नहीं बिता रहे हैं क्योंकि आप इस तथ्य पर भरोसा कर सकते हैं कि दूर होने के दौरान, बहुत अधिक "सक्रिय" नोड नहीं हैं, क्योंकि सभी उच्च-रिज़ॉल्यूशन नोड्स को हटा दिया जाएगा।


मान लें कि छोटे नोड्स रॉक-स्केल हैं, तो इसका मतलब दर्जनों होगा यदि मैं सैकड़ों महाद्वीपों में नहीं जाता हूं

मुझे लगता है कि ओक्ट्री का लॉगरिदमिक पैमाना इसे अभी भी संभव बनाता है। यदि आपका शीर्ष स्तर 1,000,0000,000 मीटर चौड़ा है (यह वास्तविक पृथ्वी की तुलना में 25 गुना चौड़ा होगा, और 625x सतह क्षेत्र के साथ) और आपके सबसे निचले स्तर की बिट्स 10 सेमी के पार हैं, तो ऑक्ट्री में 32 स्तर हैं, जो संभवतः है प्रबंधनीय पर्याप्त है। यदि आप पृथ्वी से 100 गुना व्यापक (और 10000 गुना अधिक सतह क्षेत्र) वाला ग्रह चाहते थे, तो यह आपके ऑक्ट्री में केवल 3-4 अतिरिक्त स्तर है। इस बिंदु पर दुनिया भर में चलने के लिए एक खिलाड़ी को सैकड़ों साल लगेंगे, और यदि आप भोले फ्लोटिंग पॉइंट गणित का उपयोग करते हैं, तो दुनिया सटीक त्रुटियों को जमा कर रही होगी।

अक्टूबर के संग्रह को बनाए रखें और दूरी के आधार पर जोड़ें / निकालें। यह नहीं देख पा रहा हूं कि मैं पूरी तरह से कैसे घूमूंगा, साथ ही मुझे ज्ञात-रिक्त नोड्स की एक सूची की आवश्यकता होगी, खासकर अगर मुझे 3 डी सतहों की मनमानी चाहिए (बार-बार खाली वॉल्यूम की पुन: गणना करने से बचने के लिए)

क्या यह मूल रूप से बिलियन-किमी-वाइड ऑक्ट्री के बराबर नहीं है, लेकिन 1 किमी ब्लॉक, हर तरफ पॉइंटर्स की एक सूची है? फिर "जाली भर" बस 2 किमी-आकार के नोड्स पर निर्भर होगा। प्रत्येक मध्य-स्तरीय "बड़े ब्लॉक" के लिए एक स्थानीय संदर्भ रखने से भी आपको शीर्ष-स्तरीय नोड्स के माध्यम से पुनरावृति होने से बचा रहता है, यदि आप "संभवतः दर्जनों अतिरिक्त ऑक्ट्री स्तरों" के बारे में चिंतित हैं


जवाब के लिए धन्यवाद। मैं एक विशाल प्रारंभिक मात्रा नहीं चुन सकता क्योंकि मेरा इलाक़ा अनंत है (यही मेरा लक्ष्य है)। अंदाजा लगाने के लिए वीडियो देखें। जैसे, मेरे नोड्स का पेड़ बस कभी-कभी ऊंचा हो जाएगा। मान लें कि छोटे नोड्स रॉक-स्केल हैं, तो इसका मतलब दर्जनों होगा यदि मैं सैकड़ों महाद्वीपों में नहीं जाता हूं। पुन: भरकर, मुझे इस प्रश्न पर कुछ और विस्तार करने दें [Done]
मूल

जहां तक ​​खिलाड़ी का सवाल है, "एक अरब मील" "अनंत" के काफी करीब है। निश्चित प्रारंभिक मात्रा के लिए अधिक तर्क जवाब देने के लिए जोड़े गए।
जिमी

मैं अभी भी असंबद्ध हूं। ज्ञात-बेकार प्रसंस्करण की 30+ परतें क्यों हैं? यह सुरुचिपूर्ण नहीं है, अकेले कुशल है। मैं समय के साथ चलने के लिए आपकी बात को लेता हूं, लेकिन हम केवल इलाके की पीढ़ी के बारे में बात कर रहे हैं। ऐसा कुछ भी नहीं जो कहता है कि मुझे मूल में केंद्र में है, और न ही उच्च गति पर उड़ना असंभव है (हालांकि मैं उस गति से नहीं जाल कर रहा हूं!)। FWIW मैं उस सटीक समस्या से बचने के लिए आंतरिक रूप से डबल्स का उपयोग कर रहा हूं।
बेसिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.