2011-02-14 15 views
6

मैं सी ++/ओपनजीएल में स्थैतिक 3 डी ब्लॉक दुनिया जैसे Minecraft लिख रहा हूं। मैं framerates में सुधार करने के लिए काम कर रहा हूँ, और अब तक मैं एक ऑक्टेट का उपयोग कर frustum culling लागू किया है। इससे मदद मिलती है, लेकिन मैं अभी भी मध्यम से खराब फ्रेम दर देख रहा हूं। अगला कदम क्यूब्स को कम करना होगा जो दृष्टिकोण से छिपे हुए क्यूब्स से छिपे हुए हैं। हालांकि मैं इसे पूरा करने के तरीके पर कई संसाधन नहीं ढूंढ पा रहा हूं।3 डी ऑक्लुजन कूलिंग

+0

आपने जेड-बफर के बारे में पढ़ा है? http://de.wikipedia.org/wiki/Z- बफर –

+2

@ थॉमस: आप का अर्थ हो सकता है http://en.wikipedia.org/wiki/Z-Buffer :) –

+0

मैंने उनके बारे में संक्षेप में पढ़ा है, लेकिन पर्याप्त नहीं है उन्हें जानने के लिए कैसे पता है। मुझे और पढ़ना होगा। –

उत्तर

7

एक जेड-बफर (या "गहराई बफर") के साथ एक रेंडर लक्ष्य बनाएं। फिर अपने सभी अपारदर्शी वस्तुओं को सॉर्ट करना सुनिश्चित करें ताकि उन्हें पहले से पीछे की ओर प्रस्तुत किया जा सके, यानी पहले कैमरे के सबसे नज़दीक हैं। अल्फा ब्लेंडिंग का उपयोग करने वाले कुछ भी अभी भी आपके सभी अपारदर्शी वस्तुओं को प्रस्तुत करने के बाद, आगे की ओर प्रस्तुत किए जाने की आवश्यकता है।

एक और तकनीक प्रलोभन खींच रहा है: आप सस्ती रूप से अपनी ज्यामिति को "सूखा-प्रस्तुत" कर सकते हैं और फिर पता लगा सकते हैं कि कितने पिक्सल गहराई परीक्षण में विफल रहे। डायरेक्टएक्स और ओपनजीएल में प्रलोभन क्वेरी समर्थन है, हालांकि हर जीपीयू ऐसा नहीं कर सकता है।

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

और एक और बात: एक अधिक पारंपरिक समाधान (जिसे आप संलयन कूलिंग के साथ समवर्ती रूप से उपयोग कर सकते हैं) एक कमरा/पोर्टल सिस्टम है, जहां आप "पोर्टल" के माध्यम से क्षेत्रों को "कमरे" के रूप में परिभाषित करते हैं। यदि कोई पोर्टल आपके वर्तमान कमरे से दिखाई नहीं दे रहा है, तो आप उससे जुड़े कमरे को नहीं देख सकते हैं। और यहां तक ​​कि, आप पोर्टल के माध्यम से जो दिखाई दे रहे हैं, उसके लिए आप अपने व्यूपोर्ट पर क्लिक कर सकते हैं।

+1

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

+0

इसके लिए, प्रलोभन कूलिंग है। मुझे उस विषय को छूने के लिए अपना जवाब संपादित करना चाहिए। – EboMike

3

यदि आपके पास कैमरे के नजदीक सतहें हैं, तो आप एक निराशा बना सकते हैं जो एक क्षेत्र का प्रतिनिधित्व नहीं करता है जो दिखाई नहीं दे रहा है, और उस ऑब्जेक्ट को पूरी तरह से निहित वस्तुएं हैं। नीचे दिए गए आरेख में, C कैमरा है, | कैमरे के पास एक सपाट सतह है, और . से बना फ्रस्टम-आकार वाला क्षेत्र प्रक्षेपित क्षेत्र का प्रतिनिधित्व करता है। सतह को antiportal कहा जाता है।

 . 
     .. 
     ... 
    .... 
    |.... 
    |.... 
    |.... 
    |.... 
C |.... 
    |.... 
    |.... 
    |.... 
    .... 
     ... 
     .. 
     . 

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

+0

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

4

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

यदि आप प्रत्येक ब्लॉक को एक अलग ड्रॉ कॉल (glDrawElements/Arrays, glbegin/glEnd, आदि) के साथ चित्रित कर रहे हैं (बोनस अंक: glbegin/glEnd का उपयोग न करें) तो यह आपकी बाधा होगी। शुरुआती लोगों के लिए यह एक आम नुकसान है। यदि आप ऐसा कर रहे हैं, तो आपको प्रत्येक त्रिकोणों को एक साथ बैच करने की आवश्यकता है जो प्रत्येक सेटअप के लिए एक कॉल में बनावट और छायांकन पैरामीटर साझा करते हैं। यदि ज्यामिति स्थैतिक है और फ्रेम को फ्रेम में नहीं बदलती है, तो आप त्रिकोण के प्रत्येक बैच के लिए एक Vertex Buffer Object का उपयोग करना चाहते हैं।

