कैसे टुकड़ा shader एक पिक्सेल के रंग के लिए उपयोग करने के लिए चर पता है?


83

मुझे बहुत सारे अलग-अलग टुकड़े दिखाई देते हैं,

और वे सभी "आउट रंग" (इस मामले में flatColor) के लिए एक अलग चर का उपयोग करते हैं । तो कैसे OpenGL जानता है कि आप क्या करने की कोशिश कर रहे हैं?

मैं इस काम का अनुमान लगा रहा हूं क्योंकि flatColorएकमात्र वैरिएबल के रूप में परिभाषित किया गया है out, लेकिन आपको अधिक outचर जोड़ने की अनुमति है क्या आप नहीं हैं? या कि बस दुर्घटना होगी?


वास्तव में, एक परीक्षण के रूप में, मैंने इसे चलाया:

यह ठीक काम करता है कि मैं उपयोग करता हूं xया y


इसके अलावा, हमारे पास पूर्वनिर्धारित है gl_FragColor। क्या अंतर है, और लोग आमतौर पर अपने स्वयं के चर का उपयोग करने पर जोर क्यों देते हैं?

जवाबों:


143

इसके अलावा, हमारे पास एक पूर्वनिर्धारित gl_FragColor है।

इससे शुरुआत करते हैं। नहीं, आपके पास पूर्वनिर्धारित नहीं है gl_FragColor। कि कोर OpenGL 3.1 और ऊपर से हटा दिया गया था। जब तक आप संगतता का उपयोग नहीं कर रहे हैं (किस स्थिति में, आपके 3.30 शेडर्स को #version 330 compatibilityशीर्ष पर कहना चाहिए ), आपको इसका उपयोग कभी नहीं करना चाहिए।

अब, उपयोगकर्ता-परिभाषित टुकड़ा shader आउटपुट पर वापस। लेकिन पहले, एक त्वरित सादृश्य।

याद रखें कि कैसे, शीर्ष क्रम में, आपके पास इनपुट हैं? और ये इनपुट वर्टेक्स विशेषता सूचकांकों का प्रतिनिधित्व करते हैं, जिन संख्याओं को आप पास करते हैं glVertexAttribPointerऔर glEnableVertexAttribArrayआगे? आप सेट करते हैं कि कौन सा इनपुट किस विशेषता से खींचता है। GLSL 3.30 में, आप इस सिंटैक्स का उपयोग करते हैं:

यह colorविशेषता स्थान 2 से आने के लिए शीर्ष shader इनपुट सेट करता है । 3.30 से पहले (या ARB_explicit_attrib_location के बिना), आपको glBindAttrbLocationविशेषता सूचकांक के लिए प्रोग्राम को लिंक करने या क्वेरी करने से पहले इसे या तो स्पष्ट रूप से सेट करना होगा glGetAttribLocation। यदि आप स्पष्ट रूप से एक विशेषता स्थान प्रदान नहीं करते हैं, तो GLSL एक स्थान को मनमाने ढंग से निर्दिष्ट करेगा (यानी: कार्यान्वयन-परिभाषित तरीके से)।

इसे shader में सेट करना लगभग हमेशा बेहतर विकल्प होता है।

किसी भी मामले में, टुकड़ा shader outputs लगभग उसी तरह काम करते हैं। फ्रेग्मेंट शेड्स कई आउटपुट रंगों को लिख सकते हैं , जो स्वयं मैप किए जाते हैं फ्रेमबफ़र में कई बफ़र्स के । इसलिए, आपको यह इंगित करने की आवश्यकता है कि कौन सा आउटपुट किस टुकड़े में जाता है आउटपुट रंग।

यह प्रक्रिया खंड आउटपुट स्थान मान से शुरू होती है। यह बहुत समान रूप से शेल्टर इनपुट स्थानों पर सेट है:

वहाँ भी एपीआई कार्य कर रहे हैं glBindFragDataLocationऔर glGetFragDataLocation, जो अनुरूप हैं glBindAttribLocationऔरglGetAttribLocation

यदि आप कोई स्पष्ट कार्य नहीं करते हैं, तो कार्यान्वयन आमतौर पर आपके आउटपुट चर में से एक को स्थान 0 पर निर्दिष्ट करेगा। हालांकि, OpenGL प्रक्रिया नहीं करती है इस व्यवहार की आवश्यकता है , इसलिए आपको इस पर निर्भर नहीं होना चाहिए।

अब निष्पक्ष होने के लिए, आपके प्रोग्राम को लिंक करने में विफल होना चाहिए जब आपने दो आउटपुट का उपयोग किया था जो अलग-अलग आउटपुट स्थान नहीं मिला। संभवतः ऐसा क्या हुआ था कि आपके कंपाइलर ने आपके द्वारा लिखे गए को अनुकूलित नहीं किया था, इसलिए जब यह लिंकर त्रुटियों की जांच करने का समय आया तो वह इसके बारे में भूल गया।


4
काश मैं +1 से ज्यादा दे पाता। शानदार जवाब। मैं सोच रहा था कि टुकड़े के उत्पादन के स्थानों ने कैसे काम किया। :)
केविंटोडिस्को

