Three.js · glTF pipeline · Animasyon
Modelin ruhu: Animation clips (animasyon klipleri)
Üç boyutta animasyon, bir nesnenin özelliklerinin (konum, dönüş, ölçek veya kemik hareketleri) zaman içinde değişmesidir. Three.js bu hattı AnimationClip (veri), AnimationMixer (zaman ve karıştırma) ve AnimationAction (oynatma politikası) üçlüsüyle düzenler.
Klipler tek başına «dosya» gibidir; sahneye hayat veren, karıştırıcıyı her kare güncellemek ve gerektiğinde eylemlerin ağırlığını yönetmektir. Önceki adımda yüzey haritalamasını gördük; bu sayfada zaman çizelgesi verisinin sahne grafiğindeki düğümlere nasıl uygulandığına odaklanıyoruz — kemik ağırlıkları ve skinning ayrıntıları Skinning konusunda tamamlanır.
Önce okuyun: Material mapping, Node hiyerarşisi, Animasyon döngüsü & zaman, Lerp, easing & mixer.
Aşağıdaki lab, rigged bir karakter üzerinde AnimationClip → AnimationMixer →
AnimationAction zincirini gösterir: aynı iskelette birden fazla klip
(Idle / Walk / Run),
aktif eylemin effectiveWeight ayarı ve
crossFadeTo ile yumuşak geçiş. Karakter
Soldier.glb, Mixamo değil — Three.js
resmi örnek deposundan (MIT) projeye eklenmiş yerel kopyadır; sayfa altbilgisinde de atıf
gösterilir.
Aktif klip
Blend ağırlığı
Crossfade
Hedef klipi seçip geçişi başlatın; mevcut aktif
eylemden crossFadeTo ile 0.4s süre kullanılır.
Model kullanım notu
Bu üç boyutlu model harici bir kaynaktan (Three.js resmi örnek deposu, yerel kopya) temin edilmiştir; yalnızca bu sayfadaki konuyu anlatmak ve göstermek amacıyla kullanılmaktadır, ayrı bir ticari ürün veya marka sunumu değildir. Hak sahibi veya yetkili bir merci tarafından kaldırılması veya düzeltilmesi talep edilirse, talep makul süre ve usule uygun şekilde değerlendirilip gereği yapılabilir.
Nasıl kullanılır:
Önce Aktif klip ile Idle / Walk
/ Run arasında kesin geçiş yapın; ardından Blend
ağırlığı
ile o anki eylemin katkısını düşürüp yükseltin. Crossfade bölümünde hedef
klipi seçip düğmeye basınca API düzeyinde yumuşak geçiş görürsünüz —
bu, küp üzerinde yalnızca kök dönüşüm oynatmaktan farklı olarak track
tabanlı kemik animasyonunu gerektirir.
Model: Three.js examples / MIT — yerel Soldier.glb
(Adobe Mixamo indirmesi değildir). Ticari kullanımda güncel depo lisansını doğrulayın.
AnimationClip nedir?
Bir AnimationClip, modelin yapabileceği belirli bir hareketin (walk, jump, ateş etme vb.) veri paketidir.
glTF yüklemesinde çoğu zaman gltf.animations dizisinde
gelir; her öğe bir klibi temsil eder ve adı dışa aktarma sırasında belirlenir.
Keyframes
Zaman çizelgesinde hangi anda hangi değerlerin geçerli olduğunu söyler; ara değerler genelde enterpolasyonla üretilir. Eğri türleri ve easing hissi için lerp / mixer sayfasına bakın — bu sayfada veri taşıyıcısı olarak klibi ele alıyoruz. İsimlendirilmiş klipleri canlı görmek için karakter labına bakın.
Tracks
Kol, bacak veya kök dönüşümü gibi kanallar için ayrı izler; aynı klibin parçaları birlikte oynatıldığında bütün hareket ortaya çıkar. İz adları sahne grafiğindeki nesne yollarına bağlıdır; isim uyuşmazlığında düğüm adlandırma pratiği kritik hale gelir.
Klibin süresi (duration) ve hedef nesne yolları (track adları) içerik üretim aracına göre değişir; sahne grafiğindeki düğüm adlarıyla eşleşmeleri kontrol etmek, ilk yüklemede sık yapılan bir doğrulama adımıdır.
AnimationMixer: Orkestra Şefi
Klipler kendi başlarına oynatılmaz; bunun için kök nesneye (çoğunlukla
gltf.scene
veya karakter kökü) bağlı bir AnimationMixer oluşturulur. Karıştırıcı, o köke
bağlı izlerin örneklenmesini ve birden fazla eylemin aynı anda nasıl birleşeceğini yönetir.
Pratik kural: aynı rig / aynı sahne alt ağacı için tek karıştırıcı düşünün; farklı karakterler için ayrı örnekler açın. Böylece hangi modelin hangi zaman çizelgesinde olduğu net kalır.
Her karede karıştırıcıya geçen süre delta time
(clock.getDelta()) ile verilmelidir; aksi halde animasyon hızı ekran yenileme
hızına yapışır
(6. bölüm). Aynı kökte birden fazla
eylem örneği için üstteki
labı kullanın.
AnimationAction: Kontrol Paneli
mixer.clipAction(clip) aynı klibe tekrar başvurduğunuzda genelde aynı eylem
örneğini döndürür; böylece durum (paused, süre vb.) korunabilir.
Oynatma politikası bu nesnede toplanır.
Play / Pause / Stop
Klibi başlatır, dondurur veya keser. Uzun süre kullanılmayacaksa stop veya fadeOut ile devreden çıkarmak, gereksiz örneklemeden kaçınmaya yardım eder.
Loop
Tek sefer veya döngü; LoopRepeat, LoopOnce gibi modlarla seçilir.
Kesintisiz döngülerde dikiş noktası için klibin başı–sonu uyumu önemlidir.
Weight (ağırlık)
Genelde 0–1 arası; birden fazla klibin üst üste binmesinde (blending) ve crossfade sırasında kullanılır.
Karakter labında
ağırlık kaydırıcısı ve crossFadeTo düğmesi bu iki kavramı yan yana dener.
Animasyonlar arası geçiş (crossfade)
Yürümeden koşmaya doğrudan atlama, pozun bir karede sıçramasına yol açar. İki eylem arasında kısa bir süre boyunca ağırlıkları kaydırmak (crossfade), izleyicide «aynı vücudun» sürekliliğini korur.
Three.js’te bunu crossFadeFrom / crossFadeTo ile yapabilirsiniz;
süre parametresi saniye cinsinden verilir. Geçiş süresi ne kısa ne aşırı uzun olmalı: çok
kısa yine sıçrar, çok uzun ise ayakların kaydığı hissi doğabilir.
İki klibin iskelet veya dönüşüm yolları uyumlu değilse crossfade tek başına her zaman «mükemmel» sonuç vermez; bu durumda kaynakta benzer bağ pozları veya ayrı geçiş klipleri düşünmek gerekir. İnce lerp davranışı için easing / mixer sayfasındaki sezgileri yan yana tutmak faydalıdır — burada oynatıcı API sınırını çizmeye odaklanıyoruz.
Karakter labında
crossFadeTo düğmesi ile aynı rig üzerinde iki eylem arasında geçişi deneyin.
JavaScript uygulaması
Aşağıdaki iskelet, glTF yüklemesi tamamlandıktan sonra tek bir klibi
oynatmak için yeterlidir. gltf.animations[0] yerine isim veya sıra ile doğru
klibi seçtiğinizden emin olun. Karıştırıcı kökü olarak gltf.scene kullanımı,
yanlış kök
seçiminden kaçınmak için de önemlidir. Tam akış için
Soldier labına
göz atın.
const clock = new THREE.Clock();
// 1. Karıştırıcı (model köküne bağlı)
const mixer = new THREE.AnimationMixer(gltf.scene);
// 2. Klibi al ve eylem oluştur
const walkClip = gltf.animations[0];
const walkAction = mixer.clipAction(walkClip);
// 3. Oynat
walkAction.play();
// 4. Render döngüsünde güncelle
function update() {
const delta = clock.getDelta();
mixer.update(delta);
}
Teknik kural: Zamanlama (delta time)
Animasyonların farklı ekran yenileme hızlarında aynı «gerçek dünya» hızında görünmesi için
sabit kare başına sabit saniye varsaymamalısınız. clock.getDelta(), iki kare
arasında gerçekten geçen süreyi verir; mixer.update(delta) bu süreyle orantılı
ilerler.
Yüksek yenileme hızında delta küçülür; düşükte büyür — böylece saniye
başına hareket miktarı cihazdan bağımsız kalır. Sekme arka planda beklerken büyük delta sıçramalarına karşı üst sınır koymak (isteğe bağlı) uzun süreli
duraklamalarda ani fırlamayı yumuşatır. Genel döngü mimarisi için
animasyon döngüsü sayfasına dönün — bu bölüm yalnızca
mixer güncellemesiyle ilişkilidir.
HoloDepth «Animation» checkpoint’i
Özet
İyi animasyon yalnızca doğru klibi seçmek değildir: zamanın (delta), geçişin (crossfade) ve eylem ağırlıklarının birlikte ayarlanmasıdır; izleyicide «canlı» hissi çoğunlukla buradan gelir.
Sıradaki konu: kemik ağırlıkları ve SkinnedMesh tarafı Skinning system sayfasında — kliplerin iskelet izleriyle nasıl birleştiğini orada tamamlıyoruz.
HoloDepth özet stratejisi
- Mixer sınırları: Her önemli karakter veya bağımsız rig için ayrı karıştırıcı kullanın; tek sahneye onlarca gereksiz örnek eklemeyin.
- Geçişler: Durum değişimlerinde
crossFadeFrom/crossFadeToile süreyi kontrol edin; kök poz uyumsuzluğunda veri tarafını da gözden geçirin. - Yük: İhtiyaç kalmayan eylemleri sürekli play
durumunda tutmayın;
stop()/fadeOutile devreden çıkarın.