Untuk pemahaman saya, fungsi Lerp interpolasi antara dua nilai ( a
dan b
) menggunakan nilai ketiga ( t
) antara 0
dan 1
. Di t = 0
, nilai a dikembalikan, at t = 1
, nilai b
dikembalikan. Nilai 0,5 di tengah jalan a
dan b
dikembalikan.
(Gambar berikut adalah langkah mulus, biasanya interpolasi kubik)
Saya telah menjelajahi forum dan pada jawaban ini saya menemukan baris kode berikut:transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime);
Saya berpikir dalam hati, "bodoh sekali, dia tidak tahu" tetapi karena ada 40+ peningkatan, saya mencobanya dan cukup yakin, itu berhasil!
float t = Time.deltaTime;
transform.rotation = Quaternion.Slerp(transform.rotation, toRotation, t);
Debug.Log(t);
Saya mendapat nilai acak antara 0.01
dan 0.02
untuk t
. Bukankah seharusnya fungsi interpolasi sesuai? Mengapa nilai-nilai ini menumpuk? Ada apa dengan lerp yang tidak saya mengerti?
sumber
Jawaban:
Lihat juga jawaban ini .
Ada dua cara umum untuk digunakan
Lerp
:1. Pencampuran linier antara awal dan akhir
Ini adalah versi yang mungkin paling Anda kenal.
2. Kemudahan eksponensial menuju target
Perhatikan bahwa dalam versi ini
current
nilai muncul sebagai output dan input. Itu menggeserstart
variabel, jadi kami selalu mulai dari mana pun kami pindah ke pada pembaruan terakhir. Inilah yang memberikan versiLerp
memori ini dari satu frame ke yang berikutnya. Dari titik awal yang bergerak ini, kami kemudian memindahkan sebagian kecil dari jarak ke arah yangtarget
ditentukan olehsharpness
parameter.Parameter ini bukan "kecepatan" lagi, karena kami mendekati target dengan cara yang mirip Zeno . Jika
sharpnessPerTick
berada0.5
, maka pada update pertama kami akan pindah setengah jalan untuk tujuan kami. Kemudian pada pembaruan berikutnya kami akan memindahkan setengah jarak yang tersisa (jadi seperempat dari jarak awal kami). Kemudian pada berikutnya kita akan bergerak setengah lagi ...Ini memberikan "pelonggaran eksponensial" di mana gerakannya cepat ketika jauh dari target dan secara bertahap melambat ketika mendekati asimtotik (meskipun dengan angka presisi tak terbatas, ia tidak akan pernah mencapainya dalam jumlah pembaruan terbatas - untuk keperluan kami, cukup dekat). Ini bagus untuk mengejar nilai target bergerak, atau menghaluskan input berisik menggunakan " moving average eksponensial ," biasanya menggunakan
sharpnessPerTick
parameter yang sangat kecil suka0.1
atau lebih kecil.Tapi Anda benar, ada kesalahan dalam jawaban yang Anda jawab tautannya. Itu tidak mengoreksi
deltaTime
dengan cara yang benar. Ini adalah kesalahan yang sangat umum ketika menggunakan gayaLerp
.Gaya pertama
Lerp
adalah linear, jadi kami dapat menyesuaikan kecepatan secara linear dengan mengalikannya dengandeltaTime
:Tapi pelonggaran eksponensial kami adalah non-linear , jadi hanya mengalikan
sharpness
parameter kami dengandeltaTime
tidak akan memberikan koreksi waktu yang benar. Ini akan muncul sebagai juri dalam gerakan jika framerate kami berfluktuasi, atau perubahan dalam ketajaman pelonggaran jika Anda beralih dari 30 menjadi 60 secara konsisten.Sebaliknya kita perlu menerapkan koreksi eksponensial untuk kemudahan eksponensial kita:
Berikut
referenceFramerate
ini adalah konstanta yang ingin30
menjaga unit tetapsharpness
sama seperti yang kami gunakan sebelum mengoreksi waktu.Ada satu kesalahan lain yang bisa diperdebatkan dalam kode itu, yang menggunakan
Slerp
- interpolasi linear bola berguna ketika kita menginginkan tingkat rotasi yang persis konsisten melalui seluruh gerakan. Tetapi jika kita akan menggunakan kemudahan eksponensial non-linear,Lerp
akan memberikan hasil yang hampir tidak dapat dibedakan dan lebih murah. ;) Kuotaerner lebih baik daripada matriks, jadi ini biasanya pengganti yang aman.sumber
Saya pikir konsep inti yang hilang dalam skenario ini A tidak diperbaiki. A diperbarui dengan setiap langkah, sejauh interpolasi Time.deltaTime.
Jadi, dengan semakin dekat ke B dengan setiap langkah, total ruang interpolasi berubah dengan setiap panggilan Lerp / Slerp. Tanpa melakukan matematika yang sebenarnya, saya menduga bahwa efeknya tidak sama dengan grafik Smoothstep Anda, tetapi merupakan cara murah untuk memperkirakan deselerasi karena A semakin mendekati B.
Juga, ini sering digunakan karena B mungkin juga tidak statis. Kasing yang umum adalah kamera mengikuti pemain. Anda ingin menghindari jerkiness, membuat kamera melompat ke lokasi atau rotasi.
sumber
Anda benar, metode ini
Quaternion Slerp(Quaternion a, Quaternion b, float t)
menginterpolasi antaraa
danb
dengan jumlaht
. Tapi perhatikan nilai pertama, itu bukan nilai awal.Di sini nilai pertama yang diberikan pada metode ini adalah rotasi objek saat ini
transform.rotation
. Jadi untuk setiap frame itu interpolasi antara rotasi saat ini dan rotasi target_lookRotation
dengan jumlahTime.deltaTime
.Itu sebabnya ia menghasilkan rotasi yang halus.
sumber