2010-06-28 26 views
6

समय के लिए कई कणों का निर्माण करना। इस बार यह पूरी तरह से एक तकनीकी डिजाइन दृष्टिकोण से है।एक्सएनए - एक ही समय में

मेरी स्थिति यह है: मैंने जीपीयू-गणनाओं के आधार पर एक कण इंजन बनाया है, जो कि पूर्ण से दूर है लेकिन यह काम करता है। मेरा जीपीयू आसानी से पसीना तोड़ने के बिना 10k कणों को संभालता है और अगर मैं एक गुच्छा अधिक जोड़ सकता हूं तो मुझे आश्चर्य नहीं होगा।

मेरी समस्या: जब भी मेरे पास एक ही समय में बनाए गए बहुत सारे कण होते हैं, तो मेरी फ्रेम दर मुझसे नफरत करती है। क्यूं कर? बहुत सी सीपीयू-उपयोग, भले ही मैंने इसे लगभग केवल मेमोरी ऑपरेशंस रखने के लिए कम किया है।

  • विधि कण बनाना चाहता है और एक कॉल करता है: कणों की

    निर्माण अभी भी इस तरह के रूप में सीपीयू कॉल द्वारा किया जाता है।

  • क्वाड कोने के रूप में बनाया गया है और एक बफर में संग्रहीत
  • बफर GPU में डाला जाता है और मेरे सीपीयू अन्य बातों के

जब मैं लगभग 4 emitters फ्रेम प्रति एक कण बनाने है, पर ध्यान केंद्रित कर सकते हैं है मेरी एफपीएस कम हो जाता है (निश्चित रूप से, प्रति सेकेंड केवल 4 फ्रेम लेकिन 15 उत्सर्जक मेरे एफपीएस को 25 तक छोड़ देते हैं)। एक कण के

निर्माण:

 //### As you can see, not a lot of action here. ### 
     ParticleVertex []tmpVertices = ParticleQuad.Vertices(Position,Velocity,this.TimeAlive); 
     particleVertices[i] = tmpVertices[0]; 
     particleVertices[i + 1] = tmpVertices[1]; 
     particleVertices[i + 2] = tmpVertices[2]; 
     particleVertices[i + 3] = tmpVertices[3]; 
     particleVertices[i + 4] = tmpVertices[4]; 
     particleVertices[i + 5] = tmpVertices[5]; 

     particleVertexBuffer.SetData(particleVertices); 

मेरे विचार कर रहे हैं कि शायद मैं कणों को अक्सर, शायद वहाँ GPU, सब कुछ बना सकते हैं का एक तरीका है कि नहीं बनाना चाहिए या हो सकता है मैं सिर्फ डॉन ' टी नहीं जानते कि आप इन चीजों को कैसे करते हैं। ;)

संपादित करें: अगर मैं अक्सर कण नहीं बना रहा था, तो यह अभी भी अच्छा दिखने के लिए कामकाज क्या है?

तो मैं उम्मीद में यहां पोस्ट कर रहा हूं कि आप जानते हैं कि एक अच्छा कण इंजन कैसे डिजाइन किया जाना चाहिए और यदि शायद मैंने गलत मार्ग लिया हो।

उत्तर

4

GPU को सबकुछ बनाने का कोई तरीका नहीं है (Geometry Shaders का उपयोग करने से कम, जिसके लिए SM4.0 की आवश्यकता है)।

अगर मैं अधिकतम सीपीयू दक्षता के लिए एक कण प्रणाली निर्माण कर रहे थे, मैं (सिर्फ उदाहरण के लिए एक नंबर लेने के लिए) एक शीर्ष और सूचकांक बफर में 100 कणों इस तरह पूर्व बनाना होगा:

  • क्वाड युक्त एक कशेरुक बफर बनाएं (प्रति कण के चार शिखर, आपके पास छः नहीं)
  • एक कस्टम वर्टेक्स प्रारूप का उपयोग करें जो "टाइम ऑफसेट" मान, साथ ही साथ "प्रारंभिक वेग" मान (जैसे प्रारंभिक वेग) को संग्रहीत कर सकता है XNA Particle 3D Sample)
  • समय मूल्य निर्धारित करें जैसे कि प्रत्येक भाग icle के पास पिछले एक की तुलना में 1/100 वें कम समय का ऑफसेट होता है (इसलिए बफर के माध्यम से ऑफ़सेट 1.0 से 0.01 तक है)।
  • प्रारंभिक वेग को यादृच्छिक रूप से सेट करें।
  • एक सूचकांक बफर का उपयोग करें जो आपको प्रत्येक कण के लिए चार शीर्षकों का उपयोग करके आपको आवश्यक दो त्रिभुज देता है।

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

  • प्रति वर्टेक्स:

    तो मैं एक शीर्ष शेडर कि निम्न इनपुट ले जाएगा के लिए होता है

    • समय ऑफसेट
    • प्रारंभिक वेग
  • छायांकर्ता पैरामीटर:
    • वर्तमान समय
    • कण जीवन (जो भी कण समय चादर के आसपास बना रहता है और बफर में कणों इस्तेमाल किया जा रहा के अंश)
    • कण प्रणाली स्थिति/रोटेशन/पैमाने (दुनिया मैट्रिक्स)
    • कण आकार, गुरुत्वाकर्षण, हवा, आदि
    • एक समय के पैमाने (एक वास्तविक समय प्राप्त करने के लिए है, इसलिए वेग और अन्य भौतिक विज्ञान गणना मतलब)
