Three.js · Hareket
Hareketin estetiği: Lerp, easing ve AnimationMixer
3B bir nesneyi A noktasından B noktasına taşımak kolaydır:
position.set(x, y, z) anında sonucu verir. Oyuncu veya kullanıcı için asıl mesele,
o geçişin nasıl hissettirdiğidir; sert sıçrama mı, yumuşak yaklaşma mı,
hızlanıp yavaşlayan sinematik hareket mi? Bu fark, konum matematiğinden çok
zamanlama ve karışım (interpolation) dilidir.
Bu sayfada üç araç birlikte okunur: lerp (hedefe gecikmeli takip, kamera ve imleç), easing (hareketin karakteri; ease-in, ease-out, tween kütüphaneleri), AnimationMixer (glTF karakter gibi önceden kaydedilmiş kliplerin oynatılması). Döngünün ne zaman döndüğü; rAF, tick ve delta time; önceki sayfada; burada nasıl yumuşattığınız anlatılır.
İyi animasyon yalnızca hareket değil, hissettirme meselesidir: küçük easing
farkları bile kullanıcı deneyimini değiştirir. Kapsam: lerp formülü ve FPS uyarısı, easing
profilleri, mixer / clip akışı, uygulama kodu ve karşılaştırma tablosu. Sabit
alpha ile lerp’in doğal “ease-out” hissi ile tam easing ihtiyacının ayrımı sayfa
sonundaki Holodepth notunda toplanır.
Yumuşak hareket ve zamanlama
Lerp (linear interpolation): doğrusal yumuşatma
Lerp, "lineer interpolasyon"un kısaltmasıdır. İki değer arasında ; örneğin iki konum veya iki renk; belirli bir alpha oranında ara değer üretmenizi sağlar.
Çekirdek mantık şu formüle dayanır: mevcut değer, hedefe doğru her adımda fark vektörünün bir kısmı kadar yaklaşır.
current + (target - current) * alpha
Three.js'te mesh.position.lerp(hedef, alpha) bu ilişkiyi
Vector3 üzerinde uygular; alpha 0 ile 1 arasında bir karışım
oranıdır.
Formülün pratik karşılığı üç başlıkta özetlenir:
- Matematiksel mantık: Her tick’te
current, hedefe doğru fark vektörününalphaoranı kadar yaklaşır — üsttekicurrent + (target - current) * alphaifadesinin kare döngüsü içindeki uygulamasıdır.alphaküçükse hareket yavaş ve “yumuşak”; büyüdükçe daha sert. Hedef sabitken mesafe azaldıkça adım da küçülür; bu yüzden doğrusal lerp çoğu zaman doğal bir ease-out hissi verir (tam easing ihtiyacı aşağıda). Teoridealpha < 1ile hedefe asla tam oturmaz; pratikte eşik mesafedecopyveyaalpha = 1ile bitirirsiniz. - Kullanım alanı: Kameranın oyuncuyu veya imleci gecikmeli takip etmesi (third-person, drone kamerası), UI panelinin hedef konuma süzülmesi, ses veya ışık yoğunluğunun yumuşak geçişi. Anlık teleport yerine “biraz geriden gelme” istenen her yerde lerp uygundur; sinematik giriş–çıkış veya süreli tween gerekiyorsa easing / GSAP tercih edilir. Örnek döngü uygulama bölümündedir.
- Three.js:
Vector3.lerp(hedef, alpha)mevcut vektörü yerinde günceller;lerpVectors(a, b, alpha)iki uç nokta arasında ara değer üretir. Renk ve benzeri özelliklerde aynı fikirColor.lerpile devam eder; dönüşlerde çoğu zamanQuaternion.slerpkullanılır (doğrusal açı karıştırmaz). Ek tween kütüphanesi şart değildir; tick içinde bir satır lerp yaygın başlangıç kalıbıdır — yine dealpha’yı delta ile ölçeklemeyi unutmayın (hemen alt paragraf).
FPS bağımlılığı: alpha sabit bir oran olarak kaldığında,
saniyede
daha fazla kare çizildiğinde toplam kayma artar; yani hareket kare hızına
duyarlıdır. Daha tutarlı sonuçlar için alpha'yı
delta time ile ölçeklemek (veya hızı saniye bazında tanımlamak) yaygın
pratiktir; ayrıntı için
delta time
bölümüne bakın.
Örnek; her karede konumu hedefe yaklaştırma:
// Her karede mevcut konumu hedefe %5 oranında yaklaştır (yumuşak takip)
mesh.position.lerp(targetPosition, 0.05);
Easing: hareketin karakteri
Düz lerp, adım oranı sabit kaldığı sürece doğrusal kalır ve bazen mekanik / robotik hissettirebilir. Easing, zamanın nasıl "harcanacağını" belirler: hareketin başında veya sonunda hızlanma / yavaşlama (ör. ease-in, ease-out).
Easing fonksiyonları genellikle normalize edilmiş zaman (t,
0–1) değerini yeniden şekillendirerek hareketin hız profilini değiştirir; böylece aynı başlangıç ve bitiş noktalarında bile "nasıl varılacağı" farklılaşır.
Easing iki katmanda düşünülür: araç (kütüphane veya saf fonksiyon) ve karakter (hız profili):
- Kütüphaneler: Normalize zaman
t ∈ [0, 1]içint → f(t)eğrisi saf matematikle yazılabilir (polinom, sinüs, özel Bézier). Üretimde sık tercihler: GSAP — timeline, zincir, UI ve sahne tween’leri için güçlü; @tweenjs/tween.js — Three.js projelerinde hafif “A’dan B’ye şu sürede git” ihtiyacı. Her ikisi deanimate/ tick içindeupdate(time)ile ilerler;deltaveya geçen süre kütüphaneye verilir. Sürekli takip (kamera hedefi her kare değişiyor) için çoğu zaman lerp yeterlidir; süreli, tek seferlik geçişlerde easing / tween daha uygundur — karşılaştırma tabloda. - Karakter: Ease-in — yavaş başlar, sona doğru hızlanır;
örn. nesnenin ekrandan çıkışı veya “uzaklaşma”. Ease-out — hızlı
başlar,
yavaşlar; menü açılışı, kamera inişi, sabit
alphalerp’in doğal hissi bu gruba yakındır. Ease-in-out — giriş ve çıkış yumuşak; kapı, platform, sinematik geçiş. CSS’tekicubic-bezierile aynı dil: hareketin ağırlık ve süre hissi. Robotik doğrusallıktan kaçınmak için profili bilinçli seçin; kemik animasyonu klipleri için AnimationMixer ayrı kanaldır.
AnimationMixer: karmaşık animasyonların orkestra şefi
Dışarıdan (Blender vb.) aktarılan kemikli / skinned modellerde yürüme,
zıplama gibi hareketler için Three.js tarafında merkez bileşen
AnimationMixer'dır.
glTF / Blender’dan gelen veri genelde üç katmanda okunur; lerp veya tween ile elle yazılmaz; anahtar kareler dışarıda üretilmiştir:
- Track (kanal): Tek bir özelliğin zaman içindeki değişimini taşır —
örn.
"mixamorigHips.position"veya bir kemik.quaternion. Bir clip içinde onlarca track olabilir; her biri anahtar kare dizisi (keyframe) içerir. Track, “hangi kemik / hangi özellik hareket ediyor?” sorusunun cevabıdır. - Clip (klip): Track’lerin paketi; süre ve isimle tanımlı animasyon
parçasıdır —
Walk,Run,Idlegibi. glTF yüklerkengltf.animationsdizisi çoğu zaman doğrudanAnimationClipörneklerine dönüşür. Clip, tasarımcının ürettiği hazır hareket; kodda yeniden icat etmek yerine seçip oynatırsınız. - Mixer (mikser): Bir model (veya alt graf) için oynatıcı orkestra
şefidir:
mixer.clipAction(clip)ile aksiyon oluşturur,play()/stop(), süre ölçeği (timeScale) ve klipler arası crossfade (yürüme → koşu) burada yönetilir. Tick içindemixer.update(delta)olmadan track’ler sahneye uygulanmaz — aşağıdaki paragraf ve güncelle → çiz sırasına bağlıdır. Kamera takibi için lerp; karakter kemikleri için mixer — seçim tabloda özetlenir.
Her karede mixer'ın iç zamanını ilerletmek için
mixer.update(delta) çağrısı gereklidir; bu olmadan clip
oynatma ve kemik güncellemeleri çalışmaz. delta, iki kare arasındaki süredir (
THREE.Clock
ile
getDelta()).
Teknik tablo: hangi yöntemi ne zaman?
| Yöntem | Türü | En iyi kullanım | Zorluk |
|---|---|---|---|
| Lerp | Matematik / API | Kamera veya nesne takibi, basit yumuşak geçişler. | Kolay (dahili Vector3) |
| GSAP / tween | Kütüphane | UI, önceden tanımlı sekanslar, karmaşık easing. | Orta (harici bağımlılık) |
AnimationMixer |
Three.js animasyon API | Karakter animasyonları, glTF / FBX ile gelen klipler. | İleri (sahne ve clip yönetimi) |
Uygulama: lerp ile yumuşak takip
Fare konumunu hedef olarak kullanıp nesneyi ekran düzlemine yaklaştıran tipik bir örnek:
mesh, scene, camera ve renderer önceden
tanımlıdır. THREE.Clock ve getDelta(), ileride
mixer.update(delta) ile aynı döngüde kullanılmaya hazır olması için
eklenmiştir.
const clock = new THREE.Clock();
const targetPosition = new THREE.Vector3();
window.addEventListener('mousemove', (event) => {
targetPosition.x = (event.clientX / window.innerWidth) * 2 - 1;
targetPosition.y = -(event.clientY / window.innerHeight) * 2 + 1;
});
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
// İleride AnimationMixer ile: mixer.update(delta);
mesh.position.lerp(targetPosition, 0.1);
renderer.render(scene, camera);
}
animate();
Holodepth notu: lerp ve easing ayrımı
Lerp ile her karede kalan mesafenin bir yüzdesi alındığı için hareketin sonunda doğal bir yavaşlama (ease-out benzeri) hissi oluşur. Buna karşılık hem başta hem sonda kontrollü eğri (ease-in-out) istiyorsanız, GSAP gibi easing ve zaman çizelgesi sunan bir kütüphane iş akışını ciddi şekilde kolaylaştırır.