बड़े वर्टेक्स बफर बनाम मल्टीपल ड्रा कॉल


14

मैं सिर्फ ओपनजीएल के साथ शुरुआत कर रहा हूं, और मैं इसे 2 डी गेम बनाने के लिए उपयोग करने का प्रयास कर रहा हूं। इस खेल में, मेरे पास एक हेक्सागोनल ग्रिड है जो बहुत अलग-अलग रंग के हेक्सागोन्स की एक बहुत बड़ी विविधता से बना है। एक नौसिखिया OpenGL प्रोग्रामर के रूप में, मुझे इस ग्रिड को बनाने के दो तरीके दिखाई देते हैं:

  1. एक एकल हेक्सागोन के लिए डेटा के साथ एक वर्टेक्स बफर का उपयोग करना, फिर एक समान ऑफसेट मूल्य का उपयोग करना और सीपीयू पर पुनरावृति करना कई बार एक ही कार्यक्रम को आकर्षित करने के लिए जब तक मेरे पास ग्रिड नहीं है।
  2. एक एकल बहुत बड़ी पूर्व-गणना वर्टेक्स बफर बनाना जो एक कॉल में सभी हेक्सागोन्स खींचता है।

सबसे कुशल तरीका क्या है? क्या ऐसा करने का कोई बेहतर तरीका है?


आपके पूर्व-परिकलित शीर्ष बफ़र को केवल स्क्रीन को एक षट्भुज द्वारा विस्तारित करने की आवश्यकता है, आप तब तक इसे आसानी से स्क्रॉल करके नकली कर सकते हैं जब तक कि आप एक पूर्ण षट्भुज पर न जाएं और फिर "वारपिंग" करें, जैसा कि उस परिदृश्य में रंगों के लिए है, आप एक रख सकते हैं जीपीयू पर 2 डी बनावट, इसे वर्टेक्स शेडर में पढ़ें, और फ्लैट इसे टुकड़े टुकड़े करने वाले में विभाजित करते हैं।
मिकेल

पास आमतौर पर एक ऐसी स्थिति को संदर्भित करता है जहां एक रेंडर ऑपरेशन एक पूर्व ऑपरेशन के परिणामों पर निर्भर करता है। आप इस प्रश्न के बारे में जो पूछ रहे हैं वह वास्तव में एक पास के भीतर ड्रा कॉल की संख्या को कम करने से संबंधित है। मुझे पता है कि यह पांडित्यपूर्ण लगता है, लेकिन अंतर को समझना बहुत महत्वपूर्ण है अन्यथा मल्टी-पास एल्गोरिदम बहुत मायने नहीं रखेगा;)
एंडन एम। कोलमैन

@ AndonM.Coleman हम्म, धन्यवाद, मैं स्पष्ट रूप से ग्राफिक्स शब्दावली से परिचित नहीं हूं। तो, इस मामले में, मैं इसका वर्णन कैसे करूंगा? एकाधिक shader / कार्यक्रम कॉल?
एलेक्सिस किंग

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

जवाबों:


9

ऐसे ग्रिड बनाने के लिए वास्तव में कुछ तरीके हैं।

सबसे कारगर तरीका होगा इंस्टेंस। इस तरह से आप अपने षट्भुज को केवल एक बार VBO में बनाते हैं, और इसे सौ, हज़ार या लाख बार प्रस्तुत करते हैं। जैसा कि आपने बिंदु 1 में कहा था वर्दी के साथ शेड्स का उपयोग करके आप इसे मैन्युअल रूप से कर सकते हैं, लेकिन इसके लिए एक अंतर्निहित ओपनगैल कार्यक्षमता भी है। उसके लिए, glDrawElementsInstanced पर एक नज़र डालें

ध्यान दें कि यदि आप एक निश्चित मात्रा से अधिक मात्रा में वस्तुओं को खींचते हैं तो इंस्टेंसेस केवल अन्य विधियों की तुलना में तेज है। उदाहरण के लिए, ड्राइंग 1 बड़ा वीबीओ का उपयोग करके 300 तेजी से हो सकता है, लेकिन यदि आप इंस्टेंटेड रेंडरिंग का उपयोग करते हैं तो 2 मिलियन ड्राइंग तेजी से हो सकते हैं।

यदि आप इंस्टेंटेड रेंडरिंग का उपयोग करते हैं तो आप एट्रिब्यूट डिवाइडर का उपयोग करके प्रति-ऑब्जेक्ट डेटा भेज सकते हैं । अपने मामले में आप स्थिति और रंग भेजना चाहते हैं।

इंस्टेंटेड प्रतिपादन पर एक अच्छा ट्यूटोरियल: क्लिक करें

वास्तव में सबसे अच्छा तरीका दोनों तरीकों की कोशिश करना है, और 1 फ्रेम खींचने के लिए मिलीसेकंड की मात्रा की जांच करना है। इस तरह आप दोनों तरीके भी सीखते हैं, जो हमेशा अच्छा होता है।

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


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

माना। मैंने उदाहरण के लिए विंडोज / लिनक्स और एटी / एनवीडिया पर अलग-अलग प्रदर्शन देखे हैं। जोड़ के लिए धन्यवाद।
बासा

1
असल में। यदि आप एक एकल vbo के भीतर कई संयुक्त जाल (कि एक ही स्थान साझा) आकर्षित करते हैं। किसी भी तरह से इंस्टेंसिंग तेज नहीं हो सकती है। इंस्टेंसिंग के साथ समस्या यह है: कोने समानांतर गणना की गई आवृत्ति नहीं हैं। यह केवल gpu / cpu / gpu सिंक / drawcall को समाप्त करता है। इसलिए हार्डवेयर इंस्टेंस के साथ 1000 गोले खींचने की तुलना में 1000 गोले वाले एक शीर्ष बफर को खींचना अधिक तेज़ है। (नो फ्रम क्यूलिंग / ऑब्जेक्ट डिस्टेंस डिटेल ऑप्टिमाइजेशन शामिल)
जीरो वैन वैन लैंगेन

3

विधि 1 कोड के लिए सरल है और तब तक ठीक रहेगा जब तक आपके पास एक बार में बहुत अधिक षट्भुज न हों। आप एक बार में अपनी प्लेट पर बहुत अधिक जटिलता डालने से बचने के लिए OpenGL के नए होने के बाद से इसके साथ रहना चाहते हैं।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.