GLTF और GLB क्या हैं?
GLTF (GL ट्रांसमिशन फॉर्मेट) 3D दृश्यों और मॉडलों को संग्रहीत करने के लिए एक फ़ाइल प्रारूप है, जो समझने में बेहद आसान है (संरचना JSON मानक में लिखी गई है), एक्सटेंसिबल और आसानी से आधुनिक वेब प्रौद्योगिकियों के साथ इंटरैक्ट करता है। यह प्रारूप तीन आयामी दृश्यों को अच्छी तरह से संपीड़ित करता है और वेबजीएल और अन्य एपीआई का उपयोग करके अनुप्रयोगों के रनटाइम प्रसंस्करण को कम करता है। GLTF को अब 3 डी दुनिया से जेपीईजी के रूप में क्रोनोस ग्रुप द्वारा सक्रिय रूप से पदोन्नत किया गया है। वर्तमान में GLTF संस्करण 2.0 का उपयोग किया जाता है। जीएलबी नामक इस प्रारूप का एक द्विआधारी संस्करण भी है, जिसका एकमात्र अंतर यह है कि सब कुछ जीएलबी एक्सटेंशन के साथ एक फ़ाइल में संग्रहीत है।
यह लेख 2 का भाग 1 है। इसमें, हम ऐसे प्रारूप कलाकृतियों और उनकी विशेषताओं को दृश्य, नोड, बफर, बफ़र व्यू, एक्सेसर और मेष के रूप में देखेंगे । और दूसरे लेख में हम बाकी को देखेंगे: सामग्री, बनावट, एनिमेशन, त्वचा और कैमरा। अधिक सामान्य प्रारूप की जानकारी यहां मिल सकती है ।
यदि आप व्यक्तिगत रूप से एक लेख को देखते हुए इस प्रारूप के साथ काम करना चाहते हैं, तो आप गिटहब पर आधिकारिक ख्रोनोस भंडार से GLTF 2.0 मॉडल डाउनलोड कर सकते हैं

मुद्दा और इसका समाधान
प्रारंभ में, जीएलटीएफ प्रारूप की कल्पना ख्रोनोस समूह द्वारा इंटरनेट पर 3 डी सामग्री को प्रसारित करने के लिए एक समाधान के रूप में की गई थी और इसे ग्राफिक एपीआई के साथ काम करते समय विभिन्न प्रकार के आयातकों और कन्वर्टर्स की संख्या को कम करने के लिए डिज़ाइन किया गया था।

वर्तमान में, GLTF और इसके बाइनरी भाई GLB का उपयोग सीएडी कार्यक्रमों (ऑटोडेस्क माया, ब्लेंडर, आदि) में एकीकृत प्रारूपों के रूप में किया जाता है, खेल इंजन (अवास्तविक इंजन, एकता, आदि), एआर / वीआर अनुप्रयोगों और सामाजिक सेवाओं में। नेटवर्क आदि।
ख्रोनोस समूह के प्रतिनिधि निम्नलिखित बताते हैं:
- जीएलटीएफ सार्वभौमिक है - इसका उपयोग समान रूप से सरल ज्यामिति के साथ-साथ एनिमेशन, विभिन्न सामग्रियों, आदि के साथ जटिल दृश्यों के लिए भी किया जा सकता है।
- यह काफी कॉम्पैक्ट है। हां, यह तर्क दिया जा सकता है, क्योंकि सब कुछ रूपांतरण एल्गोरिदम पर निर्भर करता है, और मैं व्यक्तिगत रूप से ऐसे मामलों को जानता हूं जहां जीएलटीएफ मूल से बड़ा था, उदाहरण के लिए, एफबीएक्स फ़ाइल, लेकिन ज्यादातर मामलों में यह है।
- डेटा विश्लेषण में आसानी इस प्रारूप का मूल प्लस है। GLTF पदानुक्रम JSON का उपयोग करता है, और ज्यामिति को द्विआधारी रूप में संग्रहीत किया जाता है, कोई डिकोडिंग की आवश्यकता नहीं होती है!
समन्वय प्रणाली और इकाइयाँ
GLTF एक दाएं हाथ की समन्वित प्रणाली का उपयोग करता है, अर्थात, + X और + Y का क्रॉस उत्पाद + Z देता है, जहां + Y शीर्ष अक्ष है। 3D GLTF परिसंपत्ति के सामने + Z अक्ष का सामना करना पड़ता है। सभी रैखिक दूरी के लिए माप की इकाइयां मीटर हैं, कोणों को रेडियन में मापा जाता है, और वस्तुओं का सकारात्मक घुमाव वामावर्त है। एनिमेशन के नोड रूपांतरण और चैनल पथ तीन आयामी वैक्टर या निम्नलिखित डेटा प्रकार और शब्दार्थ के साथ quaternions हैं:
अनुवाद : एक त्रि-आयामी सदिश जिसमें x, y और z axes साथ अनुवाद हैं
रोटेशन : quaternion (x, y, z, w), जहां w एक अदिश राशि है
स्केल : x, y और z स्केलिंग कारकों से युक्त एक त्रि-आयामी वेक्टर

