holodepth

Three.js · Geometri

Primitive geometriler (hazır formlar)

Parametre ver; BufferGeometry çıksın

Three.js, en sık kullanılan geometrik formları tek tek denklem yazmadan üretmeniz için primitive (ilkel) sınıflar sunar. BoxGeometry, SphereGeometry, PlaneGeometry gibi yapıcılar, arka planda vertex ve üçgen listesini hesaplayıp sonucu BufferGeometry olarak verir; siz yalnızca boyut, segment ve şekle özel birkaç sayı seçersiniz; prototipte hız, öğrenmede netlik sağlar.

Bu sayfa hangi primitiv ne işe yarar ve segment / parametre seçiminin görünüm ile GPU yükünü nasıl birlikte belirlediği üzerinedir. Vertex, yüzey ve BufferGeometry dilinin genel çerçevesi Geometri giriş sayfasındadır; attribute tamponları ve indeks ayrıntısı Attributes & buffers konusuna bırakılır; burada tekrar etmiyoruz.

Primitiv ürettikten sonra sahneye Mesh ile koyarsınız; konum ve hiyerarşi Object3D & sahne sayfasının konusudur. Aşağıdaki demolar segment farkını, parametre kaydırıcılarını ve çoklu küre yükünü canlı gösterir; sabitler ve kod kesitleri her blokta diagram-primitive-geometri.js ile eşleşir.

Primitivlerin mantığı: parametrik modelleme

Bir primitiv oluştururken yalnızca “küp mü küre mü” demezsiniz; o şeklin çözünürlüğünü ve boyutlarını da seçersiniz. Three.js bu ikisini ayrı parametre gruplarında tutar: biri dünya uzayında “ne kadar büyük” ( width, radius …), diğeri yüzeyi kaç parçaya böldüğünüz ( widthSegments, radialSegments …). İkinci grup, görünür segment sayısıdır; yüzeyi oluşturan üçgenlerin yoğunluğu buradan gelir.

Segment: pürüzlülük ile maliyet

Segment arttıkça eğri yüzeyler (küre, silindir, halka) daha pürüzsüz görünür; fakat vertex ve üçgen sayısı; dolayısıyla GPU yükü; genelde hızla büyür. Düz yüzeyli primitivlerde ( kutu, düzlem) segment çoğu zaman 1 kalır; yüzey zaten düzdür, ek bölme görsel kazanç vermez, yalnızca üçgen sayısını şişirir. Düzlemde segmenti bilinçli yükseltmek istisnadır: dalga, yükseklik haritası veya vertex animasyonu için ızgara gerekir; düzlem dalga demo bunun örneğidir.

Aynı sınıfta segmenti iki katına çıkarmak, üçgen sayısını kabaca dört katına yaklaştırabilir (özellikle küre gibi iki eksende bölünen yüzeylerde). Bu yüzden “her yerde 64 segment” alışkanlığı mobil ve VR’da triangle bütçesini hızla doldurur. Genel segment–performans çerçevesi Geometri giriş sayfasında özetlenir; burada segment karşılaştırma demo ile aynı kürede düşük / orta / yüksek yoğunluğu yan yana görürsünüz.

Parametrik modelleme ne demek?

Parametrik modelleme, hazır bir şekil sınıfına sayı verip kütüphanenin vertex ve üçgen listesini sizin yerinize üretmesidir; tek tek koordinat yazmazsınız. Öğrenme ve prototipte hızlıdır: ışık, kamera ve materyal denemelerini glTF içe aktarmadan yürütebilirsiniz. Üretim sahnesinde ise çoğu zaman Blender veya DCC’den gelen özel mesh tercih edilir; primitivler yine de zemin, blok, placeholder küre veya debug hacmi olarak kalır.

