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.DoubleSidegerekir.
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-1 …
4 dosya adlarıyla eşlenir (mp3, m4a, ogg, wav, webm sırayla denenir).
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.
| 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ığı.
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.
| 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.
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.
| Sahne / rol | Parametre | Değer | Tür |
|---|---|---|---|
| Izgara | COL × ROW |
6 × 6 → 36 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 < 45 → doc-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.
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.
| 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.