holodepth

3D Model Formatları · glTF / GLB · Geometri Verileri

Vertex Data — glTF Yapısında Vertex Verisi Nedir?

Pivot & Origin sayfası vertex dağılımının node origin'e göre nasıl kodlandığını gösterdi. Bu sayfa geometri hattının başlangıcıdır: bir model aslında vertex bulutudur uzaydaki noktalar, accessor kurallarıyla okunur ve GPU'ya attribute olarak gider.

Sahne verileri hattında node, transform ve origin öğrenildi. Geometri verileri hattında soru değişir: «Şekil dosyada hangi ham veri olarak yaşar?» glTF cevabı: çoğunlukla POSITION accessor'ındaki koordinat listesi + (sonraki sayfada) index ile birleştirilmiş üçgenler. Bu sayfa vertex'in ne olduğunu, dosyada nerede durduğunu ve GPU yolculuğunun format katmanını anlatır sıkıştırma ve niceleme değil.

Sayfayı bitirdiğinizde şu cümleyi kurabilmelisiniz: «Mesh görsel bir cisim değil; vertex listesi + index listesidir. Vertex verisi mesh tablosunda değil, accessor üzerinden buffer'dan okunur.»

Bu sayfanın sınırı · Vertex Quantization ile ayrım

Bu sayfa yalnızca vertex verisinin ne olduğu ve nerede yaşadığı sorusunu cevaplar. Bilinçli olarak dışarıda bırakılan konular:

  • Float → integer niceleme, bit derinliği, quantization grid
  • Dosya boyutu küçültme, Draco, Meshopt compression
  • Runtime decode / decompress pipeline detayı
  • Shader kodu, VBO upload API'si, WebGL buffer binding

Bu konuların runtime / sıkıştırma karşılığı Three.js · Vertex Quantization sayfasında ele alınır. Kısa tanım: Vertex Data (Format) «vertex nedir, nerede saklanır?» · Vertex Quantization «vertex verisini daha az byte ile nasıl saklarız?»

Vertex Nedir?

Vertex (köşe noktası), üç boyutlu uzayda bir konumdur glTF'de neredeyse her zaman (x, y, z) float üçlüsü olarak saklanır. Günlük dilde «köşe» kelimesi küpün sekiz köşesini çağrıştırır; format okuyucusu için vertex daha genel bir terimdir: mesh'in taşıdığı herhangi bir konum kaydı silindirin taban halkasındaki nokta, karakterin el bileği, zemin dörtgeninin bir köşesi hepsi aynı kategoridedir. Tek başına bir vertex «küp», «karakter» veya «zemin» değildir; yalnızca uzaydaki bir noktadır.

Bu ayrım sahne hattından geometri hattına geçişin özüdür. Önceki sayfalarda node, transform ve origin ile «cisim sahneye nereden asılıyor?» sorusunu çözdünüz. Vertex Data'da soru değişir: «Asılan şekil dosyada ne olarak yazılmış?» glTF'nin kısa cevabı: çoğunlukla iki ayrı tablo vertex listesi ve index listesi.

  • Vertex listesi mesh yerel uzayındaki koordinatlar; dosyada POSITION accessor'ı üzerinden okunur (§2'de zincir detaylandırılır)
  • Index listesi hangi vertex'lerin birlikte üçgen yüzey oluşturduğu; Index Buffer sayfasında ele alınır bu bölümde yalnızca «bağlantı katmanı ayrıdır» fikri yeterli

İki katman birlikte düşünülmezse mesh «sihirli bir cisim bloğu» gibi görünür. Oysa format dilinde mesh, attribute tablolarının birleşimidir en azından POSITION zorunludur; normal, UV ve diğer alanlar aynı vertex sırasına paralel satırlar ekler (§3). Şekil hissi ise vertex listesinden tek başına gelmez; noktaların hangi sırayla üçgene bağlandığı ikinci katmandan gelir.

Dört nokta örneği henüz yüzey yok

Yere paralel bir dörtgenin köşelerini düşünün. Dosyada önce yalnızca koordinatlar vardır; «dörtgen» veya «zemin» diye ayrı bir kayıt yoktur:

