Jeffrey Cross
Jeffrey Cross

Quake cepat terbalik akar persegi

Fungsi akar kuadrat songsang (1 / sqrt (x)) digunakan dengan banyak semasa gelung lukisan enjin permainan untuk menormalkan vektor ke vektor "unit" dengan panjang 1. vektor normal adalah penting kerana apabila anda mengambil produk dot dua mereka (Ax * Bx + Ay * Dengan + Az * Bz), hasilnya adalah kosinus sudut antara kedua vektor.

Jadi bayangkan anda mempunyai vektor yang menggambarkan cara permukaan menghadap (permukaannya normal) dan vektor kedua yang menggambarkan arah cahaya matahari. Sekiranya vektor cahaya matahari selari dengan permukaan anda yang normal, iaitu permukaan menghadap matahari, produk titik dua vektor normal ialah kosinus 0, iaitu 1. Jika permukaan adalah 90 darjah dari matahari, produk dot adalah cosine dari 90, iaitu 0. Apa-apa sahaja di antara dan anda mendapat nilai antara 0 dan 1, yang pada asasnya membolehkan anda untuk menerangkan betapa terang anda harus menyalakan permukaan itu.

Sekarang, anda menjalankan pengiraan ini pada setiap segitiga yang dapat dilihat dalam permainan 3D, dan anda melakukan semua itu sebanyak 30 kali atau lebih dalam satu saat, dan anda mempunyai kesan pencahayaan sumber titik asas! Ingat, bagaimanapun, bahawa anda memerlukan fungsi akar persegi songsang untuk mengira vektor unit bagi setiap segitiga tersebut. Operasi akar persegi lambat. Lakukan beribu-ribu kali setiap gelung lukisan, dan anda mempunyai permainan yang perlahan.

Tetapi jika anda tidak keberatan membuang sedikit ketepatan yang kecil, ada cara yang lebih cepat.

Terdapat fungsi akar persegi songsang yang banyak menggunakan enjin permainan yang dikhabarkan telah berasal dari Quake III oleh programmer Nvidia Gary Tarolli. Ia kelihatan seperti ini:

float InvSqrt (float x) {float xhalf = 0.5f * x; int i = * (int *) & x; // mendapatkan bit untuk nilai terapung i = 0x5f3759df - (i >> 1); // memberi penanda awal y0 x = * (float *) & i; // menukar bit balik ke float x = x * (1.5f-xhalf * x * x); // Langkah Newton, mengulangi peningkatan pulangan ketepatan x; }

Terus, apa itu?!?!

Oleh itu, ketika Newton muncul dengan cara bijak menghampiri akar persegi songsang. Pertama, anda membahagikan nombor asal x dengan dua. Mari memanggilnya "xhalf". Kemudian, anda membuat tekaan yang hampir rapat di akar persegi songsang. Mari kita panggil g. Kemudian, anda mengambil kedua-dua pembolehubah tersebut dan melakukan pengiraan ini (yang akan anda kenali sebagai langkah terakhir dalam fungsi InvSqrt):

g = g * (1.5 - xhalf * g * g)

Jika anda melakukannya berulang-ulang, menggantikan g yang dikemas kini pada setiap lelaran, g dengan cepat akan mengasah pada akar persegi songsang x! Sebenarnya, jika anda memilih g yang baik untuk bermula, satu atau dua lelaran akan membawa anda sangat dekat dengan nilai yang betul.

Persoalannya ialah, bagaimana anda mendapati bahawa jangkaan awal untuk g pertama? Coder enjin permainan menggunakan helah dengan cara nombor terapung diwakili dalam binary, dengan eksponen dan mantissa dipecah serupa dengan notasi saintifik. Dalam apungan 32-bit, bit paling sedikit adalah bit tanda dan 0 untuk nombor positif. Itu diikuti oleh 8 bit eksponen (berat sebelah oleh 127 untuk mewakili eksponen negatif dan positif), dan 23 bit terakhir mewakili mantissa.

Nah, untuk melakukan root square songsang, anda pada dasarnya perlu mengalikan eksponen dengan -1/2. Apabila anda mengalihkan bit tersebut ke kanan (operasi yang sangat cepat), kesan kepada eksponen adalah untuk membahagikannya dengan 2. Anda masih perlu tolak eksponen dari 0 untuk menukar tanda itu, walaupun, dan apa yang anda lakukan tentang mantissa yang juga terjejas dalam operasi shift sedikit?

Di sinilah nombor 0x5f3759df sihir masuk. Ini benar-benar menjengkelkan, tetapi dengan mengurangkan hasil peralihan bit dari 0x5f3759df, mantissa diset semula ke dekat dengan keadaan asal dan eksponen ditolak dari 0 (dengan mengambil kira ia berat sebelah 127) .

Hasilnya sangat dekat dengan akar persegi songsang. Cukup dekat untuk lulus tunggal melalui persamaan Newton untuk berakhir dengan nilai yang cukup tepat untuk tujuan praktikal.

Memahami Quake Square Inverse Fast Root Fast Root Square - butiran dan matematik di belakang nombor ajaib (PDF)

Kongsi

Meninggalkan Komen