IF स्टेटमेंट्स के साथ एक के बजाय दो शेड्स का उपयोग करना


9

मैं ES 2.0 को अपेक्षाकृत बड़े opengl ES 1.1 स्रोत को पोर्ट करने पर काम कर रहा हूं।

ओपनजीएल ईएस 2.0 (जिसका अर्थ है, सब कुछ शेड्स का उपयोग करता है) में, मैं तीन बार चायदानी खींचना चाहता हूं।

  1. एक समान रंग के साथ पहला (पुराने glColor4f अला)।

  2. दूसरा वाला, प्रति-शीर्ष रंग के साथ (चायदानी के रूप में अच्छी तरह से शीर्ष रंग की अपनी सरणी है)

  3. तीसरा, प्रति-पृष्ठ बनावट के साथ

  4. और शायद एक चौथाई, प्रति-पृष्ठ बनावट और रंग दोनों के साथ। और फिर शायद एक 5 वीं, साथ ही मानदंडों के साथ ..

मेरे पास कार्यान्वयन के साथ दो विकल्प हैं, जहां तक ​​मुझे पता है। पहला एक ऐसा शेडर बनाना है जो उपरोक्त सभी का समर्थन करता है, एक समान के साथ जो व्यवहार को बदलने के लिए निर्धारित है (जैसे एकवचन रंग वर्दी का उपयोग करें, या प्रति-शीर्ष रंग वर्दी)।

दूसरी पसंद प्रत्येक स्थिति के लिए एक अलग शेडर बनाना है। कुछ कस्टम shader प्रीप्रोसेसिंग के साथ, ऐसा करने के लिए जटिल नहीं है, लेकिन ड्राइंग ऑब्जेक्ट्स के बीच शेडर्स को स्विच करने में चिंता का प्रदर्शन लागत है। मैंने पढ़ा है कि यह मामूली रूप से छोटा नहीं है।

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

जवाबों:


10

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

ब्रांचिंग के साथ सबसे खराब स्थिति कुछ इस तरह होगी:

  • शाखा के दोनों किनारों का मूल्यांकन किया जाता है।
  • एक "मिक्स" या "स्टेप" निर्देश shader संकलक द्वारा उत्पन्न किया जाएगा और आपके कोड में यह तय करने के लिए डाला जाएगा कि किस पक्ष का उपयोग करना है।

और ये सभी अतिरिक्त निर्देश आपके द्वारा खींचे गए प्रत्येक शीर्ष या टुकड़े के लिए चलाए जाएंगे। संभावित रूप से लाखों अतिरिक्त निर्देशों को एक शैडर परिवर्तन की लागत के खिलाफ तौला जाना चाहिए।

Apple के " iOS के लिए OpenGL ES प्रोग्रामिंग गाइड " (जिसे आपके लक्षित हार्डवेयर के प्रतिनिधि के रूप में लिया जा सकता है) के पास ब्रांचिंग के बारे में यह कहना है:

ब्रांचिंग से बचें

शाखाओं को रंगों में हतोत्साहित किया जाता है, क्योंकि वे 3D ग्राफिक्स प्रोसेसर पर समानांतर में संचालन को निष्पादित करने की क्षमता को कम कर सकते हैं। यदि आपके शेड्स शाखाओं का उपयोग करते हैं, तो इन सिफारिशों का पालन करें:

  • सर्वश्रेष्ठ प्रदर्शन: शाल्डर संकलित होने पर एक निरंतर ज्ञात शाखा।
  • स्वीकार्य: एक समान चर पर शाखा।
  • संभावित रूप से धीमा: शेडर के अंदर गणना किए गए मूल्य पर शाखा।

कई knobs और levers के साथ एक बड़ा shader बनाने के बजाय, विशिष्ट रेंडरिंग कार्यों के लिए विशेष छोटे shaders बनाएं। आपके शेड्स में शाखाओं की संख्या कम करने और आपके द्वारा बनाए गए शेडर्स की संख्या बढ़ाने के बीच एक ट्रेडऑफ़ है। विभिन्न विकल्पों का परीक्षण करें और सबसे तेज़ समाधान चुनें।

