OpenGL में मल्टीपर्स शेड कैसे काम करते हैं?


13

Direct3D में, मल्टीपेस शेड्स का उपयोग करना सरल है क्योंकि आप सचमुच एक प्रोग्राम के भीतर पास को परिभाषित कर सकते हैं। ओपनजीएल में, यह थोड़ा और अधिक जटिल लगता है क्योंकि शेडर प्रोग्राम को कई वर्टेक्स, जियोमेट्री, और फ्रेगमेंट शेयर्स देना संभव है जैसा आप चाहते हैं।

मल्टीपास शेडर का एक लोकप्रिय उदाहरण एक टॉन शेडर है। एक पास वास्तविक सीएल-छायांकन प्रभाव करता है और दूसरा रूपरेखा बनाता है। अगर मेरे पास दो शीर्ष शैलें हैं, "cel.vert" और "outline.vert", और दो टुकड़ा shaders, "cel.frag" और "outline.frag" (इसी तरह से आप HLSL में करते हैं), मैं कैसे कर सकता हूँ उन्हें पूरा टॉन shader बनाने के लिए गठबंधन?

मैं आपको यह नहीं कहना चाहता हूं कि इसके लिए एक ज्यामिति शेडर का उपयोग किया जा सकता है क्योंकि मैं सिर्फ मल्टीप्लेयर GLSL जेंडर के पीछे के सिद्धांत को जानना चाहता हूं;)


"Direct3D में, मल्टीपेस शेड्स का उपयोग करना सरल है क्योंकि आप सचमुच एक प्रोग्राम के भीतर पास को परिभाषित कर सकते हैं।" नहीं, तुम नहीं कर सकते। आप एफएक्स फ़ाइल में पास को परिभाषित कर सकते हैं, लेकिन यह एचएलएसएल शेडर के समान नहीं है।
निकोल बोलस

जवाबों:


11

मल्टीपास के पीछे कोई "सिद्धांत" नहीं है। कोई "मल्टीपर्स शेड्स" नहीं हैं। मल्टीपास बहुत सरल है: आप ऑब्जेक्ट को एक प्रोग्राम के साथ आकर्षित करते हैं। फिर आप ऑब्जेक्ट को एक अलग प्रोग्राम के साथ ड्रा करते हैं ।

इन अतिरिक्त पासों को छिपाने के लिए आप एफएक्स फाइलों की तरह डी 3 डीएक्स सामान का उपयोग कर सकते हैं। लेकिन वे अभी भी उस तरह से काम करते हैं। OpenGL के पास बस इसके लिए कोई जगह नहीं है।


1

सेल शेडर के साथ ऑब्जेक्ट को रेंडर करें, और फिर इसे आउटलाइनर शेडर के साथ रेंडर करें।


1
तो मुझे दो अलग-अलग shader प्रोग्राम बनाने चाहिए? फिर ऐसा क्यों है कि मैं एक शेडर प्रोग्राम को कई वर्टेक्स / ज्योमेट्री / फ्रेगरेंस शेड्स दे सकता हूं जैसा मैं चाहता हूं? एक कार्यक्रम के साथ इसे करने का एक तरीका होना चाहिए।
जामेगफिन

1
आप इसे एकाधिक शीर्ष (आदि) शेड नहीं दे रहे हैं। केवल एक मुख्य कार्य है, इसलिए आपके पास कई प्रवेश बिंदु नहीं हैं। यह एक सी प्रोग्राम के समान है, जिसमें आपके पास कई फाइलें हो सकती हैं जो एक प्रोग्राम बनाने के लिए एक साथ जुड़ी हुई हैं। आप इन फ़ाइलों को विभिन्न कार्यक्रमों के बीच साझा कर सकते हैं, इसलिए आपको कोड की नकल करने की आवश्यकता नहीं है, लेकिन प्रत्येक फ़ाइल आवश्यक रूप से अपने आप से एक कार्यक्रम नहीं है।
Chewy Gumball

