आप उप-पिक्सेल वेतन वृद्धि में स्प्राइट को कैसे स्थानांतरित करते हैं?


11

पिक्सेल या तो चालू या बंद हैं। आप स्प्राइट को स्थानांतरित कर सकते हैं न्यूनतम राशि एक एकल पिक्सेल है। तो आप 1 फ्रेम प्रति फ्रेम से अधिक स्प्राइट मूव कैसे करते हैं?

जिस तरह से मैंने किया वह गति को एक चर और परीक्षण में जोड़ना था यदि यह 1 (या -1) तक पहुंच गया था। अगर ऐसा होता है, तो मैं स्प्राइट को स्थानांतरित करूंगा और चर को 0 पर रीसेट करूंगा, जैसे:

update(dt):
    temp_dx += speed * dt
    temp_dy += speed * dt

    if (temp_dx > 1)
        move sprite
        reset temp_dx to 0
    if (tempy_dy > 1)
        move sprite
        reset temp_dy to 0

मैंने इस दृष्टिकोण को नापसंद किया क्योंकि यह मूर्खतापूर्ण लगता है और स्प्राइट का आंदोलन बहुत झटकेदार लगता है। तो आप किस तरह से उप-पिक्सेल आंदोलन को लागू करेंगे?


केवल एक चीज जो आप कर सकते हैं वह है बिलिनियर फ़िल्टरिंग।
अट्टुरसम्स

यदि आप प्रति फ्रेम 1 px से कम गति कर रहे हैं, तो यह झटकेदार कैसे दिख सकता है?

जवाबों:


17

कई विकल्प हैं:

  1. जैसा करते हो वैसा करो। आपने पहले ही कहा है कि यह चिकना नहीं दिखता है। हालांकि आपके मौजूदा तरीके में कुछ खामियां हैं। इसके लिए x, आप निम्नलिखित का उपयोग कर सकते हैं:

    tempx += speed * dt
    
    while (tempx > 0.5)
      move sprite to x+1
      tempx -= 1
    while (tempx < -0.5)
      move sprite to x-1
      tempx += 1

    यह बेहतर होना चाहिए। अगर आपने 0.5 पार कर लिया है तो मैंने 0.5 का उपयोग करने के लिए यदि स्टैच्यूज़ को स्विच किया है, तो आप पिछले मूल्य की तुलना में अगले मान के करीब हैं। मैंने 1 से अधिक पिक्सेल प्रति समय कदम की गति के लिए अनुमति देने के लिए छोरों का उपयोग किया है (यह ऐसा करने का सबसे अच्छा तरीका नहीं है, लेकिन यह कॉम्पैक्ट और पठनीय कोड के लिए बनाता है)। धीमी गति से चलती वस्तुओं के लिए, यह अभी भी उछल-कूद करेगा, क्योंकि हमने पिक्सेल संरेखण के मूलभूत मुद्दे से निपटा नहीं है।

  2. अपने स्प्राइट के लिए कई ग्राफिक्स रखें और सबपिक्सल ऑफसेट के आधार पर एक अलग का उपयोग करें। उदाहरण के लिए, केवल एक्स में सबपिक्सल स्मूथिंग करने के लिए, आप अपने स्प्राइट के लिए एक ग्राफिक बना सकते हैं x+0.5, और यदि स्थिति बीच में है x+0.25और x+0.75, अपने मूल के बजाय इस स्प्राइट का उपयोग करें। यदि आप बेहतर स्थिति चाहते हैं, तो बस अधिक उप-ग्राफिक्स बनाएं। यदि आप ऐसा करते हैं xऔर yआपके रेंडरिंग की संख्या जल्दी से गुब्बारा हो सकती है, क्योंकि अंतराल की संख्या के वर्ग के साथ संख्या तराजू: 0.54 के एक रिक्ति की आवश्यकता 0.25होगी , 16 की आवश्यकता होगी।

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

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

2. 3. और 4. के बीच का चुनाव इस बात पर निर्भर करता है कि आपके ग्राफिक्स कैसे लागू होते हैं। ग्राफिक्स की एक बिटमैप शैली पहले से बेहतर प्रतिपादन करती है, जबकि एक वेक्टर शैली स्प्राइट सुपरप्लूमिंग के अनुरूप हो सकती है। यदि आपका सिस्टम इसका समर्थन करता है, तो 4. जाने का रास्ता भी हो सकता है।


ऑप्ट १ में ०.५ की सीमा क्यों बदलें? मुझे यह भी समझ में नहीं आता है कि आपने बयानों को थोड़ी देर के लिए क्यों स्थानांतरित किया। अद्यतन कार्यों को एक बार प्रति टिक कहा जाता है।
बज़्र

1
अच्छा प्रश्न - मैंने आपकी टिप्पणी के आधार पर उत्तर स्पष्ट कर दिया है।
Jez

सुपरसम्पलिंग "आलसी" हो सकता है, लेकिन कई मामलों में 2x या 4x ओवरसैंपलिंग की प्रदर्शन लागत एक विशेष समस्या नहीं होगी, खासकर अगर यह रेंडरिंग के अन्य पहलुओं को सरल बनाने की अनुमति देता है।
सुपरकाट

बड़े बजट के खेल में, मैं आमतौर पर ग्राफिक्स सेटिंग में सूचीबद्ध 3 विकल्प को एंटी-अलियासिंग के रूप में देखता हूं।
केविन