GLTF - एक अंदर का नजारा
जैसा कि ऊपर उल्लेख किया गया है, जीएलटीएफ, एक नियम के रूप में, 2 फाइलें शामिल हैं: 1 .gltf प्रारूप के साथ, जो JSON के रूप में 3 डी दृश्य की संरचना को संग्रहीत करता है और दूसरा फ़ाइल .bin प्रारूप के साथ, जो इस दृश्य के सभी डेटा को सीधे संग्रहीत करता है।
प्रारूप संरचना कड़ाई से पदानुक्रमित है और इसके निम्न रूप हैं:

संरचना के बारे में आगे बोलते हुए, मैं सबसे सरल GLTF फ़ाइल के उदाहरणों का उपयोग करूंगा, जो डिफ़ॉल्ट सामग्री के साथ 1-तरफा त्रिकोण को संग्रहीत करता है। यदि आप चाहते हैं, तो आप इसे कॉपी कर सकते हैं और किसी भी GLTF दर्शक में व्यक्तिगत रूप से फ़ाइल की सामग्री को "महसूस" करने के लिए पेस्ट कर सकते हैं। अपने अभ्यास में, मैंने अलग-अलग लोगों का उपयोग किया, लेकिन इस पर बस गए, जो हुड के नीचे थ्री.जेएस का उपयोग करता है। इसके अलावा एक अच्छा विकल्प GLTF प्लगइन के साथ विजुअल स्टूडियो कोड का उपयोग करना होगा। तो आपके पास तुरंत 3 इंजनों में से एक विकल्प होगा: बाबुल.जेएस, सीज़ियम, तीन.जेएस
दृश्य और नोड तत्व
पहली चीजें पहले मुख्य नोड है जिसे सीन कहा जाता है। यह फ़ाइल में रूट बिंदु है जहां यह सब शुरू होता है। इस नोड में GLTF स्टोर और फ़ाइल खोलने के बाद डिफ़ॉल्ट रूप से लोड किए जाने वाले विकल्प को चुनने का एक दृश्य होता है। 3D दृश्य की सामग्री अगली वस्तु से शुरू होती है, जिसे "नोड" कहा जाता है। दृश्यों और नोड्स की एक सरणी व्यर्थ में नहीं बताई गई थी, क्योंकि एक फ़ाइल में कई दृश्यों को संग्रहीत करने की क्षमता कार्यान्वित की जाती है, लेकिन व्यवहार में वे एक दृश्य को एक फ़ाइल में संग्रहीत करने का प्रयास करते हैं।
{ "scenes" : [ { "nodes" : [ 0 ] } ], "nodes" : [ { "mesh" : 0 } ], "scene": 0
प्रत्येक नोड व्यक्तिगत वस्तुओं का वर्णन करने के लिए एक "प्रवेश बिंदु" है। यदि वस्तु जटिल है और इसमें कई जाल हैं, तो ऐसी वस्तु का वर्णन "अभिभावक" और "बच्चे" नोड द्वारा किया जाएगा। उदाहरण के लिए, एक कार, जिसमें एक शरीर और पहियों होते हैं, को निम्नानुसार वर्णित किया जा सकता है: मुख्य नोड कार का वर्णन करता है और, विशेष रूप से, इसका शरीर। इस नोड में "चाइल्ड नोड्स" की एक सूची है, जो बदले में, शेष घटकों, जैसे, उदाहरण के लिए, पहियों का वर्णन करता है। सभी तत्वों को पुनरावर्ती रूप से संसाधित किया जाएगा। नोड्स में टीआरएस (अनुवाद, रोटेशन, स्केल उर्फ विस्थापन, रोटेशन और स्केलिंग) एनिमेशन हो सकते हैं। इस तथ्य के अलावा कि इस तरह के परिवर्तन सीधे मेष को ही प्रभावित करते हैं, वे बिल्कुल उसी तरह से बाल नोड्स को भी प्रभावित करते हैं। उपरोक्त सभी के अलावा, मुझे लगता है कि यह ध्यान देने योग्य है कि आंतरिक "कैमरे", यदि कोई हो, जो उपयोगकर्ता के लिए फ्रेम में ऑब्जेक्ट को प्रदर्शित करने के लिए जिम्मेदार हैं, तो नोड ऑब्जेक्ट से भी जुड़े हुए हैं। ऑब्जेक्ट उपयुक्त विशेषताओं का उपयोग करके एक दूसरे को संदर्भित करते हैं: दृश्य में एक नोड विशेषता होती है, एक नोड ऑब्जेक्ट में एक मेष विशेषता होती है। एक सरल समझ के लिए, उपरोक्त सभी को निम्न आकृति में चित्रित किया गया है।

बफ़र, बफ़र व्यू और एक्सेसर
बफ़र ऑब्जेक्ट का अर्थ है बाइनरी का भंडारण, असंसाधित, बिना संरचना के डेटा, बिना मूल्य के विरासत। बफर ज्यामिति, एनिमेशन और स्किनिंग के बारे में जानकारी संग्रहीत करता है। बाइनरी डेटा का मुख्य लाभ यह है कि यह बहुत ही कुशलतापूर्वक GPU द्वारा संसाधित किया जाता है, जैसा कि संभवतः, अपघटन को छोड़कर, अतिरिक्त पार्सिंग की आवश्यकता नहीं है। बफर में डेटा को यूआरआई विशेषता द्वारा पाया जा सकता है, जो स्पष्ट रूप से यह स्पष्ट करता है कि डेटा कहाँ स्थित है और केवल 2 विकल्प हैं: या तो डेटा को .bin प्रारूप के साथ एक बाहरी फ़ाइल में संग्रहीत किया जाता है, या वे स्वयं JSON के अंदर एम्बेडेड होते हैं। पहले मामले में, यूआरआई में एक बाहरी फ़ाइल का लिंक होता है, इस मामले में, जिस फ़ोल्डर में GLTF फ़ाइल स्थित है उसे रूट माना जाता है। दूसरे मामले में, फ़ाइल में .glb प्रारूप होगा, जो हमें अधिक कॉम्पैक्ट, फ़ाइलों की संख्या, GLTF जुड़वां भाई, GLB प्रारूप के संदर्भ में संदर्भित करता है। बाइनरी फ़ाइल में डेटा को बाइट-बाय-बाइट के रूप में संग्रहीत किया जाता है।

हमारे त्रिकोण उदाहरण में JSON इस तरह दिखेगा:
बेस 64 एनकोडेड बफर का एक उदाहरण:
"buffers" : [ { "uri" : "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 44 } ],
यदि आपके पास कोई बाहरी फ़ाइल है, तो JSON इसका दृश्य निम्नलिखित में बदल देगा:
"buffers" : [ { "uri" : "duck.bin", "byteLength" : 102040 } ],
बफ़र्स ब्लॉक में एक अतिरिक्त बाइटलेक्लिअर विशेषता भी है, जो बफर आकार के मूल्य को संग्रहीत करता है।
बफर से डेटा को संरचित करने में पहला कदम बफ़र व्यू ऑब्जेक्ट है। बफ़र व्यू को बफ़र की जानकारी का "टुकड़ा" कहा जा सकता है, जो बफर की शुरुआत से बाइट्स की एक निश्चित बदलाव की विशेषता है। इस "स्लाइस" को 2 विशेषताओं का उपयोग करके वर्णित किया गया है: रीड बफर की शुरुआत और स्लाइस की लंबाई से "शिफ्ट" गणना। हमारे उदाहरण के आधार पर उनके उपयोग को स्पष्ट करने के लिए कई बफ़र व्यू ऑब्जेक्ट्स का एक सरल उदाहरण:
"bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 6, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 8, "byteLength" : 36, "target" : 34962 } ],
जैसा कि आप देख सकते हैं, इस उदाहरण में 4 मुख्य विशेषताएं हैं:
- बफर बफर के सूचकांक को इंगित करता है (बफर सरणी में अनुक्रम संख्या 0 से शुरू होती है)।
- बाइटऑफसेट - इस "स्लाइस" के लिए बाइट्स में मूल की "पारी" को परिभाषित करता है
- बाइट लर्निंग - "स्लाइस" की लंबाई को परिभाषित करता है
- लक्ष्य - बफरव्यू में निहित डेटा के प्रकार को परिभाषित करता है
पहले बफ़र व्यू में बफर के पहले 6 बाइट्स होते हैं और उनकी कोई शिफ्ट नहीं होती है। दूसरे "स्लाइस" के साथ, सब कुछ थोड़ा और अधिक जटिल है: जैसा कि आप देख सकते हैं, इसकी पारी 8 वीं बाइट पर है, अपेक्षित 6 के बजाय। ये 2 बाइट्स रिक्त हैं और बफर पीढ़ी प्रक्रिया के दौरान "पेडिंग" नामक प्रक्रिया के लिए जोड़े गए थे। सीमा बाइट्स के मूल्य को 4 बाइट्स पर समायोजित करने के लिए यह आवश्यक है। बफर से डेटा की तेज और आसान रीडिंग के लिए इस ट्रिक की जरूरत है।

यह लक्ष्य विशेषता के बारे में कुछ शब्द कहने के लायक है। इसका उपयोग बफर व्यू द्वारा संदर्भित सूचना के प्रकार को वर्गीकृत करने के लिए किया जाता है। केवल 2 विकल्प हैं: या तो इसका मूल्य 34962 होगा, जिसका उपयोग वर्टेक्स विशेषताओं (वर्टेक्स एट्रिब्यूट्स - 34962 - ARRAY_BUFFER) या 34963 को संदर्भित करने के लिए किया जाता है, जिसका उपयोग वर्टेक्स इंडेक्स के लिए किया जाता है (वर्टेक्स इंडेक्स - 34963 - ELEMENT_ARRAY_BUFFER)। बफ़र में सभी जानकारी को समझने और संरचित करने का अंतिम स्पर्श एक्सेसर ऑब्जेक्ट है।
एक्सेसर एक ऐसी वस्तु है जो बफ़रव्यू तक पहुँचती है और इसमें ऐसे गुण होते हैं जो बफ़रव्यू से डेटा का प्रकार और स्थान निर्धारित करते हैं। एक्सेसर डेटा प्रकार टाइप और कंपोनेंट टाइप में इनकोड किया गया है। प्रकार विशेषता का मान एक स्ट्रिंग है और इसमें निम्न मान हैं: स्केलर मान के लिए SCALAR, 3-आयामी वैक्टर के लिए VEC3 और 4x4 मैट्रिक्स या चतुर्धातुक के लिए MAT4, जिसका उपयोग रोटेशन का वर्णन करने के लिए किया जाता है।
ComponentType, बदले में, इस डेटा के घटक के प्रकार को इंगित करता है। यह एक GL स्थिरांक है, जिसमें 5126 (FLOAT) या 5123 (UNSIGNED_SHORT) जैसे मूल्य हो सकते हैं, उदाहरण के लिए, यह इंगित करने के लिए कि तत्वों का एक अस्थायी बिंदु है, आदि।
इन गुणों के विभिन्न संयोजनों का उपयोग मनमाने ढंग से डेटा प्रकारों का वर्णन करने के लिए किया जा सकता है। हमारे त्रिकोण पर आधारित एक उदाहरण।
"accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 3, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 3, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] } ],
आइए JSON में प्रस्तुत विशेषताओं का विश्लेषण करें:
- बफर व्यू - बफ़र व्यू सरणी से बफ़र व्यू की क्रम संख्या को इंगित करता है जो एक्सेसर उपयोग करता है। बफ़रव्यू, बदले में, अनुक्रमित के बारे में जानकारी संग्रहीत करता है।
- बाइटऑफसेट - बाइट शिफ्ट वर्तमान एक्सेसर से डेटा पढ़ना शुरू करने के लिए। मल्टीपल एक्सेसर ऑब्जेक्ट एक बफ़र व्यू को संदर्भित कर सकते हैं।
- घटक टाइप तत्वों के प्रकार को इंगित करने वाला एक निरंतर है। इसमें 5123 मान हो सकते हैं, जो डेटा प्रकार UNSIGNED_SHORT से मेल खाती है, या FLOAT के लिए 5126।
- गिनती - प्रदर्शित करता है कि कितने तत्व बफर में संग्रहीत हैं।
- प्रकार - डेटा प्रकार को परिभाषित करता है: स्केलर, वेक्टर, मैट्रिक्स।
- अधिकतम और न्यूनतम - विशेषताएँ जो अंतरिक्ष में इन तत्वों की स्थिति का न्यूनतम और अधिकतम मूल्य निर्धारित करती हैं।
जाल
मेश ऑब्जेक्ट में दृश्य में स्थित मेश के बारे में जानकारी होती है। एक नोड (नोड ऑब्जेक्ट) केवल 1 जाल स्टोर कर सकता है। टाइप मेश के प्रत्येक ऑब्जेक्ट में टाइप मेश की एक सरणी होती है। उभयलिंगी, बदले में, आदिम आदिम ऑब्जेक्ट्स हैं (उदाहरण के लिए, त्रिकोण) जिनमें से मेष ही होते हैं। इस ऑब्जेक्ट में कई अतिरिक्त विशेषताएं हैं, लेकिन यह सब एक उद्देश्य को पूरा करता है - ऑब्जेक्ट के प्रदर्शन के बारे में जानकारी का सही भंडारण। मेष की मुख्य विशेषताएं:
- स्थिति - XYZ कुल्हाड़ियों के साथ कोने की स्थिति
- सामान्य - सामान्यीकृत XYZ वर्टेक्स नॉर्मल
- टैंगेंट - एक्सवाईजेडडब्ल्यू कोने के स्पर्शरेखा। डब्ल्यू इंगित करता है कि स्पर्शरेखा कहाँ निर्देशित है और इसका मूल्य +1 या -1 है।
- TEXCOORD_0 - यूवी बनावट समन्वय करती है। कई सेट संग्रहीत किए जा सकते हैं।
- COLOR_0 - आरजीबी या RGBA रंगों के कोने।
- JOINTS_0 - इस विशेषता में संबंधित जोड़ों के सरणी से जोड़ों / जोड़ों के सूचकांक शामिल हैं, जो कि शीर्ष (वर्टेक्स) को प्रभावित करना चाहिए।
- WEIGHTS_0 - इस विशेषता के डेटा से यह पता चलता है कि संयुक्त कितना शीर्ष को प्रभावित करता है।
- वजन - विशेषता वजन वजन के लिए जिम्मेदार है।
- सामग्री - इसमें सूचकांक होता है, जो सामग्री सरणी में सामग्री की संख्या है
यह वस्तु हमारे मामले के लिए निम्न रूप होगी:
"meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1 }, "indices" : 0 } ] } ],
दुर्भाग्य से, प्रतिबंध के कारण, सभी सामग्री एक लेख में फिट नहीं हुई थी, इसलिए बाकी दूसरे लेख में पाया जा सकता है, जिसमें हम शेष कलाकृतियों पर विचार करेंगे: सामग्री, बनावट, एनिमेशन, त्वचा और कैमरा , साथ ही साथ एक न्यूनतम काम करने वाली GLTF फ़ाइल एकत्र करें।
2 भाग में निरंतरता: https://habr.com/en/post/448298/