मैं वास्तविक समय में तेजी से हस्ताक्षरित दूरी क्षेत्र (2D) कैसे उत्पन्न कर सकता हूं?


21

एक में पिछले प्रश्न है, यह सुझाव दिया है कि हस्ताक्षरित दूरी फ़ील्ड, precomputed किया जा सकता है क्रम में लोड और फिर वहाँ से इस्तेमाल किया गया था।

कारणों से मैं इस प्रश्न के अंत में समझाऊंगा (रुचि रखने वाले लोगों के लिए), मुझे वास्तविक समय में दूरस्थ क्षेत्रों को बनाने की आवश्यकता है।

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

आप विशेष रूप से दूरी के क्षेत्रों की गुणवत्ता को देखते हुए वास्तविक समय में (निश्चित रूप से GPU पर) दूरी के क्षेत्र बनाने के लिए क्या एल्गोरिदम सुझाएंगे?

चूँकि मैं एक वास्तविक विवरण / ट्यूटोरियल की तलाश कर रहा हूँ, जो किसी अन्य पेपर या स्लाइड के लिंक के विपरीत है, यह प्रश्न एक बार प्राप्त होगा जब यह एक के लिए योग्य होगा।

यहां मुझे वास्तविक समय में ऐसा करने की आवश्यकता है:

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

उदाहरण के लिए, 10 * 10 पिक्सल के टाइल आकार के साथ 1000 * 256 (चौड़ाई * ऊंचाई) के साथ एक अपेक्षाकृत छोटा नक्शा और इस प्रकार 10000 * 2560 पिक्सल के कुल आयामों के लिए आपको पहले से ही लगभग 2 मेगाबाइट आकार का खर्च आएगा, यदि आप एक अपेक्षाकृत छोटा चुनते हैं 128x128 का SDF रिज़ॉल्यूशन, यह मानते हुए कि आप केवल 0 से 255 तक की दूरी का मान जमा कर रहे हैं।

जाहिर है, यह जल्दी से बहुत अधिक हो सकता है और एक ओवरहेड है जो मुझे नहीं करना है।

कुछ और है:

एसडीएफ का उपयोग कई चीजों के लिए किया जा सकता है (जैसे टकराव का पता लगाना), और कुछ उपयोगी एप्लिकेशन संभवतः अभी तक खोजे नहीं गए हैं। मुझे लगता है कि भविष्य में बहुत से लोग इन चीजों की तलाश करने जा रहे हैं, और अगर हमें यहां व्यापक जवाब मिलता है, तो मुझे लगता है कि हम बहुत से लोगों की मदद करने जा रहे हैं।


मैंने गुगली की "क्या एक हस्ताक्षरित दूरी क्षेत्र है" और पहला हिट एक GPU संस्करण था: http.developer.nvidia.com/GPUGems3/gpugems3_ch34.html यह थोड़ा पुराना है, लेकिन आपकी खोजों को आगे बढ़ाने में मदद कर सकता है।
पैट्रिक ह्यूजेस

1
हो सकता है कि मुझे कुछ याद आ रहा है, लेकिन मैं इस बयान से कुछ उलझन में हूं कि आपको वास्तविक समय में इसे करने की आवश्यकता क्यों है (कम से कम, क्यों यह बिगाड़ने वाला टैग है); सबसे पहले, आपको 128x128 के एसडीएफ के लिए 2 एमबी आंकड़ा कहां मिलता है? दूसरे, आप 2MB को विशेष रूप से भारी मेमोरी उपयोग क्यों मानते हैं? मैं मानता हूं कि यह असंवेदनशील नहीं है, लेकिन यह आपके समग्र मानचित्र मेमोरी उपयोग का एक छोटा सा अंश लगता है। और तीसरा, रियलटाइम में फ़ील्ड बनाने से उस मेमोरी को कैसे बचाया जाएगा? आपको अभी भी वही डेटा संग्रहीत करने की आवश्यकता है, चाहे वह मक्खी पर उत्पन्न हो या पूर्व-निर्मित हो, नहीं?
स्टीवन स्टडनिक

मोटे तौर पर, यह आसानी से हो सकता है कि एसडीएफ आपके लिए आवश्यक तकनीक नहीं है। आपकी विशिष्ट स्थिति के बारे में अधिक जानकारी - स्थैतिक बाधा गणना, गतिशील बाधा गणना, आदि - और वास्तव में आप जो प्रभाव प्राप्त करने की उम्मीद कर रहे हैं, वह आपके लिए उपयोगी होने की संभावना को कम करने की कोशिश करने में मददगार होगा।
स्टीवन स्टडनिक

1
यदि मैं वास्तविक समय में दूरी क्षेत्र उत्पन्न करता हूं, तो मैं केवल 2MB एक समय प्रति फ्रेम (कुल मेमोरी ओवरहेड हमेशा एक दूरी फ़ील्ड के लिए आवश्यक मेमोरी होगी, क्योंकि मुझे केवल स्क्रीन के लिए एक की आवश्यकता है)। अगर मेरे पास मेरे 1000x128 उदाहरण से बड़ा नक्शा है (मुझे लगता है कि बड़े टेरारिया नक्शे 10000 से आगे जाते हैं) मुझे उस नक्शे के प्रत्येक 1000x128 उप-संस्करण के लिए उन 2mb में से एक की आवश्यकता है। मुझे पहले स्थान पर एसडीएफ की आवश्यकता क्यों है, इस प्रश्न की शुरुआत में पहले प्रश्न में वर्णित है (यह GPU 2 डी छाया के लिए है)।
ट्रैविसग्रेन

