3D Model Formatları · glTF / GLB · Sahne Verileri
Node Hiyerarşisi: Sahnedeki Nesneler Nasıl İlişkilendirilir?
Dosya yapısı serisi şu soruları cevapladı: veri nerede (buffer), hangi bayt aralığından (bufferView), nasıl okunur (accessor). Bu sayfa tamamen farklı bir katmandır: sahne organizasyonu. Soru artık «ham veri nerede?» değil; «sahnedeki varlıklar birbirleriyle nasıl ilişkilendirilir?»
glTF’de node, sahnedeki bir varlığı temsil eden kayıttır. Ebeveyn–çocuk bağlarıyla ağaç kurar; mesh, kamera veya ışık taşıyabilir ya da yalnızca boş bir organizasyon noktası olabilir. Bu sayfada scene graph optimizasyonu, TRS / matrix matematiği, world matrix, skinning / kemik, ECS veya render sıralaması anlatılmaz bunlar ayrı konulardır.
Sayfayı bitirdiğinizde şu cümleyi kurabilmelisiniz: «Node’lar sahnedeki nesneleri temsil eder; ebeveyn–çocuk ilişkileri hiyerarşik yapılar oluşturur. Buffer, bufferView ve accessor model verisinin nasıl saklandığını açıklar; node hiyerarşisi bu verilerin sahnede nasıl organize edildiğini tanımlar.»
Node Nedir?
Dosya yapısı serisi «veri nerede, hangi bayt aralığı, nasıl parse edilir?» sorularını
cevapladı. Sahne hattına geçince soru değişir: «Sahnedeki varlıklar
birbirleriyle
nasıl ilişkilendirilir?» glTF’de bu ilişkinin birim kaydı
nodedur JSON’daki nodes dizisinin
tek bir elemanı.
Her node kaydı, sahnedeki tek bir varlık için düşünülür: isteğe bağlı bir
isim, sahneye yerleşim bilgisi (transform alanları detayı Transform sayfasında), isteğe
bağlı mesh / kamera / ışık referansları ve alt node’lara giden
children bağlantıları. Node «3D modelin kendisi» değildir; sahnede duran
organizasyon birimidir boş bir grup da olabilir, görünür mesh taşıyan
yaprak da.
Node hangi soruyu cevaplar?
Katmanları karıştırmamak için tek satırda:
buffers/accessors→ «Geometri baytları nerede, nasıl okunur?» (binary · accessor)meshes→ «Bu geometri tanımı hangi attribute’ları kullanır?» (geometri tanımı Vertex Data sayfasına bırakılır)nodes→ «Bu tanım sahneye hangi varlık olarak, kime bağlı oturuyor?»
Node, üçgen koordinatı veya materyal rengi depolamaz; gerektiğinde başka
tablolara indeksle «şuraya bak» der. Bu yüzden node kayıtları genelde küçüktür ağır veri
buffers içinde, anlam tablolarda, ilişki node’larda kurulur.
Dört olası yüz aynı tablo, farklı roller
Yeni başlayanların en sık hatası node = mesh sanmaktır. Oysa
nodes[i] zorunlu olarak geometri taşımaz; kayıt türü export’a göre değişir:
Mesh taşıyan node. "mesh": N alanı, meshes[N]
tanımına referanstır üçgen listesi ve attribute bağlantıları orada yaşar, node içinde
gömülü değildir. Sahnedeki «görünür gövde» hissi bu eşleşmeden gelir; fakat gövde tanımı
ile sahne varlığı hâlâ ayrı kayıtlardır.
Kamera taşıyan node. "camera": N, cameras[N]
kaydına işaret eder (projeksiyon, clip plane vb. kamera tanımı orada). Node, o kamerayı
sahne ağacına hangi dalda konduğunuzu belirler lens parametreleri ile sahne
yerleşimi karıştırılmamalıdır.
Işık taşıyan node. Çekirdek spec’te ışık tablosu yoktur; çoğu dosyada
KHR_lights_punctual extension ile extensions altında
tanım, node üzerinden sahneye bağlanır. Yine desen aynıdır: tanım bir yerde, sahne
ilişkisi node’da.
Boş organizasyon node’u. Ne mesh ne camera
yalnızca name, transform ve children taşır. DCC araçlarında
«Empty», «Null», «Group» veya koleksiyon kökü gibi düşünün: «Araba» node’u altında
tekerlekler; arabanın kendisi mesh olmak zorunda değildir. Bu tür kayıtlar hiyerarşiyi
okunabilir kılar (§3).
Node, model değildir ne taşır, ne taşımaz
Export edilmiş bir GLB’de outliner’da «Body» node’u görürsünüz; içinde binlerce üçgen
vardır ama üçgenler node JSON’una yazılmaz. Veri hattı:
buffers → bufferViews → accessors →
meshes (JSON haritası). Node yalnızca «meshes[2]’yi
sahne varlığı olarak kullan» der indeks referansı mekaniği JSON Structure’da anlatıldı; bu
sayfada tekrarlanmaz, node’un o referansı sahne organizasyonu için kullanması
vurgulanır.
Node kaydında bulunmayan şeyler (bilinçli sınır):
- Vertex / normal / UV baytları — accessor + buffer hattında
- Primitive başına materyal tanımı —
meshes→materialszincirinde - Parent indeksi glTF’de çocuk listesi ebeveynde; parent tersine okunur (§3)
- World matrix, TRS birleşimi — transform alanları node’da başlar, birleşim hesabı Transform / Scene Graph konularında
Minimal kayıt: yalnızca grup
En sade node yalnızca isim ve alt bağlantı (indeksler örnektir):
{
"name": "Vehicle",
"children": [1, 2, 3, 4]
}
Bu kayıtta mesh yoktur; «Vehicle» sahne ağacında bir daltır. Altındaki
1…4 node’ları mesh taşıyabilir. Dosyada meshes dolu,
nodes[0] boş görünüyorsa panik etmeyin bu, glTF’nin normal ve kasıtlı
kullanımıdır. Ağır geometri tanımı ile hafif organizasyon kaydı yan yana durur.
Sık karıştırılan kavramlar
| Kavram | Ne sorar? | Node ile ilişki |
|---|---|---|
| Node | Sahne varlığı, hiyerarşi | Bu sayfanın konusu |
| Mesh | Geometri tanımı (primitive, attribute) | Node mesh ile referans verir; mesh node değildir |
| Primitive | Mesh içindeki çizilebilir alt birim | Node doğrudan primitive seçmez mesh üzerinden dolaylı |
| Scene | Aktif kök node listesi | scenes hangi node’ların kök olduğunu söyler (§4) |
«Sahnedeki her şey bir node’du» neredeyse doğru: görünür içerik genelde mesh taşıyan node’lardan gelir; kamera ve ışık da node ile sahneye oturur. «Her node görünür» değildir: boş gruplar render edilmez, yine de hiyerarşi için gereklidir.
JSON Structure ile sınır
JSON Structure sayfası nodes tablosunu haritada
gösterdi: «dönüşüm, çocuklar, mesh / skin / camera referansı». Orada amaç dosyanın
anatomisini tanımaktı. Bu sayfa aynı tablonun sahne organizasyonu
olarak ne anlama geldiğini açar node kayıtları birbirine children ile
bağlanarak ağaç kurar; aynı mesh birden fazla node’da paylaşılabilir (§6). İndeks çözümleme ve
Node → Mesh → Material zincirinin tablo tabanlı okunması JSON sayfasında
kaldı; burada «node sahne varlığıdır, mesh tanımı değildir» cümlesi netleşir.
Neden Node Katmanı Var?
§1’de node’un ne olduğunu gördük; bu bölüm neden ayrı bir katman
gerektiğini kurar. glTF zaten meshes, materials,
accessors ile «ne çizilecek?» sorusunu cevaplayabilir peki «parçalar
birbirine
nasıl bağlı, hangi grup hangi parçayı içeriyor?» sorusu neden ayrıca
nodes ister?
Düz listenin sınırı
Düz bir liste hayal edin yalnızca isimler:
Gövde
Tekerlek_SOL_ÖN
Tekerlek_SAĞ_ÖN
Tekerlek_SOL_ARKA
Tekerlek_SAĞ_ARKA
Direksiyon
Kapı_SOL
Kapı_SAĞ
…
Her satır bağımsız bir kayıt gibi durur. «Tekerlek_SOL_ÖN» ile «Gövde» aynı araca mı ait? İsimden çıkarırsınız belki fakat isimlendirme disiplini bozulunca (farklı export, farklı dil, otomatik numaralandırma) ilişki kaybolur. Sahne on parçadan bin parçaya çıktığında liste okunmaz hale gelir: hangi indeksler birlikte taşınmalı, hangi parça hangi mantıksal gruba ait, hangi kamera hangi rig’e bağlı hepsi dosya dışında not defterinde kalır.
Node katmanı bu listeyi ağaç yapısına çevirir. Aitlik artık isim
kuralına değil, children bağlantısına dayanır (§3). Tek bir «Vehicle» dalı altında tekerlekler toplanır; kapılar ayrı alt dala alınabilir yapı, metinden bağımsız ve loader tarafından doğrudan
okunabilir olur.
İki ihtiyaç: tanım tablosu ve ilişki ağacı
glTF bilinçli olarak iki düzlemi ayırır:
- Tanım tabloları (
meshes,materials,cameras…) «Bu geometri / materyal / kamera nedir?» Soru veri ve parametre tanımıdır; dosya yapısı serisinde ağırlıklı olarak burası işlendi. - Node ağacı «Bu tanımlar sahneye hangi varlık olarak, kime bağlı oturuyor?» Soru organizasyondur.
Aynı meshes[3] tanımı tek başına sahneye konmaz; bir node
"mesh": 3 dediğinde «bu geometri, şu dalda, şu hiyerarşik bağlamda var»
anlamına gelir. Node katmanı olmasaydı glTF yalnızca «katalog» olurdu ne çizileceği
bellidir, sahne düzeni bellí değildir. JSON Structure her iki tabloyu haritada gösterdi; bu sayfa
nodes tarafının var olma gerekçesini açar.
Neden ağaç, neden düz indeks listesi değil?
«Sahnedeki tüm mesh indekslerini scenes[0].meshes: [0,1,2,…] diye yazsak
olmaz mı?» olmaz; çünkü kayıp olan şey iç içe gruplamadir. Araba
örneği:
Vehicle ← boş grup node (§1)
├─ Body ← mesh taşıyan yaprak
├─ Wheel_FL
├─ Wheel_FR
├─ Wheel_RL
├─ Wheel_RR
└─ SteeringWheel
«Vehicle» mesh taşımayabilir yalnızca alt parçaları bir arada tutan organizasyon köküdür. Düz listede bu ortak kök yoktur; «hepsi araba» bilgisini her parçaya ayrı ayrı taşımak gerekir. Ağaçta ise tek ebeveyn altında toplama yeterlidir. Parent hareket ettiğinde çocukların birlikte hareket etmesi beklentisi bu yapıdan doğar hesap Transform sayfasında; burada yalnızca organizasyon ihtiyacının ağacı zorunlu kıldığı not edilir.
Kamera ve çevre aynı sahnede kardeş dallar olabilir «Vehicle» ile «Camera» aynı seviyede, birbirinin parçası değil. Düz mesh listesi «kamera nerede duruyor, araba ile ilişkisi ne» sorusunu ayıramaz; node ağacı rolleri ayırır.
İçerik üretiminden gelen beklenti
Modelleme araçlarında sahne zaten hiyerarşik kurulur: koleksiyonlar, boş objeler, parent
altına snap edilmiş parçalar. Export «sahneyi düzleştir, yalnızca mesh bırak» deseydi DCC
ile runtime arasında köprü kopar. glTF node katmanı, bu üretim alışkanlığını dosyaya
taşır sanatçı outliner’da gördüğü yapı, JSON’da nodes + children
olarak korunur. Rig, kapı, silah attachment gibi ileri konular ayrı sayfalarda kalır; temel
motivasyon aynıdır: ilişkiyi kaybetmeden aktarmak.
Node olmasaydı ne olurdu?
Her parça kök seviyede, ilişkisiz indeksler halinde dururdu. «Hepsi bir araba» bilgisi:
- Harici JSON / oyun motoru config dosyasında tutulurdu glTF taşınabilir paket olmaktan çıkar.
- Animasyon hedefleri isim string’lerine bağlanırdı isim değişince pipeline kırılır.
- Aynı mesh’in dört tekerlekte kullanımı (§6) veri tarafında mümkün olsa bile «dört ayrı tekerlek bir araca ait» gruplaması dosyada resmileşmez.
glTF ilişkiyi dosyanın içinde, standart biçimde saklar. Bu, binary depolama veya accessor verimliliği sorununu çözmez o katmanlar «baytlar nasıl sıkıştırılır, nasıl okunur?» der. Node katmanı «sahne kim kime bağlı?» der. İki soru birbirini tamamlar; biri diğerinin yerine geçmez.
Node katmanı gereksiz tekrar değil
«meshes zaten var, neden bir de nodes?» çünkü mesh kaydı
geometri tanımıdır; sahne varlığı değildir. Tek mesh tanımı, sıfır node ile dosyada
«tanımlı ama sahneye konmamış» kalabilir; birden fazla node ile aynı tanım farklı
dallarda kullanılabilir. Node katmanı, tanım tablolarının üzerine ilişki
grafiği ekler; veriyi ikinci kez yazmaz (indeks referansı ile aynı mantık). Somut mühendislik
faydaları (okunabilirlik, gruplama, pipeline) §7’de listelenir; bu bölüm yalnızca katmanın
var olma nedenini kurar.
Parent ve Child İlişkisi
§1–§2 node’un ne olduğunu ve neden ayrı katman gerektiğini kurdu. Bu bölüm sayfanın kalbidir: ilişki nasıl dosyaya yazılır? glTF hiyerarşisi yönlü ağaçtır her node en fazla bir ebeveyne sahiptir; bağlantı çocuk tarafında değil, ebeveyn tarafında listelenir.
Parent ve child iki kavram
Parent (ebeveyn): Alt node’ları taşıyan üst kayıt. glTF’de ebeveynlik
children: [ … ] dizisiyle ifade edilir dizi, nodes tablosundaki
çocuk indekslerini listeler. Ebeveyn kaydında mesh olmak zorunda değildir; yalnızca alt dalları toplayan boş grup da ebeveyn olabilir (§1).
Child (çocuk): Başka bir node’un children dizisinde geçen
alt kayıt. Çocuk kendi children dizisine sahip olabilir o zaman hem çocuk
hem ebeveyn rolündedir (ara dal). Yaprak node’un çocuğu yoktur; yalnızca mesh / kamera
taşıyabilir.
İlişki tek yönlü saklanır: JSON’da «node 3’ün parent’ı 0» diye bir alan yoktur; loader tüm kayıtları tarayıp «0 numaralı node’un children listesinde 3 var mı?» sorusuyla ebeveyni bulur. Bu tasarım, indeks tabanlı referans düzeninin parçasıdır isimle değil, dizi konumuyla bağ kurulur.
Şema: kardeş, ata, yaprak
Root ← kök (§4)
│
├─ Camera ← Root’un çocuğu
│
└─ Vehicle ← Root’un çocuğu; Camera ile kardeş
│
├─ Body ← Vehicle’ın çocuğu
├─ Wheel_A ← kardeş tekerlekler
├─ Wheel_B
└─ Wheel_C
Kardeş (sibling): Aynı children dizisinde yan yana listelenen
node’lar «Camera» ile «Vehicle» Root’un çocukları olduğu için kardeştir; birbirinin altına
girmezler. «Wheel_A» yalnızca «Vehicle»ın çocuğudur; «Camera» ile doğrudan bağlantısı
yoktur. Bu ayrım, «tüm parçalar birbirine bağlı» hissini önler; ilişki yalnızca
açıkça listelenen parent → child kenarlarıyla vardır.
İç dal (internal node): Hem çocuğu hem (genelde) ebeveyni vardır «Vehicle», «Root»un çocuğu ve tekerleklerin ebeveyni. Yaprak (leaf): Çocuğu yoktur «Body» veya «Wheel_A» gibi; mesh taşıyan yapraklar sıktır. Organizasyon ağacında yaprak sayısı, iç dal sayısından fazladır.
Ağacın kuralları kısa
glTF sahne hiyerarşisi pratikte şu kurallara uyar (matematik ispatı değil, dosya disiplini):
- Tek ebeveyn: Bir node, farklı iki parent’ın
childrenlistesinde aynı anda yer almamalıdır aksi halde «hangi dalda?» belirsizleşir. - Döngü yok: A, B’nin çocuğu iken B de A’nın çocuğu olamaz ağaç sonsuz döngüye kilitlenir. Geçerli export’lar döngüsüz ağaç üretir.
- Indeks geçerliliği:
childreniçindeki her sayınodesdizisinde var olan bir indekse işaret etmelidir.
Scene Graph sayfası runtime’da bu ağacın nasıl gezildiğini ele alır; burada yalnızca dosyadaki statik bağ öğretilir.
JSON’da nasıl görünür?
Aynı araba parçaları indekslerle:
{
"nodes": [
{ "name": "Vehicle", "children": [1, 2, 3, 4] },
{ "name": "Body", "mesh": 0 },
{ "name": "Wheel_A", "mesh": 1 },
{ "name": "Wheel_B", "mesh": 1 },
{ "name": "Wheel_C", "mesh": 1 }
]
}
Okuma alıştırması:
nodes[0]«Vehicle»children: [1,2,3,4]der: çocuklarım 1, 2, 3 ve 4 numaralı kayıtlar.nodes[1]«Body»childrenyok; yaprak;mesh: 0.nodes[2…4]tekerlekler hepsimesh: 1paylaşır (§6); ebeveynleri yalnızca Vehicle (0) üzerinden bilinir.
children dizisindeki sıra, hiyerarşik aitliği değiştirmez
1-2-3-4 ile 4-3-2-1 aynı ağaçtır. Sıra bazı loader’larda traversal veya outliner
görünümünü etkileyebilir; render önceliği veya transform birleşimi bu sayfanın dışındadır.
Transform alanları (translation, rotation, scale)
her node kaydında isteğe bağlıdır birleşim hesabı Transform Verileri sayfasına
bırakılır.
Neden «parent» alanı yok?
Birçok motor API’sinde «setParent(child, parent)» vardır; glTF JSON’da ise yalnızca «parent’ın çocuk listesi» vardır. Pratik sonuçlar:
- Çocuk kaydında ebeveyn bilgisi doğrudan okunmaz ters tarama veya yükleme sırasında oluşturulan lookup tablosu gerekir.
- Export tek geçişte «bu node’un çocukları şunlar» diye yazar DCC outliner yönüyle uyumludur.
- Boş
childrenalanı ile alanın hiç yazılmaması aynı anlama gelir: çocuk yok.
«Parent indeksi nerede?» sorusunun cevabı: ebeveynin
children dizisinde, çocuğun indeksi olarak ters yönde değil.
Scene Graph değil statik iskelet
Bu bölümde öğrendiğiniz yapı, sahne graph’ının dosyadan gelen ham iskeletidir. Scene Graph sayfası görünürlük, güncelleme sırası, runtime traversal ve world matrix güncellemesini ele alacak. Burada yalnızca: glTF’de parent–child children indeksleriyle tanımlanır; ilişki ağacıdır; tek ebeveyn ve döngüsüzlük beklenir. Parent hareket edince child neden birlikte hareket eder sorusu ilişkiyi kurduktan sonra doğal olarak gelir cevap transform katmanındadır, bu bölüm yalnızca bağın varlığını sabitler.
Root Node Kavramı
§3 parent–child bağını öğretti: ilişki children ile kurulur, ebeveyn ters
okunur. Peki ağaç nereden başlar? Her hiyerarşinin bir giriş noktası gerekir
glTF’de buna kök (root) node denir. Kök, hiçbir başka node’un
children listesinde geçmeyen node’dur; yani ebeveyni yoktur (§3).
Sahne kökleri: scenes tablosu
nodes dizisi dosyadaki tüm node kayıtlarını içerir hepsi
aktif sahnede görünmek zorunda değildir. Hangi node’ların kök sayılacağını
scenes belirler. Aktif sahne, kök dosya alanı "scene": N ile
seçilir; ilgili kayıt scenes[N].nodes dizisinde kök indeksleri listeler.
scene: 0 ← hangi sahne aktif?
scenes[0].nodes ← bu sahnenin kök node indeksleri
↓
nodes[i] ← kök kayıtlar (children ile ağaç genişler)
JSON Structure scenes satırını haritada
«hangi kök sahne aktif?» diye tanıttı; bu bölüm kök node’un hiyerarşi rolünü
açar tablo anatomisi tekrar öğretilmez.
Kök node nasıl tanınır?
Pratik kural: nodes dizisindeki indeks k köktür ⟺ hiçbir
nodes[j].children dizisinde k geçmez. Loader veya debug aracı tüm
children listelerini birleştirip «hiç listelenmemiş» indeksleri kök adayı
sayar; bunların hangilerinin gerçekten sahneye dahil olduğu
scenes[i].nodes ile filtrelenir.
Kök olmak mesh taşımayı gerektirmez «World» veya «SceneRoot» adlı boş grup node sık köktür. Adı «Root» olmak zorunda değildir; glTF ilişkiyi indeks ile kurar, isim yalnızca okunabilirlik içindir.
Tek kök ve çoklu kök
Basit GLB’lerde scenes[0].nodes: [0] yeterlidir tek kök, altında tüm ağaç.
Büyük sahnelerde birden fazla kök normaldir:
scenes[0].nodes: [0, 5]
nodes[0] Environment ← kök dal A
nodes[5] Characters ← kök dal B (kardeş kökler)
«Environment» ile «Characters» §3’teki kardeş kavramına benzer aynı seviyede, aynı ebeveyni yok (ikisi de kök). Biri gökyüzü / zemin, diğeri oynanabilir karakterler gibi ayrı mantıksal dalları temsil eder. Transform ve dünya koordinatına oturma ayrı konudur; burada yalnızca sahnenin hangi indekslerden asıldığı önemlidir.
Minimal örnek yalnızca kök vurgusu
{
"scene": 0,
"scenes": [
{ "name": "Main", "nodes": [0, 3] }
],
"nodes": [
{ "name": "Environment", "children": [1, 2] },
{ "name": "Ground", "mesh": 0 },
{ "name": "Sky", "mesh": 1 },
{ "name": "PlayerRig", "children": [4] },
{ "name": "Body", "mesh": 2 }
]
}
Aktif sahne «Main» kökler 0 (Environment) ve 3 (PlayerRig).
İndeks 1, 2, 4 kök değildir; bir ebeveynin
children listesinde geçerler. Tam sahne + yaprak/dal okuması §8’de; burada odak yalnızca
scenes[0].nodes satırının «giriş kapısı» olmasıdır.
Dosyada olup sahnede kök olmayan node’lar
nodes dizisinde kayıtlı olup hiçbir kökten children zinciriyle
ulaşılamayan node’lar dosyada bulunabilir örneğin gizli LOD, yedek parça veya ikinci
sahneye ait dal. Aktif sahnenin kök listesine dahil değillerse runtime’da o an
görünmezler; bu, mesh tanımının dosyada durup sahneye konmamasına benzer (§1). Kök listesi «bu
sahnede hangi dallar canlı» sorusunun cevabıdır tüm node envanterinin listesi değil.
Birden fazla scenes kaydı
Dosyada scenes[1], scenes[2] … olabilir; yalnızca
scene alanının işaret ettiği kayıt varsayılan aktif sahnedir (menü, oyun
modu veya loader seçimi ile değişebilir API ayrı konu). Her sahne kaydının kendi
nodes kök listesi vardır; aynı node indeksi teorik olarak farklı sahnelerde
kök olabilir, pratik export’larda genelde sahne başına ayrı ağaçlar kurulur. Sahne
graph’ın çoklu sahne yönetimi Scene Graph sayfasına bırakılır.
Kök ≠ dünya origin
«Kök node nerede duruyor?» sorusu transform ile karıştırılır. Kök, hiyerarşide
ebeveynsiz node’dur; dünya koordinatındaki konumu translation /
rotation / scale alanlarına bağlıdır sıfır kök, modeli
otomatik olarak dünya (0,0,0)’a koymaz. Pivot, origin ve world space ayrımı Transform /
Pivot sayfalarında; bu bölüm yalnızca ağacın hangi indekslerden başladığını
sabitler.
Node Bir Organizasyon Katmanıdır
§1 node’un tanımını, §3–§4 ilişki ve kökü kurdu. Bu bölüm mesajı tek cümlede toplar: node, geometri / kamera / ışık tanımlarını üreten katman değil; bu tanımları sahne ağacına yerleştiren ve birbirine bağlayan organizasyon katmanıdır. Veri «ne» sorusu alt tablolarda; node «sahnedeki varlık olarak nerede duruyor, kime bağlı» sorusundadır.
Üç sıkı ayrım tanım vs yerleşim
Karışıklığı önlemek için aynı cümle disiplini (§1 ile uyumlu, fakat organizasyon vurgusuyla):
Node geometri değildir. Üçgenler, attribute bağlantıları ve primitive
listesi meshes + accessors + buffers hattındadır.
Node yalnızca
"mesh": N ile «bu geometri tanımının sahne örneği burada»
der mesh’in içeriğini değiştirmez, kopyalamaz. Geometri derinliği Vertex Data
sayfasına; burada yalnızca adresleme rolü sabitlenir.
Node kamera değildir. Projeksiyon matrisi, clip plane, aspect gibi
parametreler cameras tablosundaki kayıttadır. Node "camera": N
dediğinde «cameras[N] tanımını taşıyan sahne varlığı benim» der lens
ayarları ile sahne hiyerarşisindeki konum ayrı katmanlardır.
Node ışık değildir. Çekirdek glTF’de ışık tablosu yoktur; tanım çoğu dosyada extension (KHR_lights_punctual vb.) altında ayrı nesne olarak durur. Node, o tanımı sahne ağacına asar ışığın rengi / tipi node JSON’unda gömülü değildir, extension + referans düzenindedir.
Ortak desen: tanım bir tabloda, sahne varlığı node’da. Node bir «kılıf» veya «askı noktası» gibidir; içeriği indeksle seçer.
Boş node geçerli ve sık
Mesh, kamera veya ışık taşımayan node «hatalı export» değildir. «Empty», «Null», «Group»
veya «Vehicle» gibi kayıtlar yalnızca name, transform ve
children ile vardır §1’deki minimal «Vehicle» örneği bunun tipidir. Kullanım
alanları:
- Mantıksal grup: Alt parçaları tek dalda toplamak (araba gövdesi + tekerlekler).
- Pivot / attachment noktası: Silah, kapı veya aksesuarın bağlanacağı boş node mesh taşıması gerekmez; transform zinciri için yeterlidir (rig / skinning detayı ayrı konu).
- Sahne bölümü kökü: §4’teki «Environment» / «Characters» gibi çoklu kök dalların organizasyon başlığı.
Boş node, ağacın iç iskeletidir; görünür mesh yalnızca yapraklarda olabilir. Outliner’da «boş» görünen dal, dosyada en değerli organizasyon kayıtlarından biridir.
Aynı node hem taşır hem gruplar
Organizasyon ile içerik birbirini dışlamaz. Bir node aynı anda mesh
taşıyabilir ve children listeleyebilir örneğin gövde mesh’i üzerinde
kapı ve tekerlek alt node’ları. Node burada hem görünür parça hem alt
dalların ebeveynidir. Bu, «node ya grup ya mesh» ikilemi değildir; glTF kayıt
alanları birleştirilebilir. Hangi alanların bir arada kullanıldığı export aracına bağlıdır; spec her ikisine de izin verir.
İsteğe bağlı skin referansı da aynı mantıktadır: kemik ağı tanımı başka
tabloda, node yalnızca «bu varlık skin ile deforme edilir» der iskelet animasyonu bu
sayfanın dışındadır.
Katman tablosu ne nerede yaşar?
Dosya yapısı serisi ile sahne hattını tek bakışta hizalamak için:
| Katman | Soru | Node’un rolü |
|---|---|---|
buffers … accessors |
Veri nerede, nasıl okunur? | Dolaylı yalnızca mesh referansı üzerinden |
meshes / materials |
Geometri ve görünüm tanımı | mesh ile seçer; tanımı taşımaz |
cameras / ışık extension |
Kamera / ışık parametreleri | İndeks veya extension ile sahneye asar |
nodes |
Sahne ilişkisi, hiyerarşi | Organizasyon parent / child |
scenes |
Hangi kökler aktif? | Kök listesi; node ağacının giriş kapısı (§4) |
Tabloda «node’un rolü» sütunu hep aynı fiile döner: referans ver, bağ kur, grupla tanımı yeniden yazma. Aynı mesh tanımının birden fazla node’da kullanımı (§6) bu ilkenin doğal sonucudur: tanım bir kez, organizasyon kayıtları çok.
§1’den fark neden ayrı bölüm?
§1 «node nedir?» sorusuna yanıt verdi; dört olası yüz (mesh / kamera / ışık / boş grup) ve node ≠ mesh hatasını orada işledik. Bu bölüm aynı ayrımı organizasyon katmanı perspektifinden pekiştirir: glTF’de node, tanım tabloları ile sahne arasındaki zorunlu köprüdür veri olmadan sahne kurulamaz, node olmadan tanım tabloları sahneye oturmaz. Sonraki bölüm (§6) aynı ilkeyi «tek mesh, çok node» örneğiyle somutlaştırır.
Hiyerarşinin Faydaları
§2 node katmanının neden var olduğunu, §3–§6 ilişkinin ve paylaşımın dosyada nasıl göründüğünü kurdu. Bu bölüm üçüncü soruya geçer: hiyerarşi pratikte ne kazandırır? Node ağacı yalnızca «güzel diagram» değildir içerik üretimi, el değiştirme ve runtime’da sahneyi anlamak için somut mühendislik değeri taşır.
Organizasyon bin parça, tek outliner
Karmaşık bir varlık düz indeks listesi olarak okunmaz. Karakter sahnesinde silah, nişangâh, el kemiği, kıyafet parçaları onlarca mesh tanımına karşılık gelir; node ağacı bunları mantıksal dallara ayırır:
Character
├─ Body
├─ Weapon
│ └─ Scope
└─ Rig_Bones (boş grup §5)
«Scope hangi silaha ait?» sorusunun yanıtı parent zincirindedir harici tabloya gerek kalmaz. §2’de «node olmasaydı» listelediğimiz kayıp tam burada hissedilir: ilişki dosyanın içinde, standart biçimde durur. Outliner / sahne ağacı görünümü DCC’den runtime’a aynı mental modeli taşır (§2).
Tekrarlanabilir yapı pipeline ve prefab
§6’da «aynı mesh indeksi, çok node» veri paylaşımını gördük. Hiyerarşinin bir adım ötesi: tüm bir alt ağaç başka bir kökün altında yeniden kullanılabilir veya export sırasında kopyalanabilir sokak lambası seti, standart kapı montajı, tekrarlayan bina katı gibi. Asset pipeline’da «prefab» veya «instance group» dediğiniz yapı, glTF’de node dalları olarak dosyaya düşer.
Tekrar kullanım iki yüzeyde işe yarar: dosya boyutu (paylaşılan mesh / materyal §6) ve üretim hızı (sanatçı bir kez kurar, sahneye çok kez yerleştirir). Hiyerarşi, «bu blok bir bütün» bilgisini taşır; düz liste her parçayı bağımsız sandığında pipeline güncellemesi tüm sahneyi kırar.
Mantıksal gruplama hedeflenmiş hareket
«Sol kapı açık» animasyonu yalnızca kapı dalına uygulanmalıdır gövde, tekerlekler, iç mekân aynı kalsın. Parent–child ayrımı (§3) bu sınırı dosyada çizer:
Vehicle
├─ Body
├─ Wheels
└─ Doors
└─ Door_L ← animasyon hedefi
Animasyon kanalları ve rig detayı bu sayfada açılmaz; mesele şudur: hiyerarşi, hangi node’ların birlikte hareket etmesi gerektiğini önceden tanımlar. Motor veya editör bir dalı seçtiğinde altındaki tüm child’lar aynı «mantıksal birim» sayılır düz listede bu birim dosyada resmileşmez.
Sahne okunabilirliği isim + konum
glTF’de name alanı zorunlu değildir; pratik export’larda doldurulur.
Anlamlı isimler (FrontLeft_Wheel, MainCamera) yalnızca etiket
değildir hiyerarşi ile birlikte yol üretir: «Vehicle/Wheels/FrontLeft».
Geliştirici hata ayıklarken, sanatçı revizyon gönderirken veya QA «hangi parça yanlış
materyal?» diye sorarken indeks numarası yerine bu yolu okur.
JSON’da tam path string’i yoktur (§9 analojisi); indeks + isim birleşince sahne okunabilirliği artar. §8’deki minimal örnekte «Root → GroupA → MeshNode» zinciri aynı mantığın dosya okuma tarafıdır.
Transform aktarımı ilişkinin kinematik sonucu
Parent hareket ettiğinde child’ların birlikte hareket etmesi beklenir tekerlekler araba gövdesiyle, nişangâh silahla birlikte döner. Bu, parent–child ilişkisinin doğal sonucudur; nasıl birleşik matris veya TRS hesaplandığı Transform Verileri sayfasında kalır. Burada yalnızca şunu sabitleyin: hiyerarşi olmadan «birlikte hareket» kuralını dosyada ifade edecek standart yapı kalmaz; her parça bağımsız transform taşırdı, ilişki harici kodda tekrar kurulurdu.
glTF tanımlar, motor uygular
Frustum culling grupları, draw call batching, render sırası, LOD geçişleri bunlar hiyerarşinin runtime türevleridir. glTF dosyası «kim kime bağlı» bilgisini verir; Three.js, Unity veya özel motor bu ağacı nasıl traverse edeceğine, hangi dalı ne zaman çizeceğine kendi karar verir. Scene Graph optimizasyonu ayrı konudur; bu sayfa formatın organizasyon sözleşmesine odaklanır.
Özet: organizasyon, tekrar kullanım, hedeflenmiş gruplama, okunabilirlik ve transform mirası hepsi aynı parent–child ağacından türer. Sonraki bölüm (§8) aynı faydaların JSON tarafında nasıl okunacağını minimal bir örnekle gösterir.
Node ve Sahne Organizasyonu
JSON tarafında hiyerarşi iki tablo ile okunur JSON Structure sayfasına dönmeden, yalnızca node perspektifi:
{
"scene": 0,
"scenes": [{ "nodes": [0] }],
"nodes": [
{ "name": "Root", "children": [1, 2] },
{ "name": "GroupA", "children": [3] },
{ "name": "GroupB" },
{ "name": "MeshNode", "mesh": 0 }
]
}
scenes[0].nodes kökü işaret eder (0 → «Root»). «Root» çocukları
1 ve 2 listeler; «GroupA» bir alt seviye daha iner. «MeshNode»
yaprak (leaf) node’dur: çocuğu yok, mesh taşır. Node ilişkileri sahne
organizasyonunu tanımlar binary içeriğe dokunmaz.
Yaprak ve dal node’lar
Dal node: children dolu; gruplama veya boş pivot.
Yaprak node: çoğunlukla mesh / kamera / ışık taşır; çocuğu olmayabilir.
Ağaç derinliği sınırı yoktur; pratik export’larda onlarca seviye görülebilir (rig,
animasyon rig detayı bu sayfada yok).
Hiyerarşi Nasıl Düşünülmeli?
§8 hiyerarşiyi JSON’dan okumayı gösterdi: düz nodes dizisi, kökten
children indeksleriyle inen zincir. Dosyayı açınca bu okuma yeterlidir; zihinde tutmak için görsel bir iskelet gerekir. Bu bölüm o iskeleti kurar; spec
tekrarı değil, mental model bölümüdür.
Dosya sistemi — bu sefer gerçek ağaç
BufferView sayfası buffer hattını «disk / klasör / okuma kuralı» ile anlattı. Orada «klasör» metaforu düz ofset dilimlerini hatırlatmak içindi; iç içe alt klasör yoktu. Node hiyerarşisi için aynı kelimeleri kullanabilirsiniz, ama bu sefer gerçek bir ağaç vardır: parent altında child, child altında başka child; sahne tarafında.
Dosya sistemi (sahne metaforu) glTF node ağacı
────────────────────────────── ─────────────────
Projects/ Scene
Car/ Vehicle/
Parts/ Wheels/
wheel.bin ← dosya FrontLeft ← mesh taşıyan yaprak
Sol sütun depolama düzenini, sağ sütun sahne organizasyonunu temsil eder. İkisi aynı kelimeleri paylaşır; anlattıkları katman farklıdır; bu ayrım §10’da tablo halinde netleşir; burada yalnızca sahne imgelerini sabitleyin.
Üç eşleme: klasör, alt klasör, dosya
Klasör = parent node. Alt öğeleri gruplar; kendisi mesh taşımak zorunda değildir (§5 boş grup). «Vehicle» klasörü tekerlekleri ve gövdeyi bir arada tutar; tıpkı «Car» klasörünün alt parçaları toplaması gibi.
Alt klasör = child node (ara dal). Daha derin gruplama: «Wheels» altında
dört tekerlek, «Doors» altında kapılar. Her seviye bir «adım daha içeri» demektir; parent–child kuralı (§3) dosyada
children dizisiyle yazılır, zihinde klasör açılışı gibi okunur.
Dosya = yaprak node. Mesh, kamera veya ışık gibi «somut» yük taşır; altında başka node olmayabilir (§8). Klasör boş kalabilir; yaprak node ya mesh / kamera referansı taşır ya da bilinçli boş pivot anlamına gelir.
Path — JSON’da yok, traversal’da oluşur
«Vehicle/Wheels/FrontLeft» yolu diskin «Projects/Car/Parts» yoluna benzer; tam yol
(path) kavramı Scene Graph gezinmesinde ve hata ayıklamada işe yarar. glTF JSON’da böyle
bir string yoktur; yalnızca indeks + isteğe bağlı name vardır
(§7). Path, kökten yaprak
node’a inerken isimlerin birleştirilmesiyle runtime’da üretilir:
scenes[0].nodes → 0 (Root)
Root.children → 1 (Vehicle)
Vehicle.children → 4 (Wheels)
Wheels.children → 7 (FrontLeft)
→ path: "Root/Vehicle/Wheels/FrontLeft"
İndeksler dosyanın dilidir; path insanın dilidir. Loader veya editör genelde ikisini birden tutar indeks ile hızlı erişim, path ile okunabilirlik. §8’deki «Root → GroupA → MeshNode» zinciri aynı mantığın kısa bir örneğidir; burada odak path’in dosyada değil gezinme sırasında oluşmasıdır.
Outliner ile aynı resim
Blender, Maya veya Unity Hierarchy penceresinde gördüğünüz liste zaten bu metaforun canlı
halidir: üstte sahne kökü, girintili alt satırlar child’lar, en alttaki mesh satırları
dosyalar. glTF export’u outliner’ı düzleştirmez; nodes + children
olarak taşır (§2). Dosya sistemi
analojisi,
DCC deneyimi olmayan okuyucuya outliner’ın ne hissettirdiğini anlatmanın kısa yoludur.
BufferView metaforu ile karıştırmayın
İki metafor yan yana durabilir; aynı şeyi anlatmazlar:
- Buffer hattı: Tek disk, düz dilimler — hiyerarşi yok; «klasör» yalnızca ofset aralığını hatırlatır.
- Node hattı: Gerçek parent–child ağacı — hiyerarşi asıl konudur; «klasör» gerçekten alt öğe gruplar.
«BufferView #2’ye git» ile «Vehicle/Wheels/FrontLeft node’una git» farklı sorulara yanıt verir: ilki bayt dilimini, ikincisi sahne varlığını hedefler. Analoji, ebeveyn–çocuk ilişkisini hafızada tutmak içindir; bufferView’deki «düz ofset» metaforu ile karıştırılmamalıdır; orada hiyerarşi yoktu, burada hiyerarşi asıl konudur.
Analojinin sınırları
Metafor öğreticidir, bire bir spec değildir. Birkaç bilinçli sapma:
- Aynı dosya, birden fazla klasörde: Gerçek dosya sisteminde kopya veya sembolik bağ gerekir; glTF’de aynı mesh indeksini gösteren birden fazla yaprak node doğal biçimde mümkündür (§6) — «dosya» burada tanıma referanstır, fiziksel kopya değildir.
- Boş klasör: Geçerli ve sık pivot, rig kökü, ileride eklenecek parça yuvası (§5).
- Path garantisi yok:
nameeksik veya çakışan export’larda path insan okunur olmayabilir; indeks her zaman geçerlidir.
Son bölüm (§10) aynı «ağaç» kelimesinin veri tarafında farklı anlama geldiğini netleştirir buffer zinciri ile node zinciri paralel ama özdeş değildir.
Sahne Ağacı ≠ Veri Ağacı
§9 sahne hiyerarşisini zihinde tutmak için dosya sistemi metaforunu kurdu. Bu bölüm serinin bu sayfadaki en kritik ayrımını netleştirir: glTF’de «ağaç» kelimesi iki farklı katmanda geçer; biri bayt ve geometri tanımı, diğeri sahne organizasyonu. Karıştırmak, bufferView dilimini node parent’ı sanmak kadar yaygın bir hatadır.
Dosya yapısı hattında şimdiye kadar gördüğünüz:
buffer → bufferView → accessor → mesh (geometri tanımı)
Bu zincir veri organizasyonudur; bayt havuzu, dilim, okuma kuralı, üçgen listesi. Node hiyerarşisi ise:
scene → root node(s) → children → … → mesh referansı
Sahne organizasyonudur; kim kimin altında, sahneye hangi mesh örneği nerede duruyor. İki ağaç paraleldir; aynı değildir. Bir mesh tanımına on node bakabilir (§6); bir node yalnızca bir parent zincirine sahiptir.
İki ağaç, iki soru seti
Veri ağacı «modelin ham içeriği dosyada nasıl paketlenir?» der. Sahne ağacı «bu tanımlar sahneye nasıl oturur, hangi parça kime bağlı?» der. Loader ikisini de okur; ama sıra ve rol farklıdır: önce buffer / accessor ile geometri tanımları çözülür, sonra node hiyerarşisi hangi tanımın hangi sahne varlığına asılacağını söyler. Vertex pozisyonu accessor’da; «bu panel istasyonun sol koluna ait» bilgisi node’da.
Yan yana özet
| Veri ağacı (dosya yapısı) | Sahne ağacı (bu sayfa) |
|---|---|
| Buffer, bufferView, accessor | Node, children, scenes |
| «Bayt nerede, nasıl parse edilir?» | «Varlıklar birbirine nasıl bağlı?» |
| Ham / mantıksal geometri | Yerleşim, grup, örnek (instance) |
| GPU upload öncesi okuma hattı | Sahne graph iskeleti |
Tablo «node’un rolü» sütununu tekrarlamaz; o §5’te «referans ver, bağ kur, grupla» diye özetlenmişti. Burada mesele: aynı dosyada iki organizasyon dili vardır; biri binary/JSON veri hattı, diğeri sahne ilişkisi.
Köprü noktası: mesh kaydı
İki ağacın kesiştiği yer meshes tablosudur; ama kesişim «aynı nesne» demek
değildir. Veri tarafında mesh, primitive + attribute referanslarıdır; sahne tarafında node
yalnızca "mesh": i ile o tanıma işaret eder. Birden fazla node aynı mesh
indeksine bakabilir; buffer hattında geometri yine bir kez okunur. Sahne ağacı «kaç örnek
var, hangi dalda duruyor» sorusunu cevaplar; veri ağacı «o örneğin şekli baytlarda nasıl
yazılı» sorusunu.
§9 metaforu ile birlikte okuyun
BufferView «klasör» metaforunda hiyerarşi yoktu; düz ofset. Node «klasör» metaforunda gerçek parent–child vardır (§9). «Projects/Car/Parts» ile «Station/Core» aynı kelimeleri kullanır; birincisi veri dilimini, ikincisi sahne parçasını anlatır. Holodepth serisinde bu ayrım bilinçli tutulur: BufferView Scanner veri dilimini; aşağıdaki Node Explorer sahne ağacını gösterir.
Sıradaki doğal soru
Bu sayfayı bitirince aklınıza gelmesi gereken cümle: «Tamam, node’lar birbirine bağlı. Peki bir parent hareket edince child neden birlikte hareket ediyor?» Cevap transform katmanındadır; matrix, TRS, local / world space ayrımı Transform Verileri ve Scene Graph konularının işidir; burada yalnızca ilişkinin o soruyu sordurduğunu not ediyoruz.
Özet öz cümle: Buffer, bufferView ve accessor sistemleri model verisinin nasıl saklandığını açıklar; node hiyerarşisi bu verilerin sahnede nasıl organize edildiğini tanımlar. Sonraki sayfa (Scene Graph) bu iskeletin runtime’da nasıl gezildiğine geçer; bu sayfa dosyadaki statik ilişkiyi kapatır.
Demo · Node Explorer
Metin «node nedir, parent–child nasıl kurulur?» sorularını cevaplar; bu laboratuvar sahne parçası seçerek ilişkiyi hissettirir. BufferView Scanner’da değişen şey bayt dilimiydi; burada değişen seçili nodedur; ağaç, panel ve 3D model birlikte güncellenir. Animasyon veya transform hesabı yok; yalnızca statik hiyerarşi ve parent zinciri.
Modüler bir uzay istasyonu sahnesi: «Station» kök grup node’u altında
Core, halkalar, paneller ve anten yaprak node’ları durur. Soldan bir node seçin veya sağdaki
modele tıklayın; seçilen parça glow alır, ağaçta vurgulanır, orta panel
name, parent, children, depth ve
path gösterir. Parent zinciri hem panelde hem ağaçta (ancestor highlight)
okunur.
Bu demo, dosya yapısı serisinden sonra gelen ilk gerçek sahne organizasyonu laboratuvarıdır. Öğretmek istediği cümle: «Node, sahnedeki bir parçadır; parent–child ilişkileri node ağacını oluşturur.» Mesh / accessor detayı bilinçli dışarıda bırakıldı; odak ilişkidir.
Node seçin · cyan outline · parent beam · modüler silüet
Scene tree
Seçili node
3D model · parça vurgusu
Bu demo ne hissettirir? Node yalnızca JSON satırı değildir; sahnedeki parçadır. Seçilen modül cyan outline alır; parent «Station» ile arasında soft beam parent→child ilişkisini 3D’de gösterir. Çekirdek çok katmanlı, Ring A segmentli modüllü, Ring B kesikli iletişim halkası, paneller 3×4 hücreli, anten çanak silüetindedir; hiyerarşi aynı, silüet Tier 2. Kök «Station» seçildiğinde beam gizlenir; child listesi panelde okunur (§5).