Pratikte her primitiv için üç soru yeterlidir:

  • Şekil türü: Düz hacim mi, küresel mi, halka mı — sınıf seçimi ( BoxGeometry, SphereGeometry, TorusGeometry …) silüeti belirler. Yanlış sınıfı yüksek segmentle “düzeltmek” pahalıdır; doğru sınıf + düşük segment çoğu zaman daha iyidir. Ayrıntılı tür listesi aşağıdaki bölümde.
  • Boyutlar: width, height, depth, radius, tube gibi değerler dünya biriminde ölçeği verir. Sahne genelinde “1 birim = 1 metre” gibi sabit bir iç kural tutmak, kamera ve fizik motoru ile uyumu kolaylaştırır.
  • Segment bütçesi: Kameraya yakın ve ekranda büyük görünen nesnede segment artırılır; uzak zemin, küçük prop veya arka plan için düşük segment çoğu zaman yeterlidir. Mesafeye göre farklı çözünürlük için LOD notuna bakın.

Parametre değişince ne olur?

Constructor çalıştığı anda geometri üretilir; kaydırıcı veya UI ile boyut/segment değiştirdiğinizde mevcut tamponu güncellemek yetmez; yeni SomeGeometry(...) oluşturup eskisini dispose() etmeniz gerekir. Aksi halde GPU belleği sızıntıya gider. Oluşan veri her zaman BufferGeometry olarak çizilir; attribute adları ( position, normal, uv) ve indeks yapısı Attributes & buffers konusunda açılır; burada yalnızca “primitiv seçimi = tampon boyutu” ilişkisini vurguluyoruz. Parametrik tür demo ve kod kesitleri bu yeniden oluşturma döngüsünü canlı gösterir.

Temel geometrik formlar

Aşağıdaki sınıflar sahne kurarken en sık karşılaşılan “yapı taşları”dır. Hepsi aynı kalıbı izler: geometriyi üretin, bir Material ile Mesh yapın, sahneye ekleyin. Şekil ve çözünürlük geometride; renk, doku ve ışık tepkisi materyalde kalır; bu ayrım, hangi parametrenin nerede aranacağını netleştirir.

Her başlıkta boyut (ne kadar büyük) ile segment (ne kadar ince ağ) ayrı düşünülür; segment mantığının genel özeti önceki bölümde. Parametre adlarının tam listesi teknik tabloda; kaydırıcı ile canlı deneme parametrik demoda yapılır.

BoxGeometry — küp ve prizma

Düz yüzeyli nesnelerin temelidir; width, height, depth ile dikdörtgen prizma tanımlanır. Merkez varsayılan olarak geometrinin ortasındadır; zemin “tabanı” yere oturtmak için position.y ile yarım height kaydırmak yaygındır. İsteğe bağlı widthSegments, heightSegments, depthSegments yüz başına ızgara böler; vertex animasyonu veya ızgara tabanlı efektler için kullanılır.

  • Kullanım: Duvarlar, kutular, zemin blokları, basit mimari hacimler ve “kutu dünya” prototipleri — çoğu gri kutulu sahnenin omurgası budur.
  • Segment: Sadece düz bir kutu gerekiyorsa segment sayılarını varsayılan (1) bırakmak en ekonomiktir; yüzey zaten düzdür, ek bölme yalnızca üçgen sayısını artırır.
  • Kutu vs silindir: Yuvarlak profil gerekiyorsa yüksek segmentli kutu yerine CylinderGeometry seçmek hem daha az üçgen hem daha doğru silüet verir.

SphereGeometry — küre

Tek radius ile boyut verilir; widthSegments ve heightSegments küresel ağın sıklığını belirler; eğri silüet tamamen bu ikisinden gelir. Küre, segment–performans dengesinin en görünür örneğidir: aynı yarıçapta segment iki katına çıkınca üçgen sayısı kabaca dört katına yaklaşabilir.

  • Kullanım: Gezegenler, toplar, parçacık kümeleri, ışık hacmi veya çarpışma için basit yer tutucu küreler.
  • Maliyet: Segment çok yükselirse üçgen sayısı ciddi artar; uzak veya ekranda küçük nesnelerde 8–16 segment çoğu zaman yeterlidir — segment demo düşük / orta / yüksek farkını yan yana gösterir.
  • Çoklu küre: Yüzlerce küre aynı sahnede ise segment tek tek değil, toplam triangle bütçesi düşünülür — çoklu küre demo bu yükü hissettirir.