V0 = (-1, 0,  1)
V1 = ( 1, 0,  1)
V2 = ( 1, 0, -1)
V3 = (-1, 0, -1)

Bu dört satır yalnızca şunu söyler: mesh yerel uzayında dört nokta var. Hepsi y = 0 düzleminde; V0 ile V2 köşegen karşılıklıdır. Henüz hangi noktaların birleşeceği yazılmamıştır ekranda bir yüzey çizmek için GPU'nun «şu üç noktayı bir üçgen say» demesi gerekir. §4'te (V0, V1, V2) tek üçgen örneği gösterilir; dört köşenin tamamı için genelde iki üçgen gerekir.

  V0 ───────── V1        ← yalnızca noktalar (vertex listesi)
   ·            ·
   ·            ·
   ·            ·
  V3 ───────── V2

  Henüz çizgi veya yüzey yok  bağlantı index katmanında tanımlanır.

Gördüğünüz şey vs dosyada saklanan

Viewer'da «Core silindiri» veya «Solar Panel» görürsünüz; glTF dosyasında ise önce nodes kaydı, ardından meshes ve içindeki primitives gelir. Görsel bütünlük runtime birleşiminden doğar; ham geometri katmanında ise parçalar ayrık veri tablolarıdır. Yeni başlayanların sık yaptığı hata: mesh'i tek monolitik cisim sanmak «bu mesh kaydı = ekrandaki panel» diye düşünmek. Doğru okuma: mesh kaydı = şekil tarifinin metadata'sı + accessor referansları.

Görsel algı ile format katmanı (özet)
Gözle görülen Dosyada aslında
«Bir zemin dörtgeni» 4 satır POSITION + (genelde) 6 index veya 6 tekrarlı vertex
«Küp» 8 benzersiz köşe veya 36 index'li üçgen listesi (paylaşımlı köşe modeline bağlı)
«Karakter mesh'i» Binlerce vertex satırı + index buffer + isteğe bağlı NORMAL, TEXCOORD, …

Tablo sayıları öğretim amaçlıdır; asıl mesele şudur: model görsel bir bütün olarak hissedilir, dosyada ise önce nokta bulutu, sonra bağlantı kuralı yaşar. Float hassasiyeti, byte sıkıştırma veya Draco bu tabloya girmez onlar «aynı noktalar daha az byte ile nasıl yazılır?» sorusuna aittir (Vertex Quantization).

Model = vertex bulutu

Node hiyerarşisi «kim kimin child'ı?» sorusunu; Transform verileri «node nerede, hangi yönde, hangi boyutta?» sorusunu; Pivot & Origin «origin ile vertex ofseti dosyada nasıl kodlanır?» sorusunu cevapladı. Vertex Data'da artık geometrinin kendisine iniyoruz:

Sahne graph'ı kurulduktan sonra ekranda gördüğünüz yüzey, aslında binlerce vertex noktasının doğru bağlanmasıdır önce bulut, sonra üçgen ağı.

«Vertex bulutu» ifadesi şiirsel değil, okuma disiplinidir: bir GLB açtığınızda ilk bakışta gördüğünüz şey nodes ağacıdır; asıl şekil verisi ise buffers içindeki byte yığınından accessor kurallarıyla çözülen nokta listesidir. Node transform'u bu bulutu sahneye taşır; pivot/origin dersinden hatırlayın POSITION koordinatları mesh yerel uzayındadır, world konumu node matrix ile sonra gelir. Bu sayfada matrix hesabı yok; format okuyucusu olarak vertex = mesh yerel uzayındaki ham konum demek yeterli.

Vertex, mesh, model terim ayrımı

Holodepth geometri hattında terimleri şöyle ayırırız:

  • Vertex tek bir konum kaydı (POSITION satırı)
  • Mesh aynı primitive içinde paylaşılan attribute tabloları (en az POSITION; index ile birlikte «şekil tarifi»)
  • Model (günlük dil) genelde node + mesh + materyal birleşimi; dosyada tek bir «model» anahtarı yoktur, sahne parçalarının toplamıdır

