क्या एक टुकड़े टुकड़े में एक मनमानी संख्या में रोशनी का उपयोग करने का एक तरीका है?


19

क्या खंडित शेडर के लिए प्रकाश स्थानों (और रंगों) की एक अनियंत्रित संख्या को पास करने का एक तरीका है, और छाया में उन पर लूप है?

यदि नहीं, तो कैसे कई रोशनी नकली माना जाता है? दिशात्मक प्रकाश व्यवस्था को फैलाने के लिए सम्मान के लिए, आप सिर्फ छाया के लिए प्रकाश भार का एक योग पारित नहीं कर सकते।


मैं WebGL के साथ काम नहीं कर रहा हूं, लेकिन OpenGL में, आपके पास अधिकतम 8 प्रकाश स्रोत हैं। मेरी राय में, यदि आप इससे अधिक से अधिक उत्तीर्ण करना चाहते हैं, तो आपको उदाहरण के लिए एकरूप चर का उपयोग करना होगा।
zacharmarz

पुरानी विधि हमेशा सभी रोशनी में पारित करने के लिए थी, अप्रयुक्त रोशनी को 0 प्रकाशमान पर सेट किया गया था और इसलिए यह दृश्य को प्रभावित नहीं करेगा। शायद ज्यादा इस्तेमाल नहीं किया ;-)
पैट्रिक ह्यूजेस

7
जब आप इस तरह से Google सामान बनाते हैं, तो 'WebGL' शब्द का उपयोग न करें - इन समस्याओं के करीब आने के बावजूद भी लोगों के लिए तकनीक बहुत छोटी है। उदाहरण के लिए इस खोज को लें , 'मैं भाग्यशाली महसूस कर रहा हूं' ने काम किया होगा। याद रखें कि एक WebGL समस्या को ठीक उसी OpenGL समस्या में अनुवाद करना चाहिए।
जोनाथन डिकिंसन

फॉरवर्ड रेंडरिंग में 8 से अधिक लाइट्स के लिए, मैं आम तौर पर एक मल्टी-पास शेडर का उपयोग करता हूं और प्रत्येक को 8 लाइट्स के एक अलग समूह को जोड़ने के लिए जोड़ देता हूं, एडिटिव ब्लेंडिंग का उपयोग करके।
ChrisC

जवाबों:


29

इससे निपटने के लिए आम तौर पर दो तरीके हैं। आजकल, वे आगे प्रतिपादन और आस्थगित प्रतिपादन कहलाते हैं। इन दोनों में एक भिन्नता है कि मैं नीचे चर्चा करूंगा।

आगे प्रतिपादन

प्रत्येक वस्तु को एक बार प्रत्येक प्रकाश के लिए प्रस्तुत करें जो इसे प्रभावित करता है। इसमें परिवेश प्रकाश शामिल है। आप एक additive मिश्रण मोड ( glBlendFunc(GL_ONE, GL_ONE)) का उपयोग करते हैं , इसलिए प्रत्येक प्रकाश के योगदान को एक दूसरे में जोड़ा जाता है। चूंकि विभिन्न लाइट्स का योगदान एडिटिव है, इसलिए फ्रेमबफ़र को अंततः वैल्यू मिलती है

आप एक फ्लोटिंग-पॉइंट फ्रेमबफ़र को प्रस्तुत करके एचडीआर प्राप्त कर सकते हैं। फिर आप दृश्यमान रेंज में एचडीआर प्रकाश मूल्यों को डाउन-स्केल करने के लिए दृश्य पर एक अंतिम पास लेते हैं; यह वह जगह भी होगी जहां आप ब्लूम और अन्य पोस्ट-इफेक्ट लागू करते हैं।

इस तकनीक के लिए एक सामान्य प्रदर्शन वृद्धि (यदि दृश्य में बहुत सी वस्तुएं हैं) "प्री-पास" का उपयोग करना है, जहां आप सभी वस्तुओं को बिना रंग फ्रेमबॉफ़र के कुछ भी आकर्षित किए बिना उपयोग करते हैं ( glColorMaskरंग लिखने को बंद करने के लिए)। यह सिर्फ गहराई बफर में भर जाता है। इस तरह, यदि आप किसी ऐसी वस्तु को प्रस्तुत करते हैं जो दूसरे के पीछे है, तो GPU जल्दी से उन अंशों को छोड़ सकता है। यह अभी भी शीर्ष shader को चलाने के लिए है, लेकिन यह आमतौर पर अधिक महंगे टुकड़े shader कंप्यूटर्स को छोड़ सकता है।