PlaneGeometry — düzlem

İki boyutlu, varsayılan olarak tek taraflı bir yüzdür; width ve height ile boyutlanır; isteğe bağlı widthSegments / heightSegments ızgarası alır. Varsayılan yönelim XY düzlemindedir; yatay zemin için mesh’i genelde X ekseni etrafında -Math.PI / 2 döndürürsünüz. Statik zeminlerde segment 1 yeterlidir; dalga veya yükseklik animasyonu için ızgara bilinçli yükseltilir.

  • Kullanım: Zeminler, duvarlar, UI panelleri, su yüzeyi tabanı, tam ekran arka plan quad’ı — ince bir “levha” olarak düşünün.
  • Yönlendirme: Tek taraflı görünür; kamera yüzeyin arkasındaysa mesh kaybolur. Arka yüzü de göstermek için materyalde
    side: THREE.DoubleSide gerekir (gölge ve ışık maliyeti artabilir).
  • Segment istisnası: Düzlem, §1’deki “segment çoğu zaman 1” kuralının bilinçli istisnasıdır — vertex’leri oynatmak için ızgara şarttır; düzlem dalga demo örnektir.

TorusGeometry — simit / halka

radius ana halkanın merkez çizgisinden boru merkezine uzaklığı, tube borunun kalınlığını verir. radialSegments boru kesitindeki pürüzlülük, tubularSegments halka boyunca uzanan pürüzlülüktür; ikisi de görünür yuvarlaklığı etkiler.

  • Kullanım: Halkalar, lastik profili, portal çerçevesi, dekoratif soyut formlar; “delik” hissi veren nesnelerde kutu yerine tercih edilir.
  • İpucu: İnce tube + düşük tubularSegments köşeli, çokgen bir halka verir; yakın çekimde tubular segmenti artırın, uzaktaki halkada düşük tutun.
  • Performans: Hem radial hem tubular segment çarpılır; küçük dekoratif halkada segmentleri kısıtlamak triangle bütçesini korur.

CylinderGeometry ve ConeGeometry

CylinderGeometry silindir ve koni gövdesini tek sınıfta üretir: radiusTop, radiusBottom, height, radialSegments; üst ve alt tabanlar openEnded ile açılıp kapatılabilir. ConeGeometry pratikte “üst yarıçapı 0 olan silindir” gibidir; tek radius + height ile koni tanımlanır. Kapaklar kapalıyken ek üçgenler gelir; içi boş boru veya huni için açık uç tercih edilir.

  • Kullanım: Sütunlar, fıçılar, kule gövdeleri, koni ışık huzmeleri, yönlü spot ışığının görsel hacmi.
  • Performans: radialSegments taban çemberinin çözünürlüğüdür; yan yüzey düz olsa da silüet yuvarlaklığı buradan gelir. heightSegments gövde boyunca bölme ekler — statik sütunda 1, bükülen gövdede daha fazla gerekebilir.
  • Tablo: Kritik parametreler ve performans notları aşağıdaki tabloda özetlenir; silindir ve koni satırları karşılaştırmalı okunabilir.

Özet: düz hacim → kutu, küresel kütle → küre, ince levha → düzlem, delik / halka → torus, yuvarlak gövde → silindir veya koni. Yanlış sınıfı yüksek segmentle düzeltmek yerine doğru primitivi düşük segmentle seçmek hem daha hızlı hem daha okunaklı sahneler üretir.

Etkileşimli demo: segment farkı (düşük / orta / yüksek)