1
@ केविन: आप वास्तव में शायद नहीं। अधिकांश गेम मल्टीसमैपलिंग का उपयोग करते हैं , जो कुछ अलग है। अन्य वेरिएंट भी आमतौर पर उपयोग किए जाते हैं, उदाहरण के लिए अलग-अलग कवरेज के साथ-साथ गहराई के नमूने। टुकड़े टुकड़े करना निष्पादन की लागत के कारण सुपरस्मैपलिंग लगभग कभी नहीं किया जाता है।
imallett

14

एक तरीका जिसमें कई पुराने-स्कोल गेम हल किए गए (या छिप गए) यह समस्या स्प्राइट को चेतन करने के लिए थी।

यही है, अगर आपका स्प्राइट एक पिक्सेल प्रति फ्रेम से कम चलने वाला था (या, विशेष रूप से, अगर पिक्सेल / फ्रेम अनुपात 3 फ्रेम में 2 पिक्सल की तरह कुछ अजीब होने वाला था), तो आप एक n बनाकर झटके को छिपा सकते थे फ़्रेम एनीमेशन लूप, उन n फ़्रेमों पर, कुछ के < n पिक्सेल द्वारा स्प्राइट को स्थानांतरित करना समाप्त कर दिया ।

मुद्दा यह है कि, जब तक स्प्राइट हमेशा हर फ्रेम पर किसी न किसी तरह से चलता रहता है , तब तक कभी भी ऐसा कोई फ्रेम नहीं होगा जहां पूरा स्प्राइट अचानक "झटके" के साथ आगे बढ़ जाए।


मुझे यह बताने के लिए एक पुराने वीडियो गेम से वास्तविक स्प्राइट नहीं मिला (हालांकि मुझे लगता है कि लेमिंग्स के कुछ खुदाई एनिमेशन इस तरह थे), लेकिन यह पता चला है कि कॉनवे के गेम से "ग्लाइडर" पैटर्न जीवन का खेल बनाता है। बहुत अच्छा चित्रण:

यहाँ छवि विवरण दर्ज करें
सीसी-बाय-एसए 3.0 लाइसेंस के तहत उपयोग किए जाने वाले कीफ / विकिमीडिया कॉमन्स द्वारा एनीमेशन

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


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

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

6

स्प्राइट की स्थिति को फ्लोटिंग पॉइंट मात्रा के रूप में रखा जाना चाहिए, और केवल प्रदर्शन से पहले पूर्णांक तक गोल किया जाना चाहिए।

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


3

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

पेशेवरों:

पहले से ही कार्यान्वित, बहुत तेज़, हार्डवेयर आधारित समाधान।

विपक्ष:

8-बिट / 16-बिट निष्ठा का नुकसान।


1

फ्लोटिंग पॉइंट यह करने का सामान्य तरीका है, खासकर यदि आप अंततः जीएल लक्ष्य को प्रदान कर रहे हैं जहां हार्डवेयर फ्लोट निर्देशांक के साथ एक छायांकित बहुभुज के साथ काफी खुश है।

हालाँकि वर्तमान में आप जो कर रहे हैं उसका थोड़ा और तरीका है लेकिन थोड़ा कम झटका: निश्चित बिंदु। भले ही आपकी स्क्रीन लगभग 4k पिक्सेल से कम हो, लेकिन 32 बिट स्थिति मान 4,294,967,295 के माध्यम से मानों का प्रतिनिधित्व कर सकता है। इसलिए बीच में एक निश्चित "बाइनरी पॉइंट" (दशमलव बिंदु के साथ सादृश्य द्वारा) डालें और आप 0-65536 से उप-पिक्सेल रिज़ॉल्यूशन के 16 बिट्स के साथ 0-65536 से पिक्सेल स्थिति का प्रतिनिधित्व कर सकते हैं। फिर आप संख्याओं को सामान्य रूप से जोड़ सकते हैं, बस आपको स्क्रीन स्पेस में कनवर्ट करते समय या जब आपने दो संख्याओं को एक साथ गुणा किया है, तो 16 बिट्स को सही शिफ्टिंग द्वारा परिवर्तित करना याद रखना होगा।

(मैंने उस दिन 16-बिट फिक्स्ड पॉइंट में एक 3 डी इंजन लिखा था जब मेरे पास एक इंटेल 386 था जिसमें कोई फ्लोटिंग पॉइंट यूनिट नहीं था। यह प्रति फ्रेम 200 फोंग-शेडेड पॉलीगॉन की अंधाधुंध गति प्राप्त करता था।)


1

अन्य उत्तरों के अलावा, आप कुछ हद तक डीथरिंग का उपयोग कर सकते हैं। डिटररिंग वह जगह है जहां किसी वस्तु के पिक्सल्स के किनारे हल्के / गहरे रंग के होते हैं, जो कि नरम किनारे के लिए पृष्ठभूमि बनाने से मेल खाते हैं। उदाहरण के लिए, मान लें कि आपके पास एक 4 पिक्सेल वर्ग है, जिसके साथ मैं अनुरक्त हूं:

OO
OO

यदि आप इस 1/2 को दाईं ओर ले जाते हैं, तो वास्तव में कुछ भी नहीं हिलता। लेकिन कुछ डाइटिंग से आप आंदोलन को थोड़ा सा भ्रम बना सकते हैं। हे के रूप में काले और ग्रे के रूप में ओ पर विचार करें, इसलिए आप ऐसा कर सकते हैं:

oOo
oOo

एक फ्रेम में और

 OO
 OO

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

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