सभी आर्टिकल
ट्यूटोरियल · 8 min read

फ़्रेम-रेट के बिल के बिना घनी पत्तियाँ: एक व्यावहारिक मार्गदर्शिका

एक दृश्य को वनस्पति से भरकर तेज़ बनाए रखने का तरीक़ा, instancing, cull दूरियाँ, LOD रणनीति, छाया-लागत, overdraw, घनत्व रखाई, और वह स्थिर-कैमरा प्रोफ़ाइलिंग लूप जो साबित करता है कि हर अनुकूलन सचमुच फलदायी रहा।

Illustration of a row of trees next to a rising frame-rate graph

संक्षेप में: घनी वनस्पति को शायद ही कभी अकेले त्रिभुज-गिनती मारती है: यह हज़ार draw call, लापरवाह अल्फ़ा कार्डों के overdraw, और उन छायाओं से मरती है जिनके चालू होने की किसी को याद नहीं थी। अपनी मेहनत इस क्रम में ख़र्च करें: पहले instancing, दूसरा cull दूरियाँ, तीसरा छायाएँ, चौथा LOD, पाँचवाँ घनत्व रखाई, और हर चरण को उसी स्थिर कैमरे से, एक बार में एक चर, सत्यापित करें, वरना आप कुछ नहीं सीखेंगे। यह मार्गदर्शिका हर चरण को उस प्रोफ़ाइलर हस्ताक्षर के साथ कवर करती है जो आपको बताता है कि यह आपकी समस्या है।

एक शांत धारा में परावर्तित घना वन-चंदोवा एक असली जंगल "मुफ़्त में" रेंडर होता है क्योंकि भौतिकी विशाल रूप से समांतर है। आपका GPU उस रूप को 60 fps पर नक़ली बना सकता है, पर केवल तब जब आप उस मशीनरी को हराना बंद कर दें जो इंजन ठीक इसी काम के लिए पहले से देते हैं।

मानसिक मॉडल: पाँच अड़चनें, एक क्रम

वनस्पति प्रदर्शन एक समस्या नहीं, पाँच है, और वे एक अनुमेय अनुक्रम में हावी रहती हैं। draw call पहले CPU को बाँधते हैं; cull दूरी तय करती है कि आप GPU से कितना खींचने को कह ही रहे हैं; छायाएँ चुपचाप उन सबकी लागत दुगुनी कर देती हैं जो उन्हें डालते हैं; LOD और overdraw प्रति-पिक्सेल बिल पर राज करते हैं; और घनत्व रखाई तय करती है कि इन सबका आपको वास्तव में कितना चाहिए था। इन्हें ग़लत क्रम में भिड़ें तो आप किसी ऐसी चीज़ का अनुकूलन करेंगे जो अड़चन थी ही नहीं। नीचे का क्रम वही है जिसमें लागत वास्तव में काटती है।

पहले instancing, बाक़ी सब बाद में

5,000 बार खींचा एक पेड़ 5,000 अलग-अलग पेड़ों से मूलतः सस्ता है: दोनों इंजन दोहराई मेश को instance किए draw में बैच करते हैं, और आपका पहला काम बस उस मशीनरी को न हराना है।

Unreal foliage और hierarchical instanced static meshes के ज़रिए बैच करता है; Unity GPU instancing और terrain विवरण के ज़रिए। बैचिंग को चुपचाप जो तोड़ता है:

  • वनस्पति जो instance के बजाय अद्वितीय actor/object के रूप में रखी गई;
  • प्रति-instance मटीरियल वेरिएंट: हर रूप के लिए मटीरियल रचने के बजाय एक मटीरियल के भीतर प्रति-instance डेटा (रंग, स्केल) इस्तेमाल करें;
  • संगठनात्मक रूप से बिखरी रखाई ताकि इंजन क्लस्टरों को इकाई के रूप में cull न कर सके।

प्रोफ़ाइलर की चुग़ली स्पष्ट है: पौधा-संख्या के साथ बढ़ते draw call। अगर एक जंगल दृश्य हज़ारों draw call दिखाता है, किसी और चीज़ को छूने से पहले इसे ठीक करें, इस सूची में और नीचे कुछ भी आपको नहीं बचाएगा, क्योंकि GPU के शुरू होने से पहले ही आप CPU-बाउंड हैं। स्वस्थ instance वनस्पति पूरे जंगल दृश्य के लिए draw call को निम्न सैकड़ों में रखती है, चाहे उसमें कितने ही हज़ार पौधे हों।

cull दूरियाँ मुफ़्त का पैसा हैं

घास को 800 मीटर दूर रेंडर होने की ज़रूरत नहीं: पॉप छुपाने वाली fade रेंज के साथ प्रति-प्रकार cull दूरियाँ सेट करें (भू-आवरण 30–60 मी, झाड़ियाँ 100–200 मी, केवल पेड़ लंबी दूरियों के हक़दार)।

यह पूरे पाइपलाइन में प्रति-मिनट सबसे ऊँचे मूल्य की सेटिंग है, और नियमित रूप से "अनंत" पर छोड़ दी जाती है क्योंकि डिफ़ॉल्ट वहीं है और कोई ग़ौर नहीं करता। तर्क धारणात्मक है: भू-आवरण 100 मी से बहुत पहले एक पिक्सेल से कम घेरता है, यह अंतिम छवि में शाब्दिक रूप से कुछ नहीं जोड़ता जबकि अब भी हर फ़्रेम वर्टिस, overdraw और छाया-काम ख़र्च करता है। दूर का आवरण सस्ती प्रणालियों का है: terrain मटीरियल का रंग, अपारदर्शी impostor, या बस सही हरे में रँगे terrain लेयर का दूर LOD।

fade रेंज (डिदर या अल्फ़ा) पॉप-आउट छुपाती हैं ताकि खिलाड़ी cull दूरी को कभी न देखें। fade को अदृश्य होने भर लंबा रखें और उससे ज़्यादा नहीं: बहुत लंबा fade यानी आप क्रॉसफ़ेड के दौरान उसी पौधे के दो प्रतिनिधित्वों का भुगतान कर रहे हैं।

छायाएँ: बिल का मौन आधा हिस्सा

छोटे भू-आवरण के लिए डायनामिक छाया-डालना बंद करें, पेड़ों के लिए रखें, और झाड़ियों के लिए दूरी-सीमित करें, क्योंकि घास की छायाएँ लगभग शून्य दृश्य लाभ के लिए आपकी लागत दुगुनी कर देती हैं।

छाया पास में हर घास की पत्ती प्रकाश के दृष्टिकोण से फिर खींची जाती है। घने दृश्यों में छाया पास अक्सर बेस पास जितना ख़र्चीला होता है, यानी घास की छायाएँ पूरे वनस्पति बजट का सबसे बड़ा एकल मद हो सकती हैं जबकि गुच्छे के आधार पर एक साधारण परिवेश-अँधेरे से दृश्यतः अभिन्न हैं। समाधान लगभग मुफ़्त: भू-आवरण के लिए छाया-डालना बंद, पेड़ों के लिए चालू (उनकी छायाएँ असली संयोजन-काम करती हैं), बीच वालों के लिए दूरी-सीमित। फिर पहले और बाद अपने प्रोफ़ाइलर में छाया पास जाँचें: यह आमतौर पर instancing के बाद सबसे बड़ी एकल जीत है, और मिनट लेती है।

LOD: छाया-आकृति का बजट बनाएँ, बहुभुज का नहीं

एक अच्छी वनस्पति LOD शृंखला रूपरेखा को बचाती और भीतर को क़त्ल करती है: संक्रमण दूरियों को आँख से सत्यापित करें, और impostor से पहले आख़िरी mesh LOD को सबसे कड़ा अनुकूलित करें, क्योंकि हर चौड़े शॉट में स्क्रीन पर वही होता है।

एक पगडंडी के किनारे वन-तल पर फ़र्न और निचली वनस्पति ऐसे भू-स्तर के पौधे वहीं हैं जहाँ cull दूरी और छाया सेटिंग सबसे ज़्यादा फल देती हैं: हज़ारों instance, हर एक कुछ दर्जन मीटर से आगे लगभग कुछ नहीं जोड़ता, हर एक अगर डायनामिक छाया डाले तो लागत में दुगुना।

एक हीरो पेड़ के लिए व्यावहारिक शृंखला: पूर्ण mesh → भीतर ~50 % कमी (वही छाया-आकृति) → मिलाए कार्डों के साथ ~15 % → अपारदर्शी impostor/billboard। दो नोट जो असली पीड़ा बचाते हैं:

  • वर्चुअलाइज़्ड ज्यामिति वाले इंजनों में भी दूर के impostor सार्थक रहते हैं, क्योंकि overdraw और छायाएँ असली लागत बनी रहती हैं चाहे त्रिभुज कैसे भी चुकाए जाएँ। वर्चुअलाइज़्ड ज्यामिति त्रिभुज-गिनती हल करती है, पारदर्शिता की लागत नहीं।
  • दूरी पर पारदर्शिता दुश्मन है। घने alpha-tested कार्ड ठीक वहीं overdraw ढेर करते हैं जहाँ GPU सबसे कमज़ोर है: बीच के LOD। पास में mesh पत्तियाँ और दूर अपारदर्शी impostor पसंद करें; अल्फ़ा-भारी बीच वही है जहाँ फ़्रेम समय छुपता है। अगर कोई एक LOD रहस्यमय ढंग से महँगा है, तो वह लगभग हमेशा पारदर्शी वाला है।

overdraw: वह लागत जो आप देख नहीं सकते

overdraw है GPU का उसी पिक्सेल को ढेर हुई पारदर्शी सतहों के आर-पार कई बार शेड करना: वनस्पति का ख़ास शाप, अंतिम छवि में अदृश्य, और अक्सर यह वजह कि एक "हल्का" दृश्य धीमा है।

अधिकांश इंजनों में overdraw विज़ुअलाइज़ेशन मोड होता है; उसे चालू करें और एक घास के मैदान को देखें। अगर वह सफ़ेद चमकता है, तो आप हर पिक्सेल को पाँच या दस बार शेड कर रहे हैं जैसे-जैसे अतिव्यापी अल्फ़ा कार्ड ढेर होते हैं। शमन: कई पतली के बजाय कम, बड़ी पत्तियाँ; जहाँ छाया-आकृति अनुमति दे वहाँ अपारदर्शी ज्यामिति; और सबसे कम योगदान वाले कार्डों का आक्रामक cull। overdraw "मेरा दृश्य धीमा है पर कुछ भी महँगा नहीं दिखता" का क्लासिक अपराधी है, क्योंकि त्रिभुज सस्ते हैं और पिक्सेल कई बार चुकाए जाते हैं।

घनत्व एक डिज़ाइन निर्णय है, स्लाइडर की स्थिति नहीं

जहाँ खिलाड़ी चलता और देखता है वहाँ घना, जहाँ नहीं वहाँ विरल: पगडंडी के किनारे 20 मी का समृद्ध विवरण-पट्टी एकसमान लागत के अंश पर "हर जगह हरा-भरा" पढ़ा जाता है।

ढलान और ऊँचाई मास्क इसका एक हिस्सा स्वतः करते हैं (खड़ी सतहों और दूर के पठारों को भू-आवरण की बिल्कुल ज़रूरत नहीं), और क्लस्टरिंग बाक़ी करती है: अंतराल वाले गुच्छे एकसमान भराई से सस्ते रेंडर होते हैं और अधिक प्राकृतिक दिखते हैं, तो प्रदर्शन-जीत और सौंदर्य-जीत एक ही दिशा में इशारा करती हैं। यहीं रखाई-औज़ार अपनी क़ीमत कमाता है: मास्क और प्रति-प्रजाति नियमों से घनत्व पेंट करना, फिर सीधे इंजन-नेटिव instance में बेक करना, एक दोपहर और एक हफ़्ते का अंतर है। यह Numivo के scatter के करने का केंद्र है, और चूँकि यह सादे foliage और instance मेश में बेक करता है, इस लेख की हर तकनीक परिणाम पर अपरिवर्तित लागू होती है। आपके और मानक अनुकूलनों के बीच कोई प्लगइन रनटाइम नहीं; बेक किया दृश्य बस इंजन सामग्री है।

प्रोफ़ाइलिंग लूप

वही कैमरा, वही दृश्य, एक बार में एक चर: हर बदलाव के बाद GPU फ़्रेम समय, draw call, छाया पास और overdraw मापें।

अपनी सबसे घनी विस्टा में एक स्थिर "बजट कैमरा" चुनें और ऊपर के हर चरण से पहले और बाद आँकड़ों का स्क्रीनशॉट लें। अनुशासन मायने रखता है क्योंकि वनस्पति अनुकूलन परस्पर क्रिया करते हैं: एक cull-दूरी बदलाव बदलता है कि छाया पास कितने instance देखता है; एक LOD बदलाव overdraw बदलता है; एक घनत्व बदलाव उन सबको एक साथ बदलता है। यादृच्छिक फ़्लाईथ्रू यादृच्छिक संख्याएँ और इस बारे में अखंडनीय बहसें पैदा करते हैं कि किसी बदलाव ने मदद की या नहीं। स्थिर कैमरे ऐसे निर्णय पैदा करते हैं जिनका आप बचाव कर सकते हैं। संख्याओं को एक साझा शीट में रखें, और रुझान-रेखा आपको वह कहानी बताती है जो एकल माप नहीं बता सकता।

चुराने लायक़ मैदानी आँकड़े

  • भू-आवरण cull: 30–60 मी · झाड़ियाँ: 100–200 मी · पेड़: दृष्टि-रेखा
  • एक स्वस्थ instance जंगल दृश्य के लिए draw call: निम्न सैकड़ों
  • घने दृश्यों में छाया पास का हिस्सा: अक्सर वनस्पति लागत का ~आधा, घास की छायाएँ बंद सबसे सस्ती बड़ी जीत है जो मौजूद है
  • "हर जगह हरा-भरा" पढ़ी जाने वाली पगडंडी-पट्टी ड्रेसिंग चौड़ाई: ~20 मी
  • एक हीरो पेड़ के लिए LOD संख्या: 3 mesh LOD + अपारदर्शी impostor
  • घास के लिए overdraw लक्ष्य: overdraw दृश्य में ~3× से कम, न कि ढेर अल्फ़ा कार्डों के सफ़ेद-चमकते 8–10×

मिनी-FAQ

क्या Nanite / वर्चुअलाइज़्ड ज्यामिति इसे अप्रचलित बना देती है? यह बदलती है कि कौन-से मद हावी हैं, अनुशासन नहीं। अल्फ़ा कार्डों का overdraw, छाया-लागत, और प्रति-instance ओवरहेड सब बने रहते हैं, और दूरी पर impostor अब भी फल देते हैं। यह मानने के बजाय कि नई तकनीक ने आपकी ख़ास अड़चन हल की, अपने लक्ष्य हार्डवेयर पर मापें, उसने शायद इसे खिसकाया हो, हटाया न हो।

कम घनत्व पर भी मेरा दृश्य धीमा क्यों है? आम संदिग्ध, क्रम में: डायनामिक छाया डालती घास, बैचिंग हराता प्रति-वेरिएंट अद्वितीय मटीरियल, अनंत पर cull दूरियाँ, या overdraw ढेर करती alpha-tested LOD शृंखला। हर एक का अलग प्रोफ़ाइलर हस्ताक्षर है: बदलने से पहले जाँचें, वरना आप ग़लत को ठीक करेंगे।

गेमप्ले के लिए "बहुत घना" कितना है? युद्ध की पठनीयता प्रदर्शन से पहले घनत्व की सीमा बाँधती है: अगर छाया-आकृतियाँ अव्यवस्था में लुप्त हो जाएँ, खिलाड़ी खेल को दोष देते हैं, ड्रेसिंग को नहीं। विस्टा में घना, अखाड़े में मध्यम: वह पैटर्न जो प्रोफ़ाइलर और प्लेटेस्ट दोनों को झेलता है।

बेक करूँ या प्रक्रियात्मक रखूँ? शिपिंग के लिए बेक करें: बेक किए instance ईमानदारी से प्रोफ़ाइल होते हैं और बिना रनटाइम-निर्भरता शिप होते हैं। प्रक्रियात्मक सेटअप (मास्क, नियम, सीड) को वर्शन कंट्रोल में रखें ताकि terrain बदलाव के बाद हाथ से काम दोहराए बिना पुनः बेक कर सकें।

घना दिखना और तेज़ होना विरोधाभास नहीं है: यह ज़्यादातर पाँच चीज़ें सही क्रम में करने और हर एक को उसी कैमरे से साबित करने का अनुशासन है।