2012-10-25 23 views
5

में कंकाल एनीमेशन के लिए कोष्ठक अनुकूलित करना तो मैं 2 डी कंकाल एनीमेशन सिस्टम के साथ काम कर रहा हूं।OpenGL ES

हड्डियों की एक्स संख्या है, प्रत्येक हड्डी में कम से कम 1 भाग (एक ट्रैक्टर, दो त्रिकोण) होता है। औसतन, मेरे पास 20 हड्डियां और 30 भाग हो सकते हैं। अधिकांश हड्डियां माता-पिता पर निर्भर करती हैं, हड्डियां हर फ्रेम को स्थानांतरित करती हैं। कुल प्रति एनीमेशन में 1000 फ्रेम तक हैं, और मैं लगभग 50 एनिमेशन का उपयोग कर रहा हूं। किसी भी समय स्मृति में लगभग 50,000 फ्रेम लोड हो गए। कंकाल के उदाहरणों के बीच भागों अलग-अलग हैं।

[x1,y1,u1,v1],[x2,y2,u2,v2],[x3,y3,u3,v3],[x4,y4,u4,v4] 

और glDrawElements प्रत्येक के लिए के माध्यम से इस पारित:

पहले दृष्टिकोण मैं ले लिया प्रत्येक हड्डी की स्थिति/रोटेशन की गणना, और, एक शीर्ष सरणी है, जो इस में शामिल का निर्माण प्रत्येक भाग के लिए किया गया था फ्रेम।

जो ठीक दिखता है, मुझे आवश्यक सभी परिदृश्यों को शामिल करता है, बहुत मेमोरी का उपयोग नहीं करता है, लेकिन कुत्ते की तरह प्रदर्शन करता है। आईपॉड 4 पर, इन 10 कंकालों में से 10 के साथ शायद 15fps मिल सकता है।

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

कोने, इस तरह देखा फ्रेम प्रति

[--------------------- Frame 1 ---------------------],[------- Frame 2 ------] 
[x1,y1,u1,v1,boneIndex],[x2, ...],[x3, ...],[x4, ...],[x1, ...][x2, ...][....] 

शिखर शेडर इस तरह दिखता है:

attribute vec4 a_position; 
attribute vec4 a_nextPosition; 
attribute vec2 a_texCoords; 
attribute float a_boneIndex; 

uniform mat4 u_projectionViewMatrix; 
uniform float u_boneAlpha[255]; 

varying vec2 v_texCoords; 

void main() { 
    float alpha = u_boneAlpha[int(a_boneIndex)]; 
    vec4 position = mix(a_position, a_nextPosition, alpha); 
    gl_Position = u_projectionViewMatrix * position; 
    v_texCoords = a_texCoords; 
} 

अब, प्रदर्शन स्क्रीन पर इनमें से 10 के साथ, बहुत अच्छा है, इस पर आराम से बैठता है 50fps। लेकिन अब, यह एक मीट्रिक टन स्मृति का उपयोग करता है। मैंने अनुकूलित किया है कि xyuv पर कुछ सटीकता खोकर, जो अब ushorts हैं।

समस्या भी है कि हड्डी-निर्भरता खो जाती है। यदि दो हड्डियां हैं, माता-पिता और बच्चे हैं, और बच्चे के पास 0 और 2s पर एक कीफ्रेम है, तो माता-पिता के पास 0s, 0.5s, 1.5s, 2s पर एक कीफ्रेम है, तो बच्चा 0.5 के बीच नहीं बदला जाएगा और 1.5 के रूप में यह चाहिए।

मैं इस हड्डी की समस्या को ठीक करने के लिए एक समाधान के साथ आया - बच्चे को माता-पिता के समान बिंदुओं पर कीफ्रेम रखने के लिए मजबूर कर रहा था। लेकिन यह और भी स्मृति का उपयोग करता है, और मूल रूप से हड्डी पदानुक्रम के बिंदु को मारता है।

यह वह जगह है जहां मैं अभी हूं। मैं प्रदर्शन और स्मृति उपयोग के बीच संतुलन खोजने की कोशिश कर रहा हूं। मुझे पता है कि यहां बहुत सारी अनावश्यक जानकारी है (यूवी निर्देशांक किसी विशेष भाग के सभी फ्रेम के लिए समान हैं, इसलिए ~ 30 बार दोहराया जाता है)। और प्रत्येक नए हिस्सों के लिए एक नया बफर बनाया जाना चाहिए (जिसमें अद्वितीय XYUV समन्वय होते हैं - स्थिति बदलती है क्योंकि विभिन्न हिस्सों अलग-अलग आकार होते हैं)

अभी मैं प्रति चरित्र एक वर्टेक्स सरणी सेट करने का प्रयास करने जा रहा हूं, जिसमें सभी भागों के लिए xyuv है, और प्रत्येक भागों के लिए matrices की गणना, और shader में उन्हें repositioning। मुझे पता है कि यह काम करेगा, लेकिन मुझे चिंता है कि प्रदर्शन शुरू होने पर प्रत्येक फ्रेम के लिए XYUV को अपलोड करने से बेहतर नहीं होगा।

क्या मेरे द्वारा प्राप्त किए गए प्रदर्शन को खोए बिना ऐसा करने का कोई बेहतर तरीका है?

किसी भी जंगली विचारों मैं कोशिश कर सकते वहाँ हैं?

+0

अच्छा सवाल सर – Weacked

+0

क्या सभी हड्डियों को हर फ्रेम "अपने आप पर ले जाएं" या कई हड्डियों को बस ले जाया गया क्योंकि माता-पिता चले गए? – Dirk

+0

सभी हड्डियों में से एक माता-पिता के साथ चलता है। वहाँ कुछ हड्डियों लगभग माता-पिता से स्वतंत्र कुछ नहीं कर रहे हैं, और फिर वहाँ कुछ है जो कई बार ले जाने से माता पिता ले जाया जाता है कर रहे हैं। –

उत्तर

1

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

जेसन एल McKesson के नि: शुल्क पुस्तक, Learning Modern 3D Graphics Programming, कैसे इस अध्याय के अंत में उदाहरण कार्यक्रम अध्याय 6. में यह पूरा करने पर एक अच्छा विवरण देता है दिखाता है कि कैसे एक पदानुक्रमित मॉडल लागू करने के लिए एक मैट्रिक्स ढेर उपयोग करने के लिए। I have an OpenGL ES 2.0 on iOS port of this program available

+0

दुर्भाग्य से, कि वास्तव में कैसे अपने मूल संस्करण में काम किया है। और यह वर्तमान कार्यान्वयन के रूप में लगभग कहीं भी प्रदर्शन किया। मुझे यह पता था कि इस तरह से यह एक बड़ी मात्रा में स्मृति का उपयोग करेगा, और हमारे लोडिंग समय को बढ़ाएगा, लेकिन स्क्रीन पर कई पात्रों के साथ यह कम से कम 50% तेज है। लेकिन, सुझावों के लिए धन्यवाद, वोट दिया। –

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