Aynı küre tipinde üç örnek yan yana: sol düşük segment (köşeli silüet), orta taban değer, sağ yüksek segment (pürüzsüz eğri). Ortadaki kaydırıcı taban segmenti değiştirir; sol ve sağ örnekler ona göre ölçeklenir. Wireframe açıkken üçgen yoğunluğunu doğrudan görürsünüz; “görsel olarak yeterli” ile “GPU için yeterli” aynı şey değildir; uzak kürede düşük segment çoğu zaman ikisini de karşılar.

Segment karşılaştırması · küre

Segment arttıkça eğri yüzey parçalı üçgenlerle daha iyi taklit edilir; wireframe açıkken yoğunluk gözle görülür.

Demo sabitleri tablosu (segment karşılaştırması)

Bu blok diagram-primitive-geometri.js içindeki initSegmentCompare ile eşlenir. Orta küre için seçilen taban segmentten üç farklı kesitlik üretilir; her güncellemede eski geometri dispose edilir.

initSegmentCompare — üç küre
Sahne / rol Parametre Değer Tür
Ortak setClearColor 0x05060c 🔒 Sabit
Küre ×3 SphereGeometry yarıçap 1 🔒 Sabit
Küre ×3 position.x dizisi -2.35, 0, 2.35 🔒 Sabit
Segment mantığı segTriple(base) düşük max(3, b - 8) · orta b (4–48) · yüksek min(64, b + 10) 🔒 Mantık
UI data-primitive-seg-base min 12 · max 40 · adım 2 · varsayılan 20 ↔ HTML
Malzeme MeshStandardMaterial color: 0x6a9ae8 · metalness: 0.15 · roughness: 0.42 🔒 Sabit

Önemli kod kesiti

Üç kürenin segmentleri tek kaynaktan türetilir; döngü içinde geometri yenilenir.

function segTriple(base) {
  const b = Math.max(4, Math.min(48, Math.round(base)));
  const low = Math.max(3, b - 8);
  const mid = b;
  const high = Math.min(64, b + 10);
  return [low, mid, high];
}

// apply() içinde — her küre için dispose + yeniden SphereGeometry
for (let i = 0; i < 3; i++) {
  meshes[i].geometry.dispose();
  meshes[i].geometry = geos[i];
}

Etkileşimli demo: primitiv türü ve parametreler

Aşağıda modeli elle çizmiyorsunuz; parametre seçiyorsunuz. Tür değiştikçe ilgili kaydırıcılar görünür; kutu boyutları, küre segmenti, düzlem boyutu ve ızgara, torus yarıçap ve boru kalınlığı.

Parametrik primitiv

Sahneyi fare ile sürükleyerek döndürebilirsiniz (orbit). Parametreler anlık yeniden üretilen BufferGeometry ile güncellenir.

Demo sabitleri tablosu (parametrik primitiv)

initPrimitiveSwitch: tür seçiciye göre mesh.geometry.dispose() ve yeni primitiv; kutu dışındaki türlerde düzlem rotation.x = -π/2 ile yere yaslanır.

initPrimitiveSwitch — orbit + dinamik geometri
Sahne / rol Parametre Değer Tür
Başlangıç mesh BoxGeometry 1.2 × 1.2 × 1.2 · y ≈ 0.65 🔒 Sabit
Malzeme MeshStandardMaterial color: 0x7ec8a8 · side: THREE.DoubleSide 🔒 Sabit
UI aralıkları (HTML) Kutu w/h/d her biri 0.4 … 2.5 · adım 0.05 · varsayılan 1.2 ↔ Sürgü
Küre segment 4 … 64 · varsayılan 24 ↔ Sürgü
Düzlem w/h · segment 1…6 · segment 1…48 ↔ Sürgü
Torus r / tube / radial / tubular 0.4…1.6 · 0.1…0.6 · radial 6…48 · tubular 6…48 ↔ Sürgü
Orbit OrbitControls enableDamping: true · hedef (0, 0.5, 0) 🔒 Sabit