यहां तक ​​कि अगर आप व्यंग्य कर रहे हैं कि आप "स्वीकार्य" स्लॉट में हैं, तब भी आपको यह विचार करने की आवश्यकता है कि 4 या 5 मामलों के बीच चयन करने के लिए, आप अपने शेड्स में निर्देश गणना बढ़ा रहे हैं। आपको अपने लक्ष्य हार्डवेयर पर निर्देश गणना सीमा के बारे में पता होना चाहिए और यह सुनिश्चित करना चाहिए कि आप उनके ऊपर न जाएं, ऊपर दिए गए Apple लिंक से फिर से उद्धृत करें:

ओपनजीएल ईएस कार्यान्वयन के लिए एक सॉफ्टवेयर फॉलबैक लागू करने की आवश्यकता नहीं होती है जब ये सीमाएं पार हो जाती हैं; इसके बजाय, shader बस संकलन या लिंक करने में विफल रहता है।

यह कहने के लिए कोई भी नहीं है कि ब्रांचिंग आपकी जरूरत का सबसे अच्छा समाधान नहीं है। आपने इस तथ्य की सही पहचान की है कि आपको दोनों दृष्टिकोणों की रूपरेखा तैयार करनी चाहिए, ताकि अंतिम सिफारिश हो। लेकिन बस इस बात से अवगत रहें कि जैसे-जैसे शेड अधिक जटिल होते जाते हैं, ब्रांचिंग आधारित घोल कुछ शैडर परिवर्तनों की तुलना में बहुत अधिक ओवरहेड दे सकता है।


3

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

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

इसके अतिरिक्त, इसे पूरा करने के लिए कुछ अन्य तरीके हैं: "उबेर-शेड्स" और ओपनगार्ड शेडर प्रोग्राम्स जिस तरह से जुड़े हुए हैं, उसके साथ थोड़ा सा प्रवंचना।

"उबेर-शेड्स" अनिवार्य रूप से पहली पसंद हैं, माइनस द ब्रांचिंग, लेकिन आपके पास कई शेड होंगे। उपयोग करने के बजाय if- बयान, आप पूर्वप्रक्रमक का उपयोग #define, #ifdef, #else, #endif, और उचित सहित विभिन्न संस्करणों, संकलन #defineआपको क्या चाहिए के लिए है।

vec4 color;
#ifdef PER_VERTEX_COLOR
color = in_color;
#else
color = obj_color;
#endif

आप shader को अलग-अलग कार्यों में भी तोड़ सकते हैं। एक शेडर है जो सभी कार्यों के लिए प्रोटोटाइप को परिभाषित करता है और उन्हें कॉल करता है, अतिरिक्त शेड्स का एक गुच्छा लिंक करता है जिसमें उचित कार्यान्वयन शामिल हैं। मैंने शैडो मैपिंग के लिए इस ट्रिक का उपयोग किया है, यह आसान बनाने के लिए कि सभी शेड्स को संशोधित किए बिना सभी ऑब्जेक्ट्स पर फ़िल्टरिंग कैसे की जाती है।

//ins, outs, uniforms

float getShadowCoefficient();

void main()
{
    //shading stuff goes here

    gl_FragColor = color * getShadowCoefficient();
}

फिर, मेरे पास कई अन्य shader फाइलें हो सकती हैं जो परिभाषित करती हैं getShadowCoefficient(), आवश्यक वर्दी, और कुछ नहीं। उदाहरण के लिए, shadow_none.glslइसमें शामिल हैं:

float getShadowCoefficient()
{
    return 1;
}

और shadow_simple.glslइसमें (मेरे shader से सरल है जो CSM को लागू करता है):

in vec4 eye_position;

uniform sampler2DShadow shad_tex;
uniform mat4 shad_mat;

float getShadowCoefficient()
{
    vec4 shad_coord = shad_mat * eye_position;
    return texture(shad_tex, shad_coord).x;
}

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

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