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. Bunlar arka planda BufferGeometry oluşturur; siz yalnızca boyut, segment ve birkaç şekil özel parametresi verirsiniz. Genel geometri çerçevesi için
Geometri Giriş; sahne hiyerarşisi için Object3D & sahne.

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. En sık tartışılan kavram segment sayısıdır: yüzeyi oluşturan üçgenlerin yoğunluğu buradan gelir — segment arttıkça eğri yüzeyler pürüzsüzleşir, fakat vertex ve üçgen sayısı (dolayısıyla GPU yükü) genelde hızla büyür.

Temel geometrik formlar

A. BoxGeometry (küp ve prizma)

Düz yüzeyli nesnelerin temelidir; width, height, depth ile tanımlanır. İsteğe bağlı segment parametreleri ile yüz başına ızgara bölünebilir.

  • Kullanım: duvarlar, kutular, zemin blokları.
  • İpucu: sadece düz bir kutu gerekiyorsa çoğu zaman segment sayılarını varsayılan (1) bırakmak en ekonomiktir.

B. SphereGeometry (küre)

widthSegments ve heightSegments küresel ağın sıklığını belirler.

  • Kullanım: gezegenler, toplar, kavisli yüzeyler.
  • Maliyet: segment çok yükselirse üçgen sayısı ciddi artar; uzak veya küçük nesnelerde düşük segment genelde yeterlidir.

C. PlaneGeometry (düzlem)

İki boyutlu, varsayılan olarak tek taraflı bir yüzeydir; genişlik, yükseklik ve isteğe bağlı segment ızgarası alır.

  • Kullanım: zeminler, duvarlar, UI panelleri, su yüzeyi tabanı.
  • Dikkat: tek taraflı görünür; arka yüzü de göstermek için materyalde side: THREE.DoubleSide gerekir.

D. TorusGeometry (simit / halka)

radius (ana halka) ve tube (boru kalınlığı) ile kontrol edilir; tubular / radial segmentler pürüzlülüğü ayarlar.

  • Kullanım: halkalar, lastik profili, dekoratif soyut formlar.

Silindir ve koni: CylinderGeometry ve ConeGeometry sık kullanılan diğer primitivlerdir; yarıçap, yükseklik, alt/üst kapak ve segmentler performansı doğrudan etkiler (aşağıdaki tabloda özet).

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

Aynı küre tipinde üç örnek: sol daha az segment (daha köşeli), orta taban, sağ daha fazla (daha pürüzsüz). Kaydırıcı taban segmenti değiştirir; wireframe üçgen yoğunluğunu gösterir. Her demo bölümünde, demo kutusundan ayrı — yalnızca o section içinde, ana içerik sütunu ile aynı genişlikte isteğe bağlı ses şeridi vardır: assets/audio-files/Primitive-Demo-14 dosya adlarıyla eşlenir (mp3, m4a, ogg, wav, webm sırayla denenir).

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 içinde ise o bloğa karşılık gelen sabit tablosu ve kod kesiti (segment), parametrik tablo / kesit, performans tablosu / kesit, düzlem dalgası tablosu / kesit bulunur.

Genel “tek dosyada üç satır” örneği kaldırıldı; böylece sayfadaki sayılar ile editörde gördüğünüz kod aynı dosyadan izlenir ve kopyala-yapıştır hataları azalır.

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.