Önemli kod kesiti

Tür değişince tek rebuild() dalı seçilir; düzlemde ekstra yerel dönüş ve konum ayarı yapılır.

function rebuild() {
  const t = typeSel ? typeSel.value : "box";
  mesh.geometry.dispose();
  let g;
  if (t === "box") {
    g = new THREE.BoxGeometry(w, h, d);
  } else if (t === "sphere") {
    g = new THREE.SphereGeometry(1, s, s);
  } else if (t === "plane") {
    g = new THREE.PlaneGeometry(w, h, seg, seg);
  } else {
    g = new THREE.TorusGeometry(R, tube, rs, ts);
  }
  mesh.geometry = g;
  if (t === "plane") {
    mesh.rotation.x = -Math.PI / 2;
    mesh.position.y = 0.01;
  } else {
    mesh.rotation.set(0, 0, 0);
    mesh.position.y = 0.65;
  }
}

Etkileşimli demo: segment ve GPU yükü (çoklu küre)

Aynı geometri 36 kez tekrarlanır (6×6 ızgara). Segment artınca her kürenin üçgen sayısı büyür; toplam yük artar ve FPS genelde düşer; özellikle zayıf cihazlarda fark hissedilir.

Performans · 36 küre — FPS

Bu demo “öğreten” metin değil, ölçülebilir bir his: segment kaydırıldıkça kare süresi ve FPS okuması birlikte düşünülmeli.

Demo sabitleri tablosu (çoklu küre)

initPerfSpheres: 36 ayrı Mesh aynı SphereGeometry örneğini paylaşır; segment değişince tek geometri yenilenir ve tüm mesh’lere atanır.

initPerfSpheres — 6×6 ızgara
Sahne / rol Parametre Değer Tür
Izgara COL × ROW 6 × 636 küre 🔒 Sabit
Aralık span · başlangıç ofseti 1.05 · merkezlenmiş ox, oz 🔒 Sabit
Küre yarıçap · başlangıç segment 0.32 · 12 × 12 🔒 Sabit
Malzeme MeshStandardMaterial 0xc8a0ff · metal 0.08 · rough 0.5 🔒 Sabit
UI data-primitive-perf-seg min 4 · max 48 · adım 2 · varsayılan 10 ↔ HTML
FPS düşük eşik sınıfı fps < 45doc-primitive-demo__fps--low 🔒 Mantık

Önemli kod kesiti

Paylaşımlı geometri: bir kez dispose, yeni SphereGeometry, döngüde her mesh’e aynı referans.

const COL = 6;
const ROW = 6;
const N = COL * ROW;
// ... her hücre için new THREE.Mesh(geo, mat) — başlangıç geo paylaşımlı

function updateGeo() {
  const seg = Math.max(4, Math.min(48, Math.round(Number(range.value))));
  geo.dispose();
  geo = new THREE.SphereGeometry(0.32, seg, seg);
  for (const m of meshes) {
    m.geometry = geo;
  }
}

Bonus: düzlem segmenti ve vertex deformasyonu

PlaneGeometry ızgarası ne kadar sıksa, aynı dalga fonksiyonu o kadar pürüzsüz görünür; düşük segmentte yüzey blok blok kırılır.

Plane · dalga

Vertex pozisyonları her kare güncellenir; segment düşükken dalga kenarlı, yüksekken akıcı görünür.

Demo sabitleri tablosu (düzlem dalgası)

initPlaneWave: düzlem yerel koordinatlarında saklanan rest dizisi + her karede sinüs/kosinüs ile Z yer değiştirme; computeVertexNormals() ile aydınlatma güncellenir.