यह कोड के लिए सरल है और कल्पना करना आसान है। और कुछ हार्डवेयर (मुख्य रूप से मोबाइल और एम्बेडेड GPU) पर, यह विकल्प की तुलना में अधिक कुशल हो सकता है। लेकिन उच्च अंत हार्डवेयर पर, विकल्प आमतौर पर बहुत सी रोशनी वाले दृश्यों के लिए जीतता है।

आस्थगित प्रतिपादन

आस्थगित प्रतिपादन थोड़ा अधिक जटिल है।

सतह पर एक बिंदु के लिए प्रकाश की गणना करने के लिए आपके द्वारा उपयोग किए जाने वाले प्रकाश समीकरण निम्नलिखित सतह मापदंडों का उपयोग करता है:

  • सतह की स्थिति
  • सतही मानदंड
  • सतह रंग फैलाना
  • भूतल स्पेकुलर रंग
  • भूतल स्पेक्युलर शाइननेस
  • संभवतः अन्य सतह पैरामीटर (आपके प्रकाश समीकरण कितना जटिल है इसके आधार पर)

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

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

स्थिति आमतौर पर संग्रहीत नहीं होती है। इसके बजाय गणित द्वारा दूसरे पास में पुनर्गठित किया जाता है जो यहां तक ​​पहुंचने के लिए बहुत जटिल है। यह कहने के लिए पर्याप्त है, हम सतह पर बिंदु के कैमरा-स्थान की स्थिति का पता लगाने के लिए इनपुट के रूप में गहराई बफर और स्क्रीन-स्पेस टुकड़ा स्थिति का उपयोग करते हैं।

इसलिए, अब जब ये बनावट दृश्य के हर दृश्य पिक्सेल के लिए सतह की सभी जानकारी अनिवार्य रूप से रखती है, तो हम पूर्ण-स्क्रीन क्वाड प्रस्तुत करना शुरू करते हैं। प्रत्येक प्रकाश को एक पूर्ण-स्क्रीन क्वाड रेंडर मिलता है। हम सतह पैरामीटर बनावट से नमूना लेते हैं (और स्थिति को पुनर्गठित करते हैं), तो बस उन्हें उस प्रकाश के योगदान की गणना करने के लिए उपयोग करें। यह glBlendFunc(GL_ONE, GL_ONE)छवि में (फिर से ) जोड़ा गया है । हम ऐसा तब तक करते रहते हैं जब तक हम रोशनी से बाहर नहीं निकल जाते।

एचडीआर फिर से एक प्रक्रिया के बाद का कदम है।

आस्थगित प्रतिपादन के लिए सबसे बड़ा नकारात्मक है एंटीएलियासिंग। यह ठीक से एंटीएलियास के लिए थोड़ा और काम करने की आवश्यकता है।

सबसे बड़ा उल्टा, अगर आपके GPU में मेमोरी बैंडविड्थ बहुत अधिक है, तो यह प्रदर्शन है। हम केवल वास्तविक ज्यामिति को एक बार (या 1 + 1 प्रति प्रकाश जो छाया है, यदि हम छाया मानचित्रण कर रहे हैं) प्रस्तुत करते हैं। हम कभी भी छिपे हुए पिक्सेल या ज्यामिति पर नहीं बिताते हैं जो इसके बाद दिखाई नहीं देता है। लाइटिंग पास का सारा समय उन चीजों पर खर्च किया जाता है जो वास्तव में दिखाई देती हैं।

यदि आपके GPU में बहुत अधिक मेमोरी बैंडविड्थ नहीं है, तो लाइट पास वास्तव में चोट करना शुरू कर सकता है। स्क्रीन पिक्सेल प्रति 3-5 बनावट से खींचना मज़ेदार नहीं है।

लाइट प्री-पास

यह आस्थगित प्रतिपादन पर एक बदलाव की तरह है जिसमें दिलचस्प ट्रेडऑफ़ हैं।

बस के रूप में आस्थगित प्रतिपादन में, आप अपने सतह मापदंडों को बफ़र्स के एक सेट में प्रस्तुत करते हैं। हालाँकि, आपने सतह डेटा संक्षिप्त किया है; इस समय आप जिस एकमात्र सतह डेटा की देखभाल करते हैं, वह है गहराई बफर मान (स्थिति को फिर से संगठित करने के लिए), सामान्य, और स्पेक्युलर चमक।

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

फिर, आप ज्यामिति को फिर से प्रस्तुत करते हैं, कुल स्पेक्युलर का उपयोग करते हुए और सतह के रंग के साथ अंतिम संयोजन करने के लिए प्रकाश संगणना को फैलाते हैं, इस प्रकार समग्र प्रतिबिंब का निर्माण करते हैं।