Viewer'da «model yüklendi» dersiniz; glTF spesifikasyonunda «model» diye bir kök tip tanımlanmaz. Export aracı «Export glTF» der; içeride meshes, accessors, nodes vardır. Vertex Data sayfasının odak cümlesi: «Mesh = vertex listesi (+ index listesi); görünür cisim = node transform × bu listeler.» Sonraki bölümde vertex listesinin dosyada tam olarak nerede yaşadığını POSITION accessor zincirini adım adım göstereceğiz.

POSITION Accessor Vertex Nerede Yaşar?

Vertex koordinatları mesh JSON kaydının içinde düz metin listesi olarak durmaz. glTF zinciri:

Node
 ↓  (mesh referansı)
Mesh
 ↓  (primitives)
Primitive
 ↓  (attributes)
POSITION → accessor index

İlk kez pratik JSON'da şu yapı görülür:

{
  "nodes": [{ "name": "Ground", "mesh": 0 }],
  "meshes": [{
    "name": "GroundMesh",
    "primitives": [{
      "attributes": {
        "POSITION": 0
      }
    }]
  }],
  "accessors": [{
    "bufferView": 0,
    "componentType": 5126,
    "count": 4,
    "type": "VEC3",
    "min": [-1, 0, -1],
    "max": [1, 0, 1]
  }]
}

Kritik cümle: vertex verisi mesh içinde değil, accessor içinde saklanır. Mesh yalnızca «POSITION için 0 numaralı accessor'ı kullan» der. Ham float byte'ları buffersbufferViews hattında durur (Binary Buffers, BufferView). Accessor mantığı sayfasında öğrendiğiniz kurallar (componentType, type, count) burada POSITION anlamına gelir.

Node transform vs POSITION

Node'un TRS'i tüm mesh'i sahneye taşır; POSITION vertexleri mesh yerel uzayında tanımlar. İkisi çarpılır fakat bu sayfada world matrix hesabı yok. Format okuyucusu olarak ayrı tablolarda tutulduğunu bilmek yeterli.

Vertex Başına Hangi Bilgiler Var?

glTF primitive attributes haritası, vertex başına taşınabilecek semantic alanları listeler. Bu sayfa yalnızca tanıtım yapar her biri ilerideki geometri sayfasında derinleşir:

glTF vertex attribute semantic'leri (özet)
Semantic Ne taşır? Holodepth sayfası
POSITION Konum (x, y, z) Bu sayfa
NORMAL Yüzey yönü Normal Verileri
TANGENT Teğet (normal map için) Tangent Verileri
TEXCOORD_0 UV koordinatı UV Kanalları
COLOR_0 Vertex rengi — (ileride)
JOINTS_0 / WEIGHTS_0 Kemik skinning Animasyon hattı

Tüm attribute'lar aynı count vertex sayısına sahip olmalıdır (primitive başına). POSITION olmadan primitive geçersizdir; diğerleri isteğe bağlıdır. Vertex Data sayfasının odak noktası POSITION'dır «şeklin iskeleti» budur.

Vertex → Üçgen

§1'de dört köşe koordinatı yazdık; ekranda hâlâ yalnızca nokta bulutu vardı. Render pipeline'ına geçildiğinde birim değişir: GPU ve glTF, görünür yüzeyi üçgen listesi olarak işler. Kısa ayrım:

  • Vertex = uzaydaki tek bir nokta (POSITION satırı)
  • Triangle = üç vertex'in seçilip bir yüzey parçası sayılması

Nokta tek başına çizilebilir (debug modunda); sahne geometrisi için yeterli değildir. Dört nokta bile «dörtgen» oluşturmaz hangi üçlünün yüzey sayılacağı ayrıca tanımlanmalıdır. Bu yüzden vertex listesi ile «hangi vertex'ler birleşir?» sorusunun cevabı format dilinde ayrı katmanlardır.

Neden üçgen?

Her düzlem yüzey en az üç noktayla tanımlanır; GPU rasterizer'ı da temel primitive olarak üçgen kullanır (dörtgen veya beşgen doğrudan rasterize edilmez önce üçgene bölünür). glTF mesh.primitives bu kurala uyar: görünür şekil, üçlüler halinde okunan vertex gruplarıdır. Shader derinliği bu sayfada yok; format okuyucusu için yeterli cümle: «Dosyada saklanan noktalar, render öncesi üçgenlere bağlanır.»