यह अभी भी एक ऑक्टेट्री के साथ फ्रस्टम कूलिंग के साथ जोड़ा जा सकता है यदि आपके पास आमतौर पर केवल एक ही समय में आपके कुल गेम की दुनिया का एक छोटा सा हिस्सा होता है। कशेरुक बफर अभी भी स्थिर रूप से लोड किए गए हैं और बदले नहीं गए हैं। Frustum frctum में त्रिकोण के लिए केवल सूचकांक बफर उत्पन्न करने के लिए octree को खींचें और उन गतिशील रूप से प्रत्येक फ्रेम अपलोड करें।

+0

मैं आधुनिक प्रणाली (फ्रॉम 8800 जीटी, डुअल कोर, 2 जीबी रैम) पर फ्रस्टम कूलिंग से पहले ~ 250,000 1x1x1 cubes ड्राइंग कर रहा हूं। निराशा को कम करने के साथ, मुझे 17.83 एफपीएस की फ्रेम दर मिल रही है, बिना ~ 2 एफपीएस की निराशा के बिना। क्यूब्स का वास्तविक चित्र प्रदान किए गए इंटरफेस के माध्यम से किया जाता है, लेकिन जो मैं कह सकता हूं, उससे ग्लूशश/पॉपमैट्रिक्स और ग्लूटसॉलीक्यूब का उपयोग करके खींचा जा रहा है। –

+0

glutSolidCube आपकी समस्या है। आप एक समय में 250,000 क्यूब्स खींचने के लिए सभी राज्य परिवर्तनों से बंधे हैं। 1000 वस्तुओं के तहत उचित गति पर चलाने के लिए एक सामान्य सीमा होगी। – Alan

5

this minecraft level renderer में जो दृष्टिकोण मैंने लिया वह अनिवार्य रूप से एक निराशाजनक सीमित बाढ़ भरना है।16x16x128 भाग 16x16x16 chunklets में विभाजित हैं, प्रत्येक प्रासंगिक ज्यामिति के साथ एक वीबीओ के साथ। मैं प्रस्तुत करने के लिए चंकलेट खोजने के लिए खिलाड़ी के स्थान पर चंकलेट ग्रिड में बाढ़ भरना शुरू करता हूं। भरने के द्वारा सीमित है:

  1. दृश्य छिन्नक
  2. ठोस chunklets - अगर एक chunklet के पूरे पक्ष है अपारदर्शी ब्लॉक, तो floodfill chunklet उस दिशा में
  3. दिशा में प्रवेश नहीं करेगा - बाढ़ दिशा विपरीत नहीं होगी, उदाहरण के लिए: यदि वर्तमान चंकलेट शुरुआती चंकलेट के उत्तर में है, तो दक्षिण में चंकलेट में बाढ़ न करें

ऐसा लगता है कि यह ठीक काम करता है। मैं एंड्रॉइड पर हूं, इसलिए एक अधिक जटिल विश्लेषण (माइक डेनियल द्वारा नोट किए गए एंटीपार्टल्स) अधिक ज्यामिति को कम करेंगे, मैं पहले ही सीपीयू-सीमित हूं इसलिए बहुत अधिक बिंदु नहीं है।

मैंने अभी आपका जवाब एलन को देखा है: कूलिंग आपकी समस्या नहीं है - यह है कि आप धीमे होने वाले ओपनजीएल को क्या और कैसे भेज रहे हैं।

क्या आकर्षित करना है: प्रत्येक ब्लॉक के लिए घन प्रस्तुत न करें, पारदर्शी ब्लॉक के चेहरे प्रस्तुत करें जो एक अपारदर्शी ब्लॉक को सीमाबद्ध करते हैं। कहें, पत्थर के ब्लॉक के 3x3x3 घन पर विचार करें: केंद्र ब्लॉक को खींचने का कोई मतलब नहीं है क्योंकि खिलाड़ी इसे देख नहीं सकता है। इसी तरह, खिलाड़ी कभी भी दो आसन्न पत्थर के ब्लॉक के बीच चेहरे नहीं देख पाएगा, इसलिए उन्हें आकर्षित न करें।

कैसे आकर्षित करें: एलन द्वारा नोट किया गया है, ज्यामिति बैच करने के लिए वीबीओ का उपयोग करें। आप विश्वास नहीं करेंगे कि वे चीजें कितनी तेजी से करते हैं।

आपके मौजूदा कोड में न्यूनतम परिवर्तन के साथ एक आसान दृष्टिकोण, display lists का उपयोग करना होगा। यही वह है जो Minecraft का उपयोग करता है।

-2

जेड-बफर का उपयोग यह सुनिश्चित करता है कि बहुभुज सही ढंग से ओवरलैप हो जाएं।

गहराई परीक्षण सक्षम करने से प्रत्येक ड्राइंग ऑपरेशन स्क्रीन पर पिक्सल रखने से पहले जेड-बफर की जांच करता है।

यदि आपके पास उत्तल वस्तुएं हैं तो आपको (प्रदर्शन के लिए) बैकफ़ेस कूलिंग सक्षम करना होगा!

उदाहरण कोड:

glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE);

आप glCullFace के व्यवहार (बदल सकते हैं) GL_FRONT या GL_BACK गुजर ...

glCullFace(...);

// "खेल दुनिया" ड्रा। ..