initPlaneWave — CPU vertex güncelleme
Sahne / rol Parametre Değer Tür
Düzlem PlaneGeometry (başlangıç) 4 × 4 · segment 16 × 16 🔒 Sabit
UI data-primitive-plane-seg min 2 · max 48 · varsayılan 16 ↔ HTML
Dalga sin / cos katsayıları bx*2.2 + t*1.4 genlik 0.35 · by*1.8 + t*1.1 genlik 0.22 🔒 Sabit
Zaman adımı t += … (her kare) 0.022 🔒 Sabit
Malzeme MeshStandardMaterial 0x4a9ecf · DoubleSide 🔒 Sabit

Önemli kod kesiti

Segment değişince taban düzlem yeniden üretilir ve durağan köşe konumları userData.rest içinde saklanır; animasyon döngüsünde position buffer’ı güncellenir.

function rebuildPlane() {
  const g = new THREE.PlaneGeometry(4, 4, s, s);
  mesh.geometry = g;
  const pos = g.attributes.position;
  const rest = new Float32Array(pos.count * 3);
  // ... köşe xyz rest[] içine yazılır → g.userData.rest = rest
}

// loop içinde — taban + dalga ofseti (Z)
const disp =
  Math.sin(bx * 2.2 + t * 1.4) * 0.35 + Math.cos(by * 1.8 + t * 1.1) * 0.22;
pos.setXYZ(i, bx, by, bz + disp);
pos.needsUpdate = true;
g.computeVertexNormals();

Teknik tablo: popüler primitivlerin parametreleri

Geometri Kritik parametreler Performans odağı
BoxGeometry width, height, depth (+ isteğe bağlı segmentler) Varsayılan düşük segment ile en ekonomik primitivlerden biridir.
SphereGeometry radius, widthSegments, heightSegments Segment arttıkça üçgen yükü kabaca karesel artar; uzak objelerde düşük segment.
CylinderGeometry radiusTop, radiusBottom, height, radialSegments Alt/üst kapakların açık veya kapalı olması ve radial segment sayısı.
ConeGeometry radius, height, radialSegments Tek apex; taban çemberinin segment çözünürlüğü silindirle benzer mantıkta.
PlaneGeometry width, height, widthSegments, heightSegments Vertex animasyonu (dalga vb.) için yüksek ızgara; statik zeminde düşük tutulur.

Uygulama: parametrik geometri tanımlama

Kod tarafında primitivleri üretirken segmentlerin ne işe yaradığını görmek önemlidir: aynı sınıf, farklı parametrelerle hem “kaba” hem “ince” mesh üretebilir. Bu sayfadaki çalışan davranış tek kaynakta diagram-primitive-geometri.js dosyasında toplanmıştır; her demo bölümünde isteğe bağlı ses bandı (demo kutusundan ayrı, sütun genişliğinde), kutunun altında ise o bloğa karşılık gelen sabit tablo ve kod kesiti bulunur; segment, parametrik tür, çoklu küre, düzlem dalgası.

Kaydırıcı veya tür değişince önce geometry.dispose(), ardından yeni SomeGeometry(...) ve mesh.geometry = geometry kalıbı kullanılır; sayfadaki sayılar ile editörde gördüğünüz kod aynı dosyadan gelir; kopyala-yapıştır ile kendi projenize taşırken tablodaki sabitleri referans alın.

Holodepth notu: LOD (level of detail) stratejisi

En yüksek kalite her zaman en iyi seçim değildir

Primitiv geometrilerde segment sayısını gereksiz yükseltmek hem vertex hem fragment maliyetini artırır. Kameraya yakın bir küre için 64 segment anlamlı olabilir; uzaktaki küçük bir nesne için 8 segment çoğu zaman yeterlidir.

Holodepth ve mobil web hedefinde cihazın ısınmaması ve kare süresinin korunması için ihtiyacınız olan en düşük segment ile başlayıp, görsel artefakt görürseniz kademeli artırın; mümkünse mesafeye göre LOD veya basitleştirilmiş kopyalar düşünün.