Tek üçgen Triangle 0

§1'deki zemin köşelerinden üçünü seçelim. Demo'daki Triangle 0 modu şu üçlüyü kullanır koordinatlar mesh yerel uzayındadır:

V0 = (-1, 0,  1)    ← sol üst köşe
V1 = ( 1, 0,  1)    ← sağ üst köşe
V2 = ( 1, 0, -1)    ← sağ alt köşe

Triangle 0 = (V0, V1, V2)

Üstten bakışta V0 ile V1 aynı z = 1 kenarında; V2 sağ alt köşededir. Üç nokta bir düzlemde olduğu için tek bir üçgen yüzey tanımlanır:

V0 ───────────────────────── V1
 ╲                            │
  ╲                           │  ← V1→V2 (aynı x = +1)
   ╲                          │
    ╲                         V2

Triangle 0 = (V0, V1, V2)   · üst kenar: V0→V1   · sağ kenar: V1→V2   · köşegen: V2→V0

Şema üstten bakıştır: V0 sol üstte (x = -1), V1 sağ üstte (x = +1) aralarındaki üst kenar geniş çizilir ki V1 gerçekten sağda dursun. V2, V1'in altındadır (x aynı, z derinleşir); önceki kısa şemada üst kenar dar olduğu için V1 kaymış ve V2 ortada gibi görünüyordu.

Sıra önemlidir winding

Aynı üç vertex farklı sırayla yazılırsa farklı yüzey yönü (front / back face) ortaya çıkar: (V0, V1, V2) ile (V0, V2, V1) aynı üçgenin ters yüzüdür. glTF primitive'lerinde material.doubleSided ve culling kuralları bu ayrımı etkiler; index buffer'daki üçlü sırası bu yüzden salt «hangi noktalar» değil, hangi sırada sorusudur. Detay Index Buffer sayfasında; burada yalnızca «üçlü sırası anlamlıdır» notu yeterli.

Dört köşe → iki üçgen

Dört vertex'li zemin örneğinde tek üçgen yeterli değildir dörtgenin tamamını kaplamak için düzlem en az iki üçgene bölünür. Demo'daki Quad Split modu tipik bölümü gösterir:

Triangle 0 = (V0, V1, V2)
Triangle 1 = (V0, V2, V3)

V0 ───────────────────────── V1
 │ ╲  T0                    │
 │   ╲                      │
 │    ╲  T1                 │
 V3 ───────────────────────── V2
      (köşegen: V0 → V2)

Hangi vertex'lerin hangi üçgende yer aldığı index buffer ile saklanır (veya non-indexed yolda POSITION listesi üçlüler halinde tekrarlanır). Bu sayfada index byte düzeni, componentType veya paylaşımlı vertex optimizasyonuna girilmez yalnızca kavramsal köprü: §1'deki nokta bulutu, burada üçgen ağına dönüşür; bağlantı kuralları bir sonraki sayfanın konusudur.

Non-indexed alternatif

Bazı primitive'ler indices accessor'ı taşımaz; POSITION listesi doğrudan üçlüler halinde okunur listedeki her 3 vertex = 1 üçgen. Örneğin 6 vertex satırı = 2 üçgen. Dezavantaj: köşe paylaşımı yoksa aynı konum birden fazla satırda tekrarlanır; avantaj: index tablosu gerekmez. Index'li ve index'siz yollar, winding ve mode alanı Index Buffer sayfasında karşılaştırılır.

Vertex Data açısından hatırlanacak tek cümle: noktalar ayrı katman, bağlantı ayrı katman üçgen, ikisinin birleşimidir.

GPU'ya Yolculuk Format Birleşim Noktası

Dosya yapısı hattında parçaları ayrı ayrı öğrendiniz: Binary Buffers «ham byte nerede?», BufferView «o byte yığınının hangi dilimi?», Accessor «o dilim hangi tipte okunur?» sorularını cevapladı. Geometri hattında ise §1–§4 «vertex nedir, üçgene nasıl bağlanır?» sorusunu işledi. Vertex Data'nın bu bölümü, iki hattın kesişim noktasıdır: artık soyut «byte» değil, somut bir POSITION koordinatının dosyadan GPU'ya nasıl ulaştığını tarif ediyoruz.

