Bagaimana tingkat mipmap dihitung dalam Logam?

14

Pertanyaan saya secara khusus berkaitan dengan Logam, karena saya tidak tahu apakah jawabannya akan berubah untuk API lain.

Apa yang saya percaya saya mengerti sejauh ini adalah ini:

  • Tekstur yang dipetakan telah mengkomputasi "level detail", di mana level detail yang lebih rendah diciptakan oleh downsampling tekstur asli dengan cara yang bermakna.

  • Level mipmap dirujuk dalam level detail yang menurun, di mana level 0adalah tekstur asli, dan level yang lebih tinggi adalah kekuatan dari dua pengurangannya.

  • Sebagian besar GPU menerapkan pemfilteran trilinear, yang mengambil dua tingkat mipmap yang berdekatan untuk setiap sampel, sampel dari setiap tingkat menggunakan penyaringan bilinear, dan kemudian secara linier memadukan sampel-sampel tersebut.

Yang tidak saya mengerti adalah bagaimana level mipmap ini dipilih. Dalam dokumentasi untuk pustaka standar Metal, saya melihat bahwa sampel dapat diambil, dengan atau tanpa menentukan contoh lod_optionstipe. Saya akan berasumsi bahwa argumen ini mengubah cara level mipmap dipilih, dan tampaknya ada tiga jenis lod_optionstekstur 2D:

  • bias(float value)
  • level(float lod)
  • gradient2d(float2 dPdx, float2 dPdy)

Sayangnya, dokumentasi tidak repot menjelaskan apa yang dilakukan opsi ini. Saya bisa menebak bahwa bias()bias beberapa tingkat detail yang dipilih secara otomatis, tetapi kemudian apa artinya bias value? Pada skala apa ia beroperasi? Demikian pula, bagaimana adalah loddari level()diterjemahkan ke dalam tingkat mipmap diskrit? Dan, beroperasi di bawah asumsi yang gradient2d()menggunakan gradien dari koordinat tekstur, bagaimana cara menggunakan gradien itu untuk memilih level mipmap?

Lebih penting lagi, jika saya menghilangkan lod_options, bagaimana level mipmap dipilih? Apakah ini berbeda tergantung pada jenis fungsi yang dijalankan?

Dan, jika operasi standar no-lod-options-ditentukan sample()fungsi adalah untuk melakukan sesuatu seperti gradient2D()(setidaknya dalam fragmen shader), apakah itu menggunakan turunan ruang-layar sederhana, atau apakah itu bekerja secara langsung dengan rasterizer dan koordinat tekstur yang diinterpolasi untuk menghitung gradien yang tepat?

Dan akhirnya, seberapa konsistenkah perilaku ini dari satu perangkat ke perangkat lainnya? Artikel lama (seperti pada DirectX 9) yang saya baca mengacu pada pemilihan mipmap spesifik perangkat yang kompleks, tetapi saya tidak tahu apakah pemilihan mipmap lebih baik pada arsitektur yang lebih baru.

lcmylin
sumber

Jawaban:

17

Pilihan Mip adalah standar yang cukup baik di seluruh perangkat saat ini — dengan pengecualian dari beberapa rincian penting dari pemfilteran anisotropik, yang masih tergantung pada masing-masing produsen GPU untuk menentukan (dan rincian tepatnya umumnya tidak didokumentasikan secara publik).

Tempat yang baik untuk membaca tentang pemilihan mip secara terperinci ada di spec OpenGL, bagian 8.14, "Tekstur Minifikasi" . Saya menganggap itu bekerja dengan cara yang sama di Metal. (Apple bisa saja mengubah sesuatu, mengingat mereka membuat perangkat keras dan API ... tapi saya ragu mereka.) Saya akan meringkasnya di sini.

Pilihan mip default (tidak menggunakan lod_optionspengubah) menggunakan gradien layar-ruang dari koordinat tekstur untuk memilih level mip. Pada dasarnya, ia mencoba untuk memilih level mip yang menghasilkan sedekat mungkin dengan pemetaan 1: 1 dari texels ke piksel. Misalnya, jika gradien memiliki panjang 4 texels per pixel, ia akan memilih mip level 2 (yang merupakan 1/4 ukuran level 0 dan karenanya memberi Anda 1 texel yang dicampurkan per pixel).

Dengan pemfilteran trilinear, karena Anda biasanya tidak mendarat pada pemetaan 1: 1 yang tepat , ia mengambil dua level terdekat dan menyisipkan secara linear di antara mereka, sehingga Anda memiliki transisi yang mulus antara level mip saat kamera atau objek dalam adegan bergerak sekitar.

λλλλ=2.8

λcatatan2(1/4)=-2

Sekarang, seperti untuk opsi pengubah:

  • biasλ
  • levelλλlod
  • gradient2dmemungkinkan Anda memasukkan vektor gradien Anda sendiri, yang menggantikan gradien layar-ruang implisit dari koordinat tekstur. Sisa seleksi mip dan proses pengambilan sampel berjalan seperti biasa, tetapi dengan gradien yang diubah. Ini memungkinkan Anda menyesuaikan pemfilteran anisotropik.

Dalam jenis shader lain selain shader fragmen, tidak ada gagasan tentang "gradien layar-ruang", sehingga dua operasi terakhir biasanya satu-satunya yang diizinkan — operasi apa pun yang mencoba menggunakan gradien implisit akan memberikan kesalahan kompilasi. Saya tidak yakin bahwa begitulah Metal melakukannya, tapi itulah yang saya harapkan dari bekerja dengan API lain.

Nathan Reed
sumber