: इस तरह के रूप
  • किसी भी अन्य रोचक आदानों आप चाहें, तो

    वह वर्टेक्स शेडर (फिर XNA Particle 3D Sample की तरह) उसके प्रारंभिक वेग और उस कण के अनुकरण में उस समय के आधार पर कण के चरम की स्थिति निर्धारित कर सकता है।

    time = (currentTime + timeOffset) % particleLifetime; 
    

    दूसरे शब्दों में समय बढ़ने के साथ ही, कण (ऑफसेट के कारण) एक निरंतर दर पर जारी किया जाएगा,:

    प्रत्येक कण के लिए समय (छद्म कोड) होगा। और जब भी एक कण time = particleLifetimeपर मर जाता है (या यह 1.0 पर है? फ़्लोटिंग-पॉइंट मॉड्यूलस भ्रमित है), समय time = 0.0 पर वापस लूप करता है ताकि कण एनीमेशन में फिर से प्रवेश कर सके।

    फिर, जब मेरे कणों को आकर्षित करने का समय आया, तो मेरे पास मेरे बफर, शेडर और शेडर पैरामीटर सेट होंगे, और DrawIndexedPrimitives पर कॉल करें। अब चालाक बिट है: मैं startIndex और primitiveCount सेट करता हूं जैसे कोई कण मध्य-एनीमेशन से शुरू नहीं होता है। जब कण प्रणाली पहली बार शुरू होती है तो मैं 1 कण (2 प्राइमेटिव) खींचता हूं, और जब तक कण मरने वाला होता है, तब तक मैं सभी 100 कणों को चित्रित करता हूं, जिनमें से 100 वां शुरू हो जाएगा।

    फिर, एक पल बाद में, पहला कण का टाइमर चारों ओर लूप करेगा और इसे 101 वें कण बना देगा।

    (अगर मैं केवल अपने सिस्टम में 50 कणों चाहता था, मैं सिर्फ 0.5 करने के लिए अपने कण जीवन सेट करते हैं और केवल कभी शीर्ष/सूचकांक बफर में 100 कणों के पहले 50 आकर्षित।)

    और जब यह कण प्रणाली को बंद करने के लिए समय आया - बस विपरीत में ऐसा ही करें - startIndex और primitiveCount सेट करें ताकि कणों को मरने के बाद खींचा जा सके।

    अब मुझे यह स्वीकार करना होगा कि मैंने शामिल गणित पर चमक ली है और कणों के लिए quads का उपयोग करने के बारे में कुछ विवरण हैं - लेकिन इसे समझना बहुत कठिन नहीं होना चाहिए। समझने का मूल सिद्धांत यह है कि आप कणों के गोलाकार बफर के रूप में अपने कशेरुक/सूचकांक बफर का इलाज कर रहे हैं। एक परिपत्र बफर के

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

    इस विधि का एक और नकारात्मक पक्ष यह है कि कण निरंतर दर पर जारी किए जाने चाहिए - हालांकि यह आमतौर पर कण प्रणालियों के लिए काफी विशिष्ट होता है (जाहिर है यह प्रति-प्रणाली है और दर समायोज्य है)। एक विस्फोट प्रभाव (एक बार में जारी सभी कणों) को थोड़ा tweaking के साथ संभव होना चाहिए।

    यह सब कहा जा रहा है: यदि संभव हो, तो मौजूदा कण पुस्तकालय का उपयोग करके यह सार्थक हो सकता है।

  • संबंधित मुद्दे