Zinciri iki yönden okuyabilirsiniz ikisi de aynı gerçeği tarif eder:

  • Yukarıdan aşağı (sahne okuyucusu): nodes → mesh → primitive → POSITION: 0 → accessor → bufferView → buffer
  • Aşağıdan yukarı (binary okuyucusu): buffer byte'ı → bufferView dilimi → accessor kuralı → «bu 4 satır VEC3 float» → mesh attribute haritası

Holodepth'te format okumayı «tek yönlü sıra» sanmayın; debug sırasında genelde yukarıdan başlarsınız («Ground node'unun mesh'i nerede?»), bozuk geometri görünce aşağı inersiniz («accessor count ile bufferView byteLength uyuyor mu?»).

Tam zincir format birleşimi

glTF JSON (mesh.primitives.attributes.POSITION → 0)
        ↓
Accessor  (type: VEC3, componentType: FLOAT, count: N)
        ↓
BufferView (byte aralığı, stride, offset)
        ↓
Buffer    (GLB içinde gömülü veya harici .bin)
        ↓
Loader decode  (byte → typed array)
        ↓
GPU vertex attribute slot  (semantic: POSITION)
        ↓
Vertex Shader  (konum girdisi  hesap bu sayfada yok)

§2'de gördüğünüz "POSITION": 0 satırı zincirin giriş kapısıdır mesh «konum verisi için 0 numaralı accessor'ı kullan» der. Asıl koordinatlar accessor'ın işaret ettiği bufferView dilimindeki float üçlülerdir. Index buffer (§4) aynı hiyerarşide paralel bir yol izler: indices accessor'ı → bufferView → buffer; POSITION ile aynı buffer'ı paylaşabilir veya ayrı tutulabilir bu sayfada index byte düzenine girilmez.

Her katman ne bilir, ne bilmez?

Kesişim noktasını anlamanın en sağlam yolu «sorumluluk sınırı» tablosudur. Aynı veri farklı katmanlarda farklı isimlerle anılır; karışıklık buradan gelir.

POSITION yolculuğunda katman sorumlulukları
Katman Bilir Bilmez Holodepth sayfası
buffers Toplam byte, URI / GLB chunk VEC3 mü, index mi, kaç vertex? Binary Buffers
bufferViews Byte offset, length, stride Semantic (POSITION / NORMAL) BufferView
accessors type, componentType, count, min/max Node transform, materyal rengi Accessor
mesh.primitives.attributes Semantic → accessor eşlemesi Byte düzeni, stride hesabı Bu sayfa · §2
Loader Zinciri çözüp runtime yapıya taşır Shader, ışık, animasyon kararı — (runtime kanalı)
Vertex shader girdisi «Bu slot konum verisi» glTF accessor index'i ByteOmi · shader

Buffer «byte yığını» bilmez; accessor «POSITION = VEC3 float, count = 4» kuralını uygular; mesh tablosu «hangi semantic hangi accessor?» haritasını tutar. Accessor Lens demosu aynı byte'ın yanlış kural ile okununca geometrinin nasıl bozulduğunu gösterir vertex verisi «sihirli» değil, kural zincirine bağlıdır.

Loader köprü, format değil

glTF spesifikasyonu loader'ı tanımlamaz; dosya yapısı JSON + buffer kurallarını yazar. Uygulama tarafında loader (ör. three.js GLTFLoader) şunu yapar: GLB chunk'ını veya harici .bin dosyasını okur, accessor kurallarına göre float dizisine çevirir, GPU'ya yüklenecek attribute buffer'ını hazırlar. Bu adım format okuması ile runtime arasındaki köprüdür WebGL bufferData çağrısı, VAO binding ve draw call detayı Three.js kanalındadır; burada yalnızca «byte çözüldü, POSITION slot'una kondu» seviyesinde kalıyoruz.

Sıkıştırılmış buffer (Draco, Meshopt) bu zincire decode adımı ekler fakat çıktı yine aynıdır: çözülmüş POSITION float üçlüleri. Niceleme ve sıkıştırma Vertex Quantization sayfasının konusudur; bu bölüm varsayılan «açık float VEC3» yolunu tarif eder.

