Three.js · Etkileşim · Kontrol
Kontrol mantığı: veriden harekete yolculuk
Kontrol mantığı, parmak izinin, fare imlecinin veya tuşların ürettiği ham olayları, sahneyi gözetleyen sanal gözün (konum ve oryantasyon) güncellenmiş haline çeviren süreçtir. Bu çevrim yalnızca koordinat taşımak değildir; kullanıcının «içeride durduğu» hissini taşıyan, kare kare tekrarlanan bir geri bildirim döngüsüdür.
Pratikte zincir şöyle düşünülür: tarayıcı ve işletim sistemi olayları sıraya koyar; uygulama kodu bu sırayı anlamlandırır (ölçekler, birleştirir, sınırlar); sonunda Object3D hiyerarşisindeki kamera düğümünün model–dünya dönüşümü güncellenir ve bir sonraki render karesinde dünya, yeni göz merkezinden projeksiyona aktarılır. Bu sayfa bu hattı mühendislik diliyle özetler; kamera optiği ve projeksiyon için Kamera giriş, yumuşatma ve zaman için Lerp & easing sayfalarına köprü kurar.
Aşağıda önce zincirin üç omurgası (Control Lab), ardından girdi cinsleri, işleme katmanı, matris dünyası ve son olarak UX hedefleri açılır.
Kontrol döngüsünün anatomisi
Süreç, kesintisiz üç katmandan oluşur; her katman bir öncekinin çıktı sözleşmesini tüketir. Kare zamanı (dt) ile çarpılmış ivme veya açı hızı gibi nicelikler genelde işleme aşamasına girer; böylece aynı kod hem 60 hem 120 Hz’de tutarlı «seyir» üretmeye yaklaşır.
- Girdi (input): İşaretçi hareketi, dokunuş dizileri, tuş durumları ve oyun çubuğu eksenleri donanım düzeyinde olay veya anlık durum olarak gelir. Burada kritik ayrım, çoğu zaman mutlak konum yerine kareler arası değişim okumaktır — özellikle ilk şahıs dönüşlerinde.
- İşleme (processing): Ham sayılar hedef modele bağlanır: örneğin yörünge kamerasında küresel koordinatlara haritalama, «uçuş» modunda dünya uzayında vektör tabanlı itme. Bu aşamada hassasiyet çarpanları, ivme limitleri, sürtünme benzeri sönüm ve açısal clamp devreye girer.
- Dönüşüm (transform): Elde edilen durum, kameranın yerel öteleme ve dönüşünü günceller; hiyerarşide üst düğümler varsa onların da zincirlenmiş matrisleri hesaba katılır. GPU tarafında ise view matrisi, bu dünya konfigürasyonunun tersine çevrilmiş halidir — sahne, göz merkezinde sabitlenmiş gibi çarpılır.
Üçüncü katmanı «sadece kamerayı kaydırıyorum» diye küçümsemeyin: doğru kurulmuş bir kontrol hattı, seçim ışınları (picking), parça manipülasyonu ve arayüz öğeleriyle aynı zaman ekseninde kilitlenir; aksi halde imleç ile sahne birbirinden milisaniyelerce kayar.
Bu üç katmanı yalnızca metinde tutmak zordur; aşağıdaki Control Lab aynı küp sahnesinde girdi göstergeleri ile birlikte işleme ve kamera durumunu canlı günceller. Modları değiştirdiğinizde kontrol «sözleşmesi» değişir; yumuşatma ve pitch clamp ise hissedilir ayarlardır.
Örnek isteğe bağlı yüklenir (pil ve GPU için). Orbit: tek tıklama bakışı başlatmaz; sol düğmeyi basılı tutup sürükleyin; tekerlek yakınlaştırır. FPS / Fly: tuvali tıklayınca imleç kilitlenir (Orbit’te gerekmez); çıkmak için Esc.
Girdi
Δx 0
Δy 0
İşleme
—
Dönüşüm
—
Mod
Orbit: basılı tutup sürükleyin (tek tıklama değil); tekerlek yakınlaştırır / uzaklaştırır. FPS / Fly: tuvali tıklayın → imleç kilidi → bakış. Fly: WASD, yükselmek E / Space, alçalmak Q / Shift.
Not: Pointer lock yalnızca FPS ve Fly içindir; Orbit’te imleç serbest kalır ve dönmek için sürüklemeniz gerekir. FPS/Fly’da kilit sonrası bakış (fare) ve Fly’da tuşlarla sahne içinde gezersiniz.
Girdi türleri ve veri işleme
Her girdi kanalı farklı bir matematiksel «şema» ister: kimisi sürekli özgür iki eksen, kimisi çoklu ikili anahtar. Ortak hedef, bu heterojen sinyalleri tek bir kamera durumu güncellemesi diline indirgemektir.
Fare ve dokunmatik · delta odaklı okuma
Bakış kontrolünde genelde işin içine Δ girer: önceki kareden bu yana X/Y’de ne kadar kaydı? Pozitif Δx, çoğu yerleşimde yaw’un (Y ekseni etrafında dönüş) artmasıyla eşlenir; pitch ise Δy ile üretilir ve genelde dik eksende «başı kaldır–indir» hissini taşır. Mutlak ekran koordinatı bazen menü isabetinde işe yarar; fakat serbest bakışta imleci sürekli yeniden merkezlemek (pointer lock) yerine doğrudan delta ile beslemek daha doğaldır.
- Dönüş modu: Fare hareketi doğrudan açısal hız veya anlık açı ofsetine eklenir; dikey terslik (invert Y) kullanıcı tercihi olarak ayrı bayrakta tutulmalıdır.
- Yörünge (orbit): İşaretçi sürüklemesi, gözü sabit bir merkez etrafında döndürmek için küresel parametrelere (azimuth, polar, yarıçap r) çevrilebilir; mesafe kısıtları zoom tekerleği veya pinch ile r’yi güncelleyerek tamamlanır.
- Dokunmatik nüans: Çok parmak jestleri (pinch–rotate) tek bir «sanal eksen» üretir; olayların sırası ve iptalleri (touchcancel) kaydırma sırasında sıçramayı tetikleyebileceği için, başlangıç referansını dokunuş kimliğine göre izlemek gerekir.
Klavye ve çubuk · vektör tabanlı yer değiştirme
Tuşlar çoğu zaman basılı / basılı değil ikilisidir; bunlar bir yön vektörü oluşturur: ileri–geri ekseni ile yan eksen ayrı ayrı toplanır, sonra kamera yerel uzayında dünya vektörüne döndürülür. Analog çubukta ise eksenler sürekli −1…1 aralığında gelir; küçük ölü bölgeler (dead zone) ve kareye düzeltme (circular clamp), çember dışına taşan dik köşeli girişleri yumuşatır.
- Çapraz yürüyüş: İleri ve sağa aynı anda basıldığında vektör uzunluğu √2 katına çıkar; sabit hız istiyorsanız bileşenleri topladıktan sonra normalize edip tek birim uzunlukta ölçeklersiniz — böylece köşegende «uçma» hissi oluşmaz.
- Zaman ile çarpım: Tuşlar sürekli «açık» kaldığında konum değişimi genelde hız × Δt ile birikir; ani sıçramalar yerine ivmeli rampalar daha kontrollü hız profilleri verir.
Hesaplama: kontrol hissini şekillendirmek
Doğrudan ham Δ’yı kameraya bağlamak mümkündür; fakat üretim kalitesinde aranan şey, kullanıcının titreyişini ve donanım farklarını içeren sinyali tasarımla süzmektir. Bu katman, oyun hissinin çoğunu belirler.
Hassasiyet ve hız ölçekleri
Donanım çözünürlüğü ve kişisel alışkanlıklar değiştiği için Δ değerleri sabit bir katsayıyla çarpılır: örneğin yaw güncellemesi ψyeni = ψ + Δx · kyaw. Yüksek k, daha az fiziksel hareketle daha geniş bakış açısı üretir; düşük k, hassas nişan ve mimari gezinmede tercih edilir. Bağımsız dikey/yatay çarpanlar, geniş ekran ve ultra geniş fare pad’lerinde dengesizlikleri düzeltir.
Damping ve yumuşatma
Anlık durdurma yerine kademeli duruş, sürtünmeli bir cismin ivmesini andırır. Bunun basit biçimi doğrusal interpolasyon (lerp): hedef hız veya hedef açı yerine, mevcut ile komut arasında her karede bir miktar yaklaşırsınız. Daha agresif ivmelenme için üstel yumuşatma (exponential smoothing) kullanılabilir; çıkış, girdinin ani sıçramalarını daha az «metalik» gösterir.
Fareyi bıraktıktan sonra küçük bir süzülme bırakmak bilinçli bir tasarım seçimidir; çok uzun sürmesi ise baş dönmesine yol açabilir. Bu yüzden hem maksimum hız tavanı hem de sönüm süresi birlikte ayarlanmalıdır (bkz. Lerp & easing).
Kısıtlar ve kararlılık
Pitch’i −90° ile +90° arasında clamplemek, dünya ekseni etrafında «ters takla» görüntüsünü engeller; roll ise çoğu gezinicide sıfırlanır veya çok dar bantta tutulur. Euler zincirleri gimbal lock riski taşıdığından, sürekli serbest dönüşlerde quaternion tabanlı entegrasyon daha dayanıklıdır — özellikle üst üste bindirilmiş dönüşlerde.
Mekânsal kısıtlar da aynı katmandadır: zemin altına gömülmemek için tekil eksende pozisyon kesilir veya basit sürtünme ile yüzeye yapıştırılır; yörünge kamerasında minimum/maksimum yarıçap kullanıcıyı modelin içine sıkışmaktan korur.
Kamera dönüşümü ve matrisler
İşlemenin çıktısı soyut sayılar olmaktan çıkıp sahne grafiğine yazıldığında, iki ana blok öne çıkar: konum vektörü P ile yönü temsil eden R (Euler kümesi veya quaternion). Three.js bu ikilisini birleştirerek dünya matrisini üretir; projeksiyon ise ikinci bir 4×4 ile görüntü düzlemine taşır.
Kavramsal olarak sık yapılan hatayı düzeltelim: ekranda «kamerayı kaydırıyorum» dersiniz; matematikte ise çoğu zaman dünya ters görünüş matrisiyle yeniden örneklenir — özel efektler ve bazı deneyler hariç, kullanıcı deneyimi açısından sonuç eşdeğerdir. Bu ayrım, shader yazarken ve çoklu geçiş efektlerinde (camera blending) kritik hâle gelir.
- Güncelleme sırası: Kontrol kodu genelde animasyon karesinin başında veya fizik entegrasyonundan önce çalışır; böylece aynı karede hem mantık hem görüntüleme tutarlı kalır.
- Hiyerarşi: Kamera başka bir düğüme (rig) bağlıysa, yerel dönüş dünya uzayına çarpılarak taşınır; araç içi veya asansör senaryolarında bu, kontrol mantığının dünya vs yerel vektör seçimini zorunlu kılar.
Amaç: kusursuz kontrol hissi
İyi kontrol «öne çıkmaz»: oyuncu veya ziyaretçi arayüz çubuğunu değil, uzayı manipüle ettiğini hisseder. Bu şeffaflık üç pratik ölçütle yakalanır:
- Düşük gecikme (latency): 60 Hz hedefinde bir kare ~16,7 ms sürdüğünden, girdi işleme + sahne güncelleme + çizimin bu bütçeyi aşmaması idealdir. Ağır gölgeler veya senkron bloklar aynı karede kontrol kodunu ittirirse his «yapışkan» olur.
- Titreşim süzme: Mikro Δ dalgalanmalarını ölçek öncesi düşük geçiren filtre veya ölçek sonrası küçük bir ölü bölge, özellikle parmak izinde istenmeyen titremeyi azaltır.
- Tutarlı zaman adımı: Sabit dt varsayımı yerine ölçülen gerçek süre ile çarpım, frame düşüşlerinde bile fiziksel hızın korunmasına yardım eder — detay için Animasyon döngüsü & zaman.
Sonuç olarak kontrol mantığı bir «yardımcı özellik» değil; üç boyutlu arayüzün omurgasıdır. Burada kurulan disiplin, daha sonra seçim ışınları ve nesne manipülasyonu yazarken de aynı ölçüm birimini size geri verir.
Holodepth teknik notu
Kontrol kodunu modüler tutun: girdi toplama, işleme ve sahneye yazma katmanlarını ayırırsanız, hem birim testleri yazılır hem de desktop ile dokunmatik için farklı politika dosyaları seçebilirsiniz. Hassasiyet ve yumuşatma parametrelerini sahne bazlı sabitlemek yerine kullanıcı ayarına açmak, uzun oturumlarda algılanan kaliteyi belirgin biçimde yükseltir.