1
यही कारण है कि जाने के लिए, एक बार एक shader जोड़ी (वर्टेक्स + टुकड़ा) के साथ एक बार फिर से प्रस्तुत करना एक और जोड़ी के साथ फिर से प्रस्तुत करना (या एक ही शीर्ष shader + एक और टुकड़ा shader का उपयोग करें)। कभी-कभी आप एक बफर को रेंडर करते हैं और अंतिम परिणाम में 'मिश्रण' करने के लिए एक और shader का उपयोग करते हैं (अभी तक)।
वालमंड

1

ओपनजीएल 4.0 में एकसमान सबरूटीन्स होते हैं । ये आपको उन कार्यों को परिभाषित करने की अनुमति देते हैं जिन्हें बहुत कम ओवरहेड के साथ रनटाइम पर स्वैप किया जा सकता है। तो आप प्रत्येक पास के लिए 1 फ़ंक्शन कर सकते हैं। प्रत्येक shader प्रकार के लिए 1 फ़ंक्शन।

नहीं है एक ट्यूटोरियल यहाँ

पुराने OpenGL संस्करणों के लिए आपका सबसे अच्छा दांव या तो विभिन्न शेड्स का एक गुच्छा होता है और उनके बीच स्वैप करना होता है। अन्यथा आप उन मूल्यों को एक साथ जोड़ सकते हैं जिन्हें आप एक समान से गुणा करते हैं जो या तो 0.0 या 1.0 है इसे चालू या बंद करें। अन्यथा सशर्त यदि बयानों का उपयोग किया जा सकता है, लेकिन ओपनजीएल हर निष्पादन को हर संभव परिणाम निष्पादित करेगा / तो पास सुनिश्चित करें कि वे बहुत भारी नहीं हैं।


0

कुछ लोग हैं जो GLSL के बारे में बहुत कुछ जानते हैं, इसलिए मुझे उम्मीद है कि वे सीधे रिकॉर्ड सेट करेंगे, लेकिन जो मैंने देखा है, उसके आधार पर, आपको अपने टुकड़े टुकड़े में, इस तरह से कुछ करना चाहिए (स्यूडोकोड, I 'वास्तविक GLSL को उन लोगों तक छोड़ देंगे जो इसे बेहतर जानते हैं):

out vec4 fragment_color
vec4 final_color
final_color = flat_color
If this fragment is in shadow
    final_color = shadow_color
If this fragment is an edge
    final_color = edge_color
If this fragment is a highlight
    final_color = highlight_color
fragment_color = final_color

ifइस तरह से s का उपयोग करने से आपको कई पास मिलते हैं। क्या इसका कोई मतलब है?

संपादित करें: इसके अलावा, उम्मीद है कि SO पर यह प्रश्न कुछ गलतफहमी को दूर करने में मदद करता है।


2
यह नोट करना महत्वपूर्ण है कि GLSL अगर सभी शाखाओं में हर स्टेटमेंट को निष्पादित करेगा, भले ही वे सक्षम न हों। जाहिरा तौर पर बस सब कुछ की गणना और सभी रंगों को एक साथ जोड़ने लेकिन उन्हें सक्षम या अक्षम करने के लिए मानों को 1.0 या 0.0 से गुणा करना तेज है।
डेविड सी। बिशप

1
@ DavidC.Bishop: यह सच नहीं है। कम से कम, सच होने की गारंटी नहीं । कंपाइलर तय करेगा कि एक वास्तविक शाखा तेज़ है या "सब कुछ गणना करें और बाद में इसे छाँटें" दृष्टिकोण तेज़ है।
निकोल बोलस

1
एक तरफ के रूप में, @ DavidC.Bishop द्वारा संदर्भित व्यवहार शायद ही shaders और GPU के लिए विशिष्ट है। यदि सामान्य रूप से परीक्षण किया गया मान उपलब्ध नहीं है, तो सामान्य प्रोग्रामों को निष्पादित करने वाले आधुनिक सीपीयू, कम से कम शाखाओं में से एक को अंजाम देंगे। यदि वे गलत हो जाते हैं, तो वे वापस रोल करते हैं और फिर से करते हैं। यह औसतन एक बड़े स्पीडअप को समाप्त करता है।
--पेट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.