आह .. तो उन्होंने gl_FragColorआपको और अधिक लचीलापन देने के पक्ष में पदावनत किया कि किस बफर को लिखना है? समझ में आता है। एक बार फिर धन्यवाद!
एमपीएन

3
@ मर्क: "डिप्रेसेशन" का अर्थ है "आप अभी भी इसका उपयोग कर सकते हैं, लेकिन इसे बाद के संस्करणों में हटाया जा सकता है।" "निकाला गया" का अर्थ है निकाला हुआ । इसमे अंतर है। जो जीएल 3.0 में पदावनत चिह्नित किया गया था उसे 3.1 में हटा दिया गया था (कुछ चीजों के लिए बचाओ)।
निकोल बोलस

3
@ निचलोल: "जीएल 3.3 और इसके बाद के संस्करण (यह पूर्व संस्करणों से एक बदलाव है) उन सभी को 0 स्थान पर असाइन करेगा"। मुझे आश्चर्य है कि यह कल्पना की गारंटी कहां है। 3.3 कहता है, "जब कोई प्रोग्राम लिंक किया जाता है, तो बाइंडिंग निर्दिष्ट किए बिना कोई भी भिन्न चर [...] या स्पष्ट रूप से शेडर टेक्स्ट के भीतर सेट किया जाता है, जीएल द्वारा स्वचालित रूप से विखंडन रंगों और सूचकांकों के लिए बाध्य होगा। ऐसे सभी असाइनमेंट रंग सूचकांकों का उपयोग करेंगे। शून्य। "। अंतिम वाक्य 3.2 में मौजूद नहीं है। हालांकि, सूचकांक रंग संख्या का उल्लेख नहीं करता है, लेकिन केवल दोहरे स्रोत सम्मिश्रण सूचकांक (जिसे 3.3 में जोड़ा गया था) के लिए।
derhass

1
धन्यवाद @NicolBolas, बढ़िया जवाब! इसलिए मैंने अभी तक इसे पूरी तरह से नहीं समझा है, और इसे "बिना प्रश्न के" बनाना चाहता हूं। हमारे शेड्स में, हम हमेशा यह निर्दिष्ट layout (location = 0) out vec4 outColorकरते हैं कि जो कुछ भी है, उसके लिए ड्राइंग (ज्यादातर "स्क्रीन" और एफबीओ नहीं है)। डिफ़ॉल्ट के रूप में, अगर हमने glDrawBuffers का उपयोग करके FBO (या अन्य बफर) को बाध्य नहीं किया है, और हम निर्दिष्ट करते हैं location = 0, तो यह हमेशा स्क्रीन पर सही ढंग से आकर्षित होगा?
अज़प

9

मैं इसे OpenGLES 3.1 के लिए निर्दिष्ट करना चाहता हूं जो GLSL_ES_3.10 लिंक का उपयोग करता है :

§4.4.2

यदि केवल एक ही आउटपुट [टुकड़े टुकड़े करने वाले में] है, तो उस स्थान को निर्दिष्ट करने की आवश्यकता नहीं है, जिस स्थिति में यह शून्य से चूकता है।

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