एए के साथ लाइनों को प्रस्तुत करने का सबसे तेज़ तरीका, डायरेक्टएक्स में मोटाई बदलती है


14

तो मैं कुछ DirectX विकास कर रहा हूँ, शार्पएक्स का उपयोग कर .NET के तहत सटीक (लेकिन DirectX / C ++ API समाधान लागू होते हैं)। मैं डायरेक्टएक्स का उपयोग करके एक ऑर्थोगोनल प्रोजेक्शन (जैसे वैज्ञानिक ऐप के लिए 2 डी लाइन ड्राइंग का अनुकरण करना) में लाइनों को प्रस्तुत करने का सबसे तेज़ तरीका ढूंढ रहा हूं।

मेरे द्वारा रेंडर किए गए प्लॉटों के प्रकार का एक स्क्रीनशॉट इस प्रकार है: यहाँ छवि विवरण दर्ज करें

इन प्रकार के भूखंडों के लिए यह असामान्य नहीं है कि लाखों सेगमेंट वाली लाइनें, वैरिएबल की मोटाई, प्रति-एंटीलिअसिंग प्रति-लाइन (या फुल स्क्रीन AA ऑन / ऑफ) के बिना हों। मुझे बहुत बार (जैसे 20 गुना / सेकंड) लाइनों के लिए कोने को अपडेट करने की आवश्यकता है और जितना संभव हो उतना GPU को ऑफलोड करना चाहिए।

अब तक मैंने कोशिश की है:

  1. सॉफ्टवेयर रेंडरिंग, उदाहरण के लिए GDI + वास्तव में खराब प्रदर्शन नहीं है, लेकिन स्पष्ट रूप से सीपीयू पर भारी है
  2. डायरेक्ट 2 डी एपीआई - जीडीआई की तुलना में धीमी, विशेष रूप से एंटीएलियासिंग पर
  3. Direct3D10 इस विधि का उपयोग करते हुए सीपीयू साइड पर वर्टेकल रंगों और टेसलेशन का उपयोग करके एए का अनुकरण करता है। धीमी गति से (मैंने इसे प्रोफाइल किया और 80% समय कंप्यूटिंग शीर्ष पदों पर बिताया है)

3 विधि के लिए मैं GPU के लिए एक त्रिकोण पट्टी भेजने के लिए वर्टेक्स बफ़र्स का उपयोग कर रहा हूं और हर 200ms को नए सिरे से अपडेट कर रहा हूं। मुझे 100,000 लाइन खंडों के लिए लगभग 5FPS की ताज़ा दर मिल रही है। मुझे लाखों आदर्श चाहिए!

अब मैं सोच रहा हूँ कि सबसे तेज़ तरीका GPU पर tessellation करना होगा, जैसे कि Geometry Shader में। मैं एक पंक्ति-सूची या बनावट में पैक के रूप में कोने भेज सकता हूं और क्वैड बनाने के लिए एक ज्यामिति शेडर में अनपैक कर सकता हूं। या, बस एक पिक्सेल shader में कच्चे अंक भेजें और Bresenham रेखा रेखा को पूरी तरह से पिक्सेल shader में लागू करें। मेरा एचएलएसएल 2006 से जंग खा रहा है, मॉडल 2 है तो मुझे पागल सामान के बारे में पता नहीं है जो आधुनिक जीपीयू कर सकता है।

तो सवाल यह है: - क्या किसी ने पहले भी ऐसा किया है, और क्या आपके पास कोशिश करने के लिए कोई सुझाव है? - क्या आपके पास तेजी से अपडेट होने वाली ज्योमेट्री (उदाहरण के लिए हर 20ms की नई सूची) के साथ प्रदर्शन को बेहतर बनाने के लिए कोई सुझाव है?

अद्यतन 21 जनवरी

मैंने लाइनस्ट्रिप और डायनेमिक वर्टेक्स बफ़र्स का उपयोग करके ज्यामिति शेड्स का उपयोग करके उपरोक्त विधि (3) को लागू किया है। अब मुझे 100k पॉइंट्स पर 100FPS और 1,000,000 पॉइंट्स पर 10FPS मिल रहे हैं। यह एक बहुत बड़ा सुधार है, लेकिन अब मैं फिल-दर और गणना सीमित कर रहा हूं, इसलिए मुझे अन्य तकनीकों / विचारों के बारे में सोचना पड़ा।

  • एक लाइन सेगमेंट ज्यामिति के हार्डवेयर इंस्टेंसिंग के बारे में क्या?
  • स्प्राइट बैच के बारे में क्या?
  • अन्य (पिक्सेल shader) उन्मुख तरीकों के बारे में क्या?
  • क्या मैं कुशलता से GPU या CPU पर कॉल कर सकता हूं?