Sahne verisi nerede devreye girer?

POSITION vertex shader'a mesh yerel uzayında girer. Node'un TRS veya matrix değeri Transform verileri sayfasından hatırlayın genelde vertex shader veya sonrasındaki matrix çarpımında uygulanır; dosyada ayrı tablolarda durur. Format okuyucusu için kritik ayrım:

POSITION accessor = şeklin yerel koordinatları · Node transform = şekli sahneye taşıyan çerçeve. İkisi birleşmeden «Ground nerede duruyor?» sorusunun cevabı tamamlanmaz.

Pivot/origin dersinden de: vertex ofseti POSITION'dadır, origin hissi node + POSITION birleşiminden doğar. Bu bölümde matrix çarpımı yok; yalnızca zincirin format tarafındaki son durağını işaret ediyoruz: GPU'ya giden ilk anlamlı geometri girdisi.

Shader derinliği bu sayfada yok

Vertex shader'ın gl_Position hesabı, MVP matrix çarpımı, normal transform ve lighting ByteOmi / Three.js shader kanallarındadır. Format sayfasında durma noktası net:

GPU'ya giden POSITION attribute'un dosyada nereden geldiğini tarif edebilmek.

Aşağıdaki Vertex Field Lab demosu bu zincirin görsel özetini sunar mod düğmeleri §1 ve §4'teki nokta/üçgen kavramlarını 3D'de gösterir; sol paneldeki akış şeması ise yukarıdaki tablonun kısaltılmış halidir. Metin burada durur; etkileşimli panel tekrar anlatılmaz.

Demo · Vertex Field Lab

Yukarıdaki bölümler vertex verisini metin ve şema ile anlattı; bu laboratuvar aynı dört köşeyi (V0–V3) tek sahne üzerinde adım adım gösterir. Amaç teoriyi tekrar etmek değil «dosyada nokta listesi varken ekranda neden henüz zemin yok?» sorusunu mod değiştirerek hissettirmek. Sadece POSITION vardır; sıkıştırma, Draco veya quantization yok.

Nasıl kullanılır? Sol listedeki bir satıra veya 3D küreye hover yapın renk kodu eşleşir, etiket parlar. Üstteki üç mod, aynı koordinatların farklı okuma katmanını gösterir; sağdaki GPU akışı seçili modda hangi adımların «yanıp söndüğünü» özetler (tam zincir §5).

Üç mod neyi gösterir?

  • Vertex Cloud Yalnızca dört nokta; şekil yok. Veri panelinde POSITION · 4 vertex satırı ile eşleşir.
  • Triangle Assembly V0·V1·V2 seçilir, tek yüzey belirir. V3 listede durur ama bu üçgende yok «vertex listesi ≠ her vertex her yüzeyde» ayrımı.
  • Quad Split Dörtgen iki üçgene bölünür; pembe köşegen V0→V2 split çizgisidir. Index teaser [0,1,2] ve [0,2,3] sonraki Index Buffer sayfasına kısa önizlemedir.
Demo · Vertex Field · POSITION

Hover ile V0–V3 eşle · moda göre GPU zinciri · Index teaser

Görünüm modu

Veri paneli · POSITION

Koordinatlar · V0–V3

    Primitive attribute

    POSITION VEC3 · FLOAT · 4 vertex

    GPU yolculuğu

    3D · vertex → triangle

    Bu demo ne hissettirir? Vertex Cloud: koordinatlar var, yüzey yok. Triangle Assembly: üç nokta birleşince tek primitive. Quad Split: aynı dört köşe + index üçlüleri = iki triangle köşegen çizgisi «quad aslında iki üçgen» cümlesinin görsel karşılığıdır. Sol panel yalnızca bu sayfanın konusu olan POSITION strip'ini gösterir; NORMAL ve UV burada bilinçli olarak yok (§3 metinde tanıtıldı). Demo bittiğinde şu cümleyi kurabilmelisiniz: «POSITION noktaları taşır; hangi noktaların yüzey olduğu ayrı katmandır.»