यहाँ अपसाइड यह है कि आपको मल्टीसमैपलिंग वापस मिलती है (कम से कम, आस्थगित से आसान)। आप अग्रेषित रेंडरिंग की तुलना में कम प्रति-ऑब्जेक्ट रेंडरिंग करते हैं। लेकिन मुख्य बात यह है कि यह प्रदान करता है अलग सतहों के लिए अलग प्रकाश व्यवस्था समीकरणों के लिए एक आसान समय है।

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

यह आगे प्रदान करने के मामले के रूप में ज्यादा स्वतंत्रता प्रदान नहीं करता है। लेकिन यह अभी भी तेज है अगर आपके पास स्पेयर करने के लिए बनावट बैंडविड्थ है।


-1: एलपीपी / पीपीएल का उल्लेख करने में विफलता। -1 आस्थगित: रेंडरिंग किसी भी DX9.0 हार्डवेयर पर एक त्वरित जीत है (हाँ, यहां तक ​​कि मेरे 'व्यवसाय' लैपटॉप पर भी) - जो कि आधारभूत आवश्यकताओं के लिए 2009 है। जब तक आप DX8.0 (जो कि स्थगित / एलपीपी नहीं कर सकते) को लक्षित कर रहे हैं आस्थगित / एलपीपी डिफ़ॉल्ट है । अंत में 'बहुत सारी मेमोरी बैंडविड्थ' पागल है - हम आम तौर पर अभी भी पीसीआई-एक्स एक्स 4 को संतृप्त नहीं कर रहे हैं, इसके अलावा, एलपीपी मेमोरी बैंडविड्थ को काफी हद तक गिरा देता है। अंत में, -1 आपकी टिप्पणी के लिए; इस तरह से ठीक है? तुम्हें पता है कि उन छोरों प्रति फ्रेम 2073600 बार हो रहा है, है ना? ग्राफिक्स कार्ड के विरोधाभास के साथ भी, यह बुरा है।
जोनाथन डिकिंसन

1
@JonathanDickinson मुझे लगता है कि उनकी बात यह थी कि डिफर्ड / लाइट प्री-पास के लिए मेमोरी बैंडविड्थ आमतौर पर फॉरवर्ड रेंडरिंग से कई गुना बड़ा होता है। यह आस्थगित दृष्टिकोण को अमान्य नहीं करता है; इसे चुनने पर विचार करना कुछ है। BTW: आपके आस्थगित बफ़र्स वीडियो मेमोरी में होना चाहिए, इसलिए PCI-X बैंडविड्थ अप्रासंगिक है; यह GPU का आंतरिक बैंडविड्थ है जो मायने रखता है। लंबे समय तक पिक्सेल शेड, जैसे कि एक अनियंत्रित लूप के साथ, उपयोगी कार्य करने के बारे में कुछ पता नहीं चलता है। और z- बफर प्रीपास ट्रिक में कुछ भी गलत नहीं है; यह बढ़िया काम करता है।
नाथन रीड

3
@JonathanDickinson: यह WebGL के बारे में बात कर रहा है, इसलिए "शेडर मॉडल" की कोई भी चर्चा अप्रासंगिक है। और किस प्रकार का उपयोग करने के लिए प्रतिपादन एक "धार्मिक विषय" नहीं है: यह बस एक बात है कि आप किस हार्डवेयर पर चल रहे हैं। एक एम्बेडेड जीपीयू, जहां "वीडियो मेमोरी" बस नियमित रूप से सीपीयू रैम है, आस्थगित प्रतिपादन के साथ बहुत खराब काम करेगा। मोबाइल टाइल-आधारित रेंडर पर, यह और भी खराब है । हार्डवेयर की परवाह किए बिना स्थगित प्रतिपादन "तत्काल जीत" नहीं है; यह किसी भी हार्डवेयर की तरह ही इसकी ट्रेडऑफ है।
निकोल बोलस

2
@JonathanDickinson: "इसके अलावा, z- बफर प्री-पास ट्रिक के साथ आप उन वस्तुओं के साथ z- लड़ाई को खत्म करने के लिए संघर्ष करने जा रहे हैं जिन्हें खींचा जाना चाहिए।" वह कुल बकवास है। आप एक ही ट्रांसफॉर्म मैट्रिसेस और एक ही वर्टेक्स शेडर वाली समान वस्तुओं का प्रतिपादन कर रहे हैं। 1 दिन में वूडू में मल्टीपास का प्रतिपादन किया गया ; यह एक हल समस्या है। संचित प्रकाश व्यवस्था को बदलने के लिए कुछ भी नहीं है।
निकोल बोलस

8
@JonathanDickinson: लेकिन हम वायरफ्रेम रेंडर करने की बात नहीं कर रहे हैं, क्या हम हैं? हम पहले की तरह ही त्रिकोण प्रस्तुत करने की बात कर रहे हैं । OpenGL एक ही वस्तु के लिए प्रतिरूपण की गारंटी देता है (जब तक आप एक ही शीर्ष shader का उपयोग कर रहे हैं, निश्चित रूप से, और फिर भी, invariantअन्य मामलों के लिए इसकी गारंटी देने के लिए कीवर्ड है)।
निकोल बोलस

4

आपको आस्थगित प्रतिपादन या पूर्व-पास प्रकाश का उपयोग करने की आवश्यकता है । पुराने फिक्स्ड फंक्शन पाइपलाइनों में से कुछ (पढ़ें: नो शेड्स) 16 या 24 लाइट्स तक सपोर्ट करती हैं - लेकिन ऐसा है । आस्थगित प्रतिपादन प्रकाश सीमा को समाप्त करता है; लेकिन अधिक जटिल प्रतिपादन प्रणाली की कीमत पर।

जाहिरा तौर पर वेबलॉग MRT का समर्थन करता है जो किसी भी प्रकार के आस्थगित प्रतिपादन के लिए आवश्यक है - इसलिए यह संभव हो सकता है; मुझे यकीन नहीं है कि यह कितना प्रशंसनीय है।

वैकल्पिक रूप से आप यूनिटी 5 की जांच कर सकते हैं - जिसने बॉक्स के ठीक बाहर रेंडर किया है।

इससे निपटने का एक और सरल तरीका है कि आप केवल लाइट्स को प्राथमिकता दें (हो सकता है, खिलाड़ी से दूरी के आधार पर और चाहे वे कैमरे के फ्यूम में हों) और केवल शीर्ष को सक्षम करें 8. बहुत सारे एएए शीर्षक बिना अधिक प्रभाव के ऐसा करने में कामयाब रहे। आउटपुट की गुणवत्ता पर (उदाहरण के लिए, सुदूर रो 1)।

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

साइड नोट: आप उन्हें एक shader में पाश नहीं करना चाहते थे? अपने प्रदर्शन को अलविदा कहें। GPU एक CPU नहीं है और इसे उसी तरह से काम करने के लिए डिज़ाइन नहीं किया गया है, उदाहरण के लिए, जावास्क्रिप्ट करता है। याद रखें कि आपके द्वारा प्रस्तुत प्रत्येक पिक्सेल (यदि यह ओवरराइट भी हो जाता है) को लूप निष्पादित करना पड़ता है - इसलिए यदि आप 1920x1080 पर चल रहे हैं और एक साधारण लूप जो 16 बार चलता है तो आप प्रभावी रूप से उस लूप के अंदर सब कुछ चला रहे हैं 33177600 बार। आप ग्राफिक्स कार्ड समानांतर में उन अंशों का एक बहुत भाग लेंगे , लेकिन उन छोरों अभी भी पुराने हार्डवेयर खा जाएगा।


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

1
कृपया चौथा पैराग्राफ पढ़ें।
जोनाथन डिकिंसन

2

आप एक पिक्सेल shader का उपयोग कर सकते हैं जो n लाइट्स का समर्थन करता है (जहाँ n एक छोटी संख्या है जैसे 4 या 8), और दृश्य को कई बार फिर से खोलना, हर बार रोशनी का एक नया बैच पास करना, और उन सभी को एक साथ संयोजित करने के लिए additive सम्मिश्रण का उपयोग करना।

यही मूल विचार है। बेशक इस तेजी से उचित आकार के दृश्य के लिए पर्याप्त अनुकूलन करने के लिए बहुत सारे अनुकूलन आवश्यक हैं। सभी बत्तियाँ मत खींचो, बस दिखाई देने वाले (हताशा और रोना culling); वास्तव में प्रत्येक पास में पूरे दृश्य को फिर से ड्रा न करें , बस उस पास में रोशनी की सीमा के भीतर की वस्तुओं; शेडर के कई संस्करण हैं जो अलग-अलग संख्या में रोशनी का समर्थन करते हैं (1, 2, 3, ...) ताकि आप अधिक रोशनी का मूल्यांकन करने में अपना समय बर्बाद न करें।

जब आप कई छोटी बत्तियां रखते हैं, तो अन्य उत्तर में बताए गए आस्थगित प्रतिपादन एक अच्छा विकल्प है, लेकिन यह एकमात्र तरीका नहीं है।

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