आपकी टिप्पणियों और सुझावों की बहुत सराहना की!


1
Direct3D में देशी AA के बारे में क्या?
एपीआई-बीस्ट

5
क्या आप कुछ ऐसे उदाहरणों को दर्शा सकते हैं जो आप प्लॉट करना चाहते हैं? आप एक लाख चक्कर का उल्लेख करते हैं, लेकिन आपकी स्क्रीन में संभवतः एक मिलियन पिक्सेल से अधिक नहीं है , क्या उस मात्रा की वास्तव में आवश्यकता है? यह मुझे लगता है कि आपको हर जगह पूर्ण डेटा घनत्व की आवश्यकता नहीं होगी। क्या आपने एलओडी पर विचार किया है?
सैम होसेवर

1
आपके द्वारा जोड़ा गया दूसरा दृष्टिकोण अच्छा लगता है, क्या आप एक गतिशील वर्टेक्स बफर का उपयोग कर रहे हैं जिसे आप अपडेट करते हैं, या आप हर बार एक नया बनाते हैं?

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

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

जवाबों:


16

यदि आप Y = f(X)केवल ग्राफ़ प्रस्तुत करने जा रहे हैं , तो मेरा सुझाव है कि निम्नलिखित विधि का प्रयास करें।

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

एक-घटक बनावट सामग्री इस तरह दिख सकती है:

+----+----+----+----+
| 12 | 10 |  5 | .. | values for curve #1
+----+----+----+----+
| 55 | 83 | 87 | .. | values for curve #2
+----+----+----+----+

पिक्सेल शेडर का काम निम्नानुसार है:

  • डेटासेट स्थान में वर्तमान खंड के X समन्वय का पता लगाएं
  • उदाहरण के लिए 4 निकटतम डेटा बिंदु जिनके पास डेटा है; उदाहरण के लिए यदि एक्स मूल्य है 41.3यह चुनते हैं 40, 41, 42और 43
  • 4 Y मूल्यों के लिए बनावट को क्वेरी करें (सुनिश्चित करें कि नमूना किसी भी प्रकार का कोई प्रक्षेप नहीं करता है)
  • कन्वर्ट X,Yस्क्रीन स्थान को जोड़े
  • तीन खंडों और चार बिंदुओं में से प्रत्येक के लिए वर्तमान टुकड़े से दूरी की गणना करें
  • वर्तमान टुकड़े के लिए एक अल्फा मान के रूप में दूरी का उपयोग करें

आप संभावित ज़ूम स्तर के आधार पर बड़े मूल्यों के साथ 4 स्थानापन्न करना चाह सकते हैं।

मैंने इस सुविधा को लागू करने के लिए एक बहुत ही त्वरित और गंदा GLSL शेडर लिखा है । मैं बाद में HLSL संस्करण जोड़ सकता हूं, लेकिन आपको इसे बहुत अधिक प्रयास के बिना परिवर्तित करने में सक्षम होना चाहिए। परिणाम नीचे देखा जा सकता है, विभिन्न लाइन आकार और डेटा घनत्व के साथ:

घटता

एक स्पष्ट लाभ यह है कि हस्तांतरित डेटा की मात्रा बहुत कम है, और ड्रॉक्ल्स की संख्या केवल एक है।


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

@ Dr.ABT डेटासेट का आकार केवल अधिकतम बनावट आकार तक सीमित है। मुझे नहीं लगता कि लाखों अंक कुछ उचित डेटा लेआउट क्यों नहीं देंगे। ध्यान दें कि मेरा कोड निश्चित रूप से उत्पादन की गुणवत्ता नहीं है, लेकिन अगर कोई समस्या हो तो मुझे निजी तौर पर संपर्क करने में संकोच न करें।
सैम होसेवर

चीयर्स @ समोसेश्वर - मैं इसे जाने दूँगा। यह एक समय हो गया है क्योंकि मैंने एक ओपनजीएल उदाहरण दिमाग संकलित किया है! :-)
डॉ। एबीटी

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

4

एंटीएलियास लाइनों को प्रस्तुत करने पर एक GPU रत्न अध्याय था: फास्ट प्रीफिल्ड लाइन्स । मूल विचार प्रत्येक रेखा खंड को एक क्वाड के रूप में प्रस्तुत करना और प्रत्येक पिक्सेल पर गणना करना है, लाइन सेगमेंट से पिक्सेल केंद्र की दूरी का एक गॉसियन फ़ंक्शन।