1
@heishe आप फ्रेम प्रति एक बार 2Mb डेटा उत्पन्न करने की कोशिश कर रहे हैं? गंभीरता से?
कावड

जवाबों:


9

कैटलिन जिमा बताती हैं कि अपने लेख में गतिशील 2 डी छाया कैसे प्राप्त करें - और वह एक हस्ताक्षरित दूरी क्षेत्र का उपयोग करता है (जो मैं बता सकता हूं कि इस संदर्भ में एक छाया बफर के लिए सिर्फ एक फैंसी नाम है)। उसकी विधि को एक GPU की आवश्यकता है, और जैसा कि उसका कार्यान्वयन सबसे अच्छा नहीं है (मेरी मशीन पर लगभग 20 लाइटों पर 60Hz से नीचे गिरा दिया गया, मेरी लगभग 500 रोशनी मिली); उम्मीद की जानी चाहिए क्योंकि उसने गति पर कोड की स्पष्टता का पक्ष लिया है।

कार्यान्वयन

उसके द्वारा कार्यान्वित किया गया:

  1. सभी छाया कलाकारों को एक बनावट में प्रस्तुत करना।
  2. प्रत्येक पिक्सेल के लिए प्रकाश के केंद्र की दूरी की गणना करें, और उस मान को अपारदर्शी पिक्सेल के RGB पर असाइन करें।
  3. छवि को विकृत करें ताकि यह प्रतिनिधित्व करे कि 3 डी कैमरे ने उन पिक्सेल को कैसे देखा होगा।
  4. अपने लेख में वर्णित असामान्य आकार (एक सादा आकार नहीं चलेगा) का उपयोग करके एक 2xN आकार की छवि में स्क्वैश करें।
  5. 2xN छवि अब प्रकाश के सभी चतुर्थांशों के लिए आपका हस्ताक्षरित दूरी क्षेत्र है (याद रखें कि एक क्वाड्रंट मूल रूप से 90 डिग्री पर एक एकल कैमरा फ्रॉम है)।
  6. लाइटमैप रेंडर करें।
  7. लाइटमैप को चमकाएं (प्रकाश से दूरी के आधार पर) ताकि आपको नरम छाया मिले।

मेरा अंतिम क्रियान्वयन था (प्रत्येक चरण एक ही shader):

  1. करो (१)।
  2. करो (2) और (3)
  3. करो (४)। उसका कार्यान्वयन वास्तव में धीमा है: यदि आप इसके लिए GPGPU का उपयोग कर सकते हैं। मैं GPGPU (XNA) का उपयोग नहीं कर सका इसलिए मैंने जो किया वह था:
    • एक जाल सेट करें जहां पहले N / 2 कॉलम N / 2 क्वाड्स द्वारा दर्शाए गए थे, उसी स्थिति के साथ (अंतिम बफर के पहले कॉलम को कवर करते हुए) लेकिन अलग-अलग बनावट के सह-निर्देशांक (दूसरे N / 2 कॉलम के लिए एक ही चीज़)
    • GPU पर गहराई से परीक्षण बंद करें।
    • MIN पिक्सेल ब्लेंडिंग फ़ंक्शन का उपयोग करें।
  4. करो (6) और (7)।

यह काफी सरल है: यह मूल रूप से 3 डी में 2 डी में छाया कैसे संभाला जाता है का एक सीधा अनुवाद है।

नुकसान

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


क्या आपका समायोजन आकार विधि में 60fps से ऊपर 500 रोशनी को संभालने के लिए इसे गति देने के लिए एकमात्र चीज थी?
ट्रैविसग

ठीक है, मैं उत्तर स्वीकार करूंगा क्योंकि यह मेरी मूल समस्या को हल करता है, लेकिन यह वास्तव में जवाब नहीं देता है कि मैंने इसके लिए क्या इनाम दिया है। मैं इंतजार करूँगा और शायद किसी को हस्ताक्षरित दूरी क्षेत्र पीढ़ी के लिए कई ओ (एन) तरीकों में से एक को समझाने के लिए एक लंबा समय आता है।
ट्रैविसग्रेन

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

खैर, यह एक हस्ताक्षरित दूरी क्षेत्र का एक बहुत ही खास मामला है। सामान्य हस्ताक्षरित दूरी क्षेत्र में, प्रत्येक पिक्सेल में निकटतम बाधा की दूरी होती है। इस एल्गोरिथ्म में, दूरी क्षेत्र में केवल एक बाधा होती है, और यह भी बाधा पूरी छवि (प्रकाश स्रोत) में केवल 1 पिक्सेल है, यही वजह है कि इस दूरी के क्षेत्र को ओ (एन) में उत्पन्न किया जा सकता है।
ट्रेविसग

1
@heishe यहाँ मेरी शेडर है: gist.github.com/2384073 । DistortPS 2 + 3 है।
जोनाथन डिकिंसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.