2 डी ग्राफिक्स - स्प्राइटशीट का उपयोग क्यों करें?


62

मैंने स्प्राइटशीट से स्प्राइट को कैसे प्रस्तुत करना है, इसके कई उदाहरण देखे हैं, लेकिन मैंने यह समझा कि 2 डी गेम में स्प्राइट से निपटने का सबसे आम तरीका है।

मैंने 2d स्प्राइट रेंडरिंग के साथ कुछ डेमो अनुप्रयोगों में शुरुआत की है जो मैंने प्रत्येक एनीमेशन फ्रेम के साथ किसी भी स्प्राइट प्रकार से निपटने के लिए अपनी बनावट के रूप में बनाया है - और बनावट के इस संग्रह को एक शब्दकोश में संग्रहीत किया गया है। यह मेरे लिए काम करने लगता है, और मेरे वर्कफ़्लो को बहुत अच्छी तरह से सूट करता है, क्योंकि मैं अपने एनिमेशन को gif / mng फ़ाइलों के रूप में बनाता हूं और फिर फ़्रेम को अलग-अलग png में निकालता हूं।

क्या व्यक्तिगत बनावट के बजाय एकल शीट से प्रस्तुत करने के लिए ध्यान देने योग्य प्रदर्शन लाभ है? आधुनिक हार्डवेयर के साथ जो लाखों पॉलीगनों को स्क्रीन पर सौ बार दूसरी बार खींचने में सक्षम है, क्या यह मेरे 2 डी गेम के लिए भी मायने रखता है जो सिर्फ कुछ दर्जन 50x100px आयतों से निपटते हैं?

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

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


नहीं, यह वास्तव में आपके 50 विषम स्प्राइट्स के लिए बहुत ज्यादा मायने नहीं रखता है। लेकिन हारना क्या है?
कम्युनिस्ट डक

जवाबों:


69

स्प्राइटशीट का उपयोग करने के लिए एक मजबूत तर्क यह है कि ग्राफिक कार्ड पर उपलब्ध बनावट की संख्या सीमित हो सकती है। इसलिए आपकी ग्राफिक्स लाइब्रेरी को लगातार बनावट को हटाना होगा और GPU पर बनावट को फिर से आवंटित करना होगा। यह एक बार एक बड़ी बनावट आवंटित करने के लिए बहुत अधिक कुशल है।

यह भी विचार करें कि बनावट का आकार आमतौर पर 2 की शक्ति है। इसलिए यदि आपके पास 50x100px स्प्राइट है, तो आप 64x128px आकार या बदतर स्थिति में 128x128px आकार के साथ बनावट आवंटित करेंगे। यह सिर्फ ग्राफिक्स मेमोरी बर्बाद कर रहा है। बेहतर ढंग से सभी स्प्राइट को 1024x1024px बनावट में पैक करें, जो 20x10 स्प्राइट की अनुमति देगा और आप केवल 24 पिक्सेल क्षैतिज और लंबवत रूप से खो देंगे। कभी-कभी विभिन्न आकारों के स्प्राइट्स को बनावट के रूप में संभव के रूप में उपयोग करने के लिए एक विशाल स्प्राइट-शीट में जोड़ा जाता है।

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


1
धन्यवाद, मैंने या तो उन बिंदुओं पर विचार नहीं किया था - क्या आप मोटे तौर पर जानते हैं कि उपलब्ध बनावट की संख्या पर सीमा क्या है? मैंने ग्राफ़िक्स विनिर्देशों पर उल्लिखित इस स्टेट को कभी नहीं देखा है - क्या यह सीमा मूल रूप से ग्राफिक्स रैम की मात्रा के बराबर है?
कोलंबो

आमतौर पर सीमा जीपीयू मेमोरी होगी, हाँ। मैंने सोचा कि पुराने कार्डों पर बनावट की संख्या पर कुछ प्रतिबंध हैं लेकिन मुझे ऐसा कोई संदर्भ नहीं मिल रहा है जो उस बिंदु को साबित करता हो।
बंमज़ैक 17

12
यहां तक ​​कि अगर मात्रा पर कोई सीमा नहीं है, तो बहुत सारी छोटी छवियों को स्थानांतरित करने के लिए बस-ट्रैफ़िक एक (या कुछ) बड़े स्थानांतरण (ओं) के रूप में कुशल नहीं है।
मोरधाई

5
अच्छे अंक, लेकिन सबसे महत्वपूर्ण पहलू ड्रॉ कॉल काउंट को नीचे रखकर पाइपलाइन स्टालों को कम करना है। जीपीयू बड़ी नौकरियों की एक छोटी राशि के बजाय बड़ी नौकरियों की एक छोटी राशि पसंद करते हैं। अपने सभी स्प्राइट्स को बड़ी शीट्स के एक छोटे से अमाउंट में डालने का मतलब है कि आप टेक्स्ट स्टेज को एक बार सेट कर सकते हैं और एक बैच में एक ही बार में बहुत सारे स्पाइट ड्रा कर सकते हैं। स्प्रिटबैच आपके लिए ऐसा करता है। यदि आपके पास एक से अधिक स्प्रिटशीट है, तो बनावट के आधार पर स्प्राइटबैच बताना सुनिश्चित करें
Cubed2D

बनावट संपीड़न जोड़ना किसी भी सुस्त स्थान को ओवरहेड की एक छोटी सी छोटी मात्रा में बदल देगा, उस सब के ऊपर
जो प्लांटे

36

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

यह अंतरिक्ष को बचाने में भी मदद कर सकता है, लेकिन यह इस बात पर निर्भर करता है कि पहली बार स्प्राइटशीट में आपकी पैकिंग क्या है।


2
+1 आह्वान ड्रॉ कॉल पर। (कुछ मैं स्वीकृत उत्तर में नहीं देखा था)
माइकल कोलमैन

11

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


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

मैं निश्चित रूप से सोच रहा था कि बनावट u, v 3 डी हार्डवेयर के बहुत से मानचित्रण, प्लस बिट ब्लास्टिंग ऑपरेशन स्प्राइट शीट से लाभान्वित होते हैं।
जो प्लांट

7

प्रदर्शन के विचारों के अलावा, कला का निर्माण करते समय स्प्राइट शीट को हाथ लगाया जा सकता है; प्रत्येक पात्र अपनी स्वयं की शीट में हो सकता है, और आप सभी फ़्रेमों को केवल स्क्रॉल करके देख सकते हैं। यह मुझे सभी फ़्रेमों पर एक सुसंगत नज़र रखने में मदद करता है।

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


1
+1। हालांकि ओपी फ्लैश का उपयोग नहीं कर रहा है, लेकिन एम्बेड करना या लोड करना भी स्प्राइटशीट के पक्ष में एक बिंदु है। यह तब भी प्रासंगिक है जब संपत्ति एक वेबसर्वर से भरी हुई है जहाँ 1 अनुरोध कई सौ अनुरोधों (प्रत्येक "फ्रेम" के लिए) से अधिक पसंद किया जाता है।
बंमज़ैक

निश्चित रूप से आप एक ऑनलाइन गेम के लिए सर्वर अनुरोधों को कम करना चाहते हैं। हमने विचार किया कि क्या छवियों को एक .swf या स्प्राइटशीट में रखना बेहतर है क्योंकि दोनों ही इस मुख्य लक्ष्य को पूरा करते हैं (हमने अंततः स्प्रिटशीट का फैसला किया कि हमारे कलाकारों के लिए कम श्रम गहन हैं)।
झिंगिंग

7

XNA के साथ स्प्राइटशीट का उपयोग करने का एक और कारण यह है कि Xbox360 विकास के साथ आपकी परियोजना में आपके पास मौजूद फ़ाइलों की संख्या के संबंध में धीमी तैनाती / लोड समय के साथ एक ज्ञात समस्या है। इसलिए एक ही छवि फ़ाइल में बहुत सारी छोटी छवि फ़ाइलों के संयोजन से उस समस्या से निपटने में मदद मिलेगी।


5

मैं यहाँ मेमोरी / जीपीयू का उल्लेख नहीं करने जा रहा हूँ, क्योंकि इस तरह के पर्याप्त उत्तर हैं।

इसके बजाय, यह आपकी कला को साफ कर सकता है क्योंकि आप इस पर काम करते हैं - और उसके बाद। चलने के चक्र को देखने के लिए 10 छवियों के माध्यम से फ़्लिक करने के बजाय, आप सभी फ़्रेमों को एक बार में देख सकते हैं। यदि आप इसे वितरित करना चाहते हैं, तो आपको 10 के बजाय सौदा करने के लिए केवल 1 फ़ाइल मिली है।

और फिर यह चरित्र (दृश्य के एक आयोजन बिंदु से) को भी साफ करना है।


4

ग्राफिक्स मेमोरी में डिस्क सिस्टम पर फ़ाइल सिस्टम की तरह ब्लोट अप मेमोरी प्रबंधन नहीं है ; oposite मामला है: यह सरल और तेज रखा जाता है ।

इस तरह की एक सरल और तेज़ मेमोरी मेंटेनेंस केवल एक विशालकाय 4096x4096 स्प्राइट के समान हो सकती है जो कि इसकी चौड़ाई और / या ऊँचाई को आधा करके कई छोटे स्प्राइट्स में कट जाती है। (एक समान 1-आयामी स्मृति-प्रबंधन तकनीक मौजूद है, लेकिन मैं नाम भूल गया।) आखिरकार, डीफ़्रैग्मेन्टेशन का प्रदर्शन किया जाना है।

ऐसे स्मृति प्रबंधन को रन-टाइम पर छोड़ने के लिए , डेवलपर्स बड़े-बड़े स्प्राइट्स को कई छोटे स्प्राइट्स के साथ स्वचालित रूप से संकलन-समय पर या ग्राफिक्स की डेसिंग-प्रोसेस में भरते हैं ।


3

इसके अलावा, मैं I / O संचालन को नहीं भूल सकता जो इसे आरंभ के दौरान आपको बचा सकता है। यदि आप सीडी ड्राइव से लोड कर रहे हैं, तो प्रत्येक फ़ाइल एक अतिरिक्त I / O कॉल है, और कुछ समय लग सकता है (आधुनिक HDD के बारे में 15 ms प्रति फ़ाइल, CD की शायद 50-100ms?)। यह आपको बहुत अधिक आरंभीकरण समय बचा सकता है क्योंकि केवल एक फ़ाइल को लाना है। यह आपके ओएस को इन I / O ऑपरेशनों को कैश करने की अनुमति देता है, यदि आपका एप्लिकेशन कुछ और कर रहा है (जैसे कि GPU की प्रतीक्षा में)।


1
दूसरे छोर पर यदि आप फ़ाइल की तलाश की समस्या को हल करना चाहते हैं, तो आप कस्टम प्रारूप का उपयोग करके अपने सभी स्प्राइट्स को एक फ़ाइल में पैक कर सकते हैं। ज्यादातर खेल यही करते हैं।
टाइगरॉ

0

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

मेरी राय में कोड करना भी आसान है। मेरे पास बस वस्तुओं की एक सरणी है:

sheet = {
    img: (the actual image),
    rects: [
        {x:0, y:0, w:32, h:32},
        {x:32, y:0, w:32, h:32},
        {x:64, y:0, w:32, h:32}
    ]
};

sheets.push(sheet);

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

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