इसका मतलब है कि ग्राफ में प्रत्येक लाइन खंड को एक अलग क्वाड के रूप में आरेखित किया गया है, लेकिन डी 3 डी 11 में आप निश्चित रूप से एक ज्यामिति शेडर और / या क्वैड उत्पन्न करने के लिए उपयोग कर सकते हैं, डेटा को केवल डेटा बिंदुओं पर GPU में स्थानांतरित करने के लिए कम कर सकते हैं। खुद को। मैं शायद डेटा पॉइंट्स को एक स्ट्रक्चर्डबफ़र के रूप में सेट करूँगा, जिसे वर्टेक्स / ज्योमेट्री शेडर द्वारा पढ़ा जा सकता है, फिर ड्रा कॉल को निर्दिष्ट करने के लिए सेगमेंट की संख्या निर्दिष्ट करें। कोई वास्तविक शीर्ष बफ़र नहीं होगा; वर्टेक्स शेडर सिर्फ SV_VertexID या SV_InstanceID का उपयोग करके यह निर्धारित करेगा कि कौन से डेटा बिंदुओं को देखना है।


हे धन्यवाद - हाँ, मैं उस लेख से अवगत हूं, दुर्भाग्य से इसके साथ कोई स्रोत कोड नहीं है :-( GeoShader + FragShader का आधार इस प्रकार के काम के लिए एक विजेता प्रतीत होता है। GPU को डेटा प्राप्त करना कुशलतापूर्वक होने वाला है। मुश्किल हिस्सा!
डॉ। एबीटी

अरे @NathanReed इस पर वापस जा रहा है - अगर मैंने ज्यामिति Shader का इस्तेमाल किया या quads खींचने के लिए उकसाया, तो Point1 / Point2 एक क्वाड के विपरीत कोने हैं, Pixel Shader में मैं Pt1 और Pt2 के बीच की लाइन की दूरी की गणना कैसे कर सकता हूं? क्या पिक्सेल shader को इनपुट ज्यामिति का ज्ञान है?
डॉ। एबीटी

@ Dr.ABT गणितीय रेखा के मापदंडों को प्रक्षेपक के माध्यम से पिक्सेल shader में भेजा जाना है। पिक्सेल शेडर की ज्यामिति तक कोई सीधी पहुंच नहीं है।
नाथन रीड

मैं देख रहा हूँ, क्या यह ज्यामिति या आउटपुट से आउटपुट भेजकर किया जा सकता है? अतिरिक्त क्रेडिट के लिए (यदि आप रुचि रखते हैं), तो मैंने यहां एक क्यू जोड़ा: gamedev.stackexchange.com/questions/47831/…
डॉ। एबीटी

@ Dr.ABT यह ठीक उसी तरह है कि बनावट समन्वय करती है, सामान्य वैक्टर, और उस तरह के सभी सामान सामान्य रूप से पिक्सेल shader में भेजे जाते हैं - वर्टेक्स / ज्यामिति shader से आउटपुट लिखकर जो कि प्रक्षेपित होते हैं और पिक्सेल shader में इनपुट होते हैं।
नाथन रीड

0

@ Dr.ABT - इसके लिए माफी एक सवाल है, जवाब नहीं। मुझे सैम हूसेवर द्वारा उपरोक्त उत्तर के भीतर यह पूछने का कोई तरीका नहीं मिला।

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


जैसा कि आप जानते हैं कि इसका उत्तर नहीं है कृपया संपादित करें और इसे एक टिप्पणी के रूप में डालें
MephistonX

मैं ऐसा करने की कोशिश कर रहा था, लेकिन मूल पोस्ट पर "टिप्पणी जोड़ें" बटन नहीं है।
ErcGeek

हाय ErcGeek, क्षमा करें, मैं अंतिम समाधान साझा करने में असमर्थ हूं क्योंकि यह जानकारी मेरी कंपनी के लिए स्वामित्व है। यद्यपि ऊपर दिए गए उदाहरण और सुझाव हमें सही रास्ते पर लाते हैं। शुभकामनाएं!
डॉ। एबीटी

प्रतिष्ठा की एक निश्चित राशि तक पहुँचने से पहले आप टिप्पणी पोस्ट नहीं कर सकते। और ये सभी डाउनवोट सुनिश्चित करते हैं कि आप उस अवसर को प्रदान नहीं करेंगे।
मैथियास लिकेगार्ड लोरेंजेन

अंतिम परिणाम को जानने और उसके लिए उपलब्ध एकमात्र तरीके से पूछने के लिए लड़के को दंडित नहीं किया जाना चाहिए। जवाब दिया।
डेविड चिंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.