मैं अपने सिर के चारों ओर लपेट के लिए कैसे की तरह सामग्री प्रणालियों कोशिश कर रहा हूँ इस , यह लागू किया जाता है। ये शक्तिशाली और उपयोगकर्ता के अनुकूल, ग्राफ़ जैसी प्रणाली प्रोग्रामर और गैर-प्रोग्रामर को समान रूप से शेड बनाने की अनुमति देने की एक विधि के रूप में अपेक्षाकृत सामान्य लगती हैं । हालांकि, ग्राफिक्स प्रोग्रामिंग के साथ मेरे अपेक्षाकृत सीमित अनुभव से, मुझे पूरी तरह से यकीन नहीं है कि वे कैसे काम करते हैं।
पृष्ठभूमि:
इसलिए, जब मैंने पहले सरल OpenGL रेंडरिंग सिस्टम प्रोग्राम किया है , तो मैं आमतौर पर एक सामग्री वर्ग बनाता हूं जो स्थिर GLSL फ़ाइलों से लोड, संकलन और लिंक शेड्स बनाता है जो मैंने मैन्युअल रूप से बनाए हैं। मैं भी आम तौर पर इस वर्ग को GLSL वर्दी चर तक पहुँचने के लिए एक साधारण आवरण के रूप में बनाता हूं। एक साधारण उदाहरण के रूप में, कल्पना कीजिए कि मेरे पास एक बुनियादी वर्टीकल शेडर और फ्रैग्मेंट शैडर है, जिसमें एक टेक्सचर पास करने के लिए अतिरिक्त यूनिफॉर्म Texture2D है। मेरी सामग्री वर्ग बस उन दो शेड्स को एक सामग्री में लोड और संकलित करेगा, और उस बिंदु से उस shader के Texture2D वर्दी को पढ़ने / लिखने के लिए एक सरल इंटरफ़ेस को उजागर करेगा।
इस प्रणाली को थोड़ा और अधिक लचीला बनाने के लिए, मैं आमतौर पर इसे इस तरह से लिखता हूं जिससे मुझे किसी भी नाम / प्रकार की वर्दी पास करने का प्रयास करने की अनुमति मिलती है [अर्थात: SetUniform_Vec4 ("AmbientColor", colorVec4); जो "colorVec4" कहा जाता है कि अगर वर्दी सामग्री में मौजूद है एक विशेष 4d वेक्टर को AmbientColor वर्दी स्थापित करेगा।] ।
class Material
{
private:
int shaderID;
string vertShaderPath;
string fragSahderPath;
void loadShaderFiles(); //load shaders from files at internal paths.
void buildMaterial(); //link, compile, buffer with OpenGL, etc.
public:
void SetGenericUniform( string uniformName, int param );
void SetGenericUniform( string uniformName, float param );
void SetGenericUniform( string uniformName, vec4 param );
//overrides for various types, etc...
int GetUniform( string uniformName );
float GetUniform( string uniformName );
vec4 GetUniform( string uniformName );
//etc...
//ctor, dtor, etc., omitted for clarity..
}
यह काम करता है, लेकिन यह इस तथ्य के कारण एक खराब प्रणाली की तरह लगता है कि सामग्री वर्ग के ग्राहक को विश्वास पर वर्दी तक पहुंचना पड़ता है - उपयोगकर्ता को उन वर्दी के बारे में कुछ जागरूक होना होगा जो प्रत्येक भौतिक वस्तु में हैं क्योंकि वे मजबूर हैं उनके GLSL नाम से उन्हें पास करें। जब यह सिस्टम के साथ काम करने वाले 1-2 लोगों के लिए है, तो यह बहुत बड़ी बात नहीं है, लेकिन मैं कल्पना नहीं कर सकता कि यह प्रणाली बहुत अच्छी तरह से पैमाने पर होगी, और इससे पहले कि मैं एक ओपनजीएल रेंडरिंग सिस्टम प्रोग्रामिंग में अपना अगला प्रयास करूं, मैं स्तर बनाना चाहता हूं थोड़ा सा।
सवाल:
यही वह जगह है जहां मैं अब तक हूं, इसलिए मैं यह अध्ययन करने की कोशिश कर रहा हूं कि अन्य रेंडरिंग इंजन अपनी सामग्री प्रणालियों को कैसे संभालते हैं।
यह नोड-आधारित दृष्टिकोण बहुत अच्छा है और आधुनिक इंजनों और उपकरणों में उपयोगकर्ता के अनुकूल सामग्री प्रणाली बनाने के लिए यह एक बहुत ही सामान्य प्रणाली है। जो मैं बता सकता हूं कि वे एक ग्राफ डेटा संरचना पर आधारित हैं, जहां प्रत्येक नोड आपकी सामग्री के कुछ छाया पहलू का प्रतिनिधित्व करता है और प्रत्येक पथ उनके बीच किसी प्रकार के संबंध का प्रतिनिधित्व करता है।
मैं जो बता सकता हूं, उस तरह के सिस्टम को लागू करने से सबक्लासेस (टेक्सचरनरोड, फ्लोटनोड, लेरपीनोड, आदि) की एक किस्म के साथ एक सरल सामग्री मैटेरियल क्लास होगी। जहां प्रत्येक MaterialNode उपवर्ग में MaterialConnections होगा।
class MaterialConnection
{
MatNode_Out * fromNode;
MatNode_In * toNode;
}
class LerpNode : MaterialNode
{
MatNode_In x;
MatNode_In y;
MatNode_In alpha;
MatNode_Out result;
}
यह बहुत ही मूल विचार है, लेकिन मैं थोड़ा अनिश्चित हूं कि इस प्रणाली के कुछ पहलू कैसे काम करेंगे:
1.) यदि आप अवास्तविक इंजन 4 का उपयोग करने वाले विभिन्न 'मटीरियल एक्सप्रेशंस' (नोड्स) को देखते हैं, तो आप देखेंगे कि उनमें से प्रत्येक में विभिन्न प्रकार के इनपुट और आउटपुट कनेक्शन हैं। कुछ नोड्स आउटपुट फ्लोट करते हैं, कुछ आउटपुट वेक्टर 2, कुछ आउटपुट वेक्टर 4, आदि। मैं ऊपर दिए गए नोड्स और कनेक्शन को कैसे सुधार सकता हूं ताकि वे विभिन्न प्रकार के इनपुट और आउटपुट प्रकारों का समर्थन कर सकें? क्या MatNode_Out_Float और MatNode_Out_Vec4 (और इसी तरह) के साथ MatNode_Out को उप-वार करना एक बुद्धिमान विकल्प होगा?
2.) आखिरकार, इस तरह की प्रणाली जीएलएसएल शेड्स से कैसे संबंधित है? UE4 (और इसी तरह ऊपर से जुड़ी अन्य प्रणालियों के लिए) को देखते हुए, उपयोगकर्ता को अंततः कुछ सामग्री नोड को विभिन्न मापदंडों के साथ बड़े नोड में प्लग करने की आवश्यकता होती है जो शेडर मापदंडों (आधार रंग, धातु, चमक, उत्सर्जन, आदि) का प्रतिनिधित्व करते हैं। । मेरी मूल धारणा यह थी कि UE4 में कई तरह के यूनिफॉर्म के साथ किसी तरह का कठोर कोडेड 'मास्टर शेडर' था, और उपयोगकर्ता जो कुछ भी अपनी 'सामग्री' में करता है, बस 'मास्टर शेडर' को पास कर दिया जाता है, जब वे अपने नोड्स को 'प्लग' में रखते हैं। मास्टर नोड '।
हालाँकि, UE4 प्रलेखन स्थिति:
"प्रत्येक नोड में एचएलएसएल कोड का एक स्निपेट होता है, जो एक विशिष्ट कार्य करने के लिए नामित होता है। इसका मतलब है कि जैसे ही आप एक सामग्री का निर्माण करते हैं, आप दृश्य स्क्रिप्टिंग के माध्यम से एचएलएसएल कोड बना रहे हैं।"
यदि यह सच है, तो क्या यह प्रणाली एक वास्तविक shader स्क्रिप्ट उत्पन्न करती है? यह कैसे काम करता है?