Mengapa mengakses tekstur jauh lebih lambat ketika menghitung koordinat tekstur dalam shader fragmen?

11

Saat menggunakan tekstur dalam GLSL, yang terbaik adalah menghitung koordinat tekstur akhir dalam vertex shader dan menyerahkannya ke shader fragmen menggunakan varyings. Contoh dengan flip sederhana di koordinat y:

// Vertex shader
attribute vec2 texture;
varying highp vec2 texCoord;
// ...
void main() {
    texCoord = vec2(texture.x, 1.0-texture.y);
    // ...
}

// Fragment shader
varying highp vec2 textureCoordinates;
uniform sampler2D tex;
// ...
void main() {
    highp vec4 texColor = texture2D(tex, texCoord);
    // ...
}

Jika flip dalam koordinat y, atau operasi yang lebih sederhana seperti menambahkan vec2(0.5)ke koordinat tekstur dilakukan dalam shader fragmen, akses tekstur jauh lebih lambat. Mengapa?


Sebagai catatan, misalnya memadukan dua tekstur, menggunakan jumlah tertimbang dari mereka, jauh lebih murah dari segi waktu dan juga perlu dilakukan untuk setiap piksel, sehingga perhitungan koordinat tekstur itu sendiri tampaknya tidak terlalu mahal.

Nero
sumber
1
Dugaan saya adalah bahwa jika koordinat UV dihitung dalam VS, unit tekstur dapat mulai mengambilnya saat PS mulai. Jika dihitung dalam PS, unit tekstur harus menunggu terlebih dahulu.
RichieSams
2
Fwiw ini disebut "membaca tekstur dependen", jika itu membantu pencarian Anda.
Alan Wolfe
Apakah Anda memiliki beberapa pengukuran yang menunjukkan perbedaan perf? Saya sebenarnya tidak berharap ada banyak perbedaan sama sekali; tekstur mengambil latensi akan membanjiri beberapa ALU ops. BTW, pembacaan tekstur dependen adalah di mana ada dua (atau lebih) pembacaan tekstur, dengan koordinat untuk yang kedua bergantung pada output yang pertama. Itu lebih lambat karena urutan ketat diperlukan antara dua tekstur berbunyi.
Nathan Reed
Nah, setiap operasi yang dilakukan dalam fragmen shader akan lebih mahal daripada di vertex shader. Setiap segitiga membutuhkan 3 doa dari shader vertex, tetapi mungkin membutuhkan perintah lebih banyak dari shader fragmen, tergantung pada ukuran layarnya.
glampert
@NathanReed Saya tidak berpikir Anda harus membatasi "membaca tekstur dependen" hanya untuk mereka yang datang dari akses tekstur sebelumnya. Saya mungkin juga akan memasukkan koordinat yang dihitung dalam frag shader, yang bertentangan dengan yang dapat ditentukan hanya dari linear (well, hyperbolic with perspective) interpolasi atribut vertex.
Simon F

Jawaban:

11

Apa yang Anda bicarakan biasanya disebut "membaca tekstur dependen" di komunitas pengembangan seluler. Ini adalah detail implementasi perangkat keras tertentu, dan karenanya sangat tergantung pada GPU, apakah memiliki implikasi kinerja atau tidak. Biasanya itu adalah sesuatu yang Anda lihat dibesarkan untuk GPU PowerVR di perangkat keras Apple, karena itu secara eksplisit disebutkan dalam Imagination dan Appledokumentasi. Jika saya ingat dengan benar, masalah pada dasarnya berasal dari perangkat keras dalam GPU yang akan mulai mengambil tekstur sebelum shader fragmen bahkan mulai berjalan, sehingga bisa melakukan pekerjaan yang lebih baik untuk menyembunyikan latensi. Dokumen yang saya tautkan menyebutkan bahwa ini bukan lagi masalah pada perangkat keras Series6, jadi setidaknya pada perangkat keras Apple yang lebih baru itu bukan sesuatu yang harus Anda khawatirkan. Sejujurnya saya tidak yakin tentang GPU ponsel lain, karena itu bukan bidang keahlian saya. Anda harus mencoba dan membaca dokumentasi mereka untuk mengetahui dengan pasti.

Jika Anda memutuskan untuk melakukan beberapa pencarian Google pada masalah ini, ketahuilah bahwa Anda mungkin akan menemukan beberapa materi yang lebih lama yang berbicara tentang tekstur dependen yang diambil pada perangkat keras desktop lama. Dasar pada hari-hari awal pixel / fragmen shader, istilah "pengambilan tekstur dependen" mengacu pada penggunaan alamat UV yang mengandalkan pengambilan tekstur sebelumnya. Contoh klasik adalah rendering peta lingkungan bump-dipetakan, di mana Anda ingin menggunakan vektor refleksi berdasarkan peta normal untuk sampel peta lingkungan. Pada perangkat keras yang lebih lama ini ada beberapa implikasi kinerja utama, dan saya pikir itu bahkan tidak didukung pada beberapa GPU yang sangat lama. Dengan GPU modern, perangkat keras dan shader ISA jauh lebih umum, sehingga situasi kinerjanya jauh lebih rumit.

MJP
sumber
Omong-omong: Saya mengalaminya di iPad 3. Jadi mungkin ini sebenarnya perangkat keras khusus.
Nero