Apa yang sebenarnya dilakukan oleh ddx (hlsl)?


17

Saya sedikit bingung. Dokumentasi resmi ( http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588(v=vs.85).aspx ) mengatakan bahwa ddx (input) adalah turunan parsial dari input dengan hormat ke "layar-ruang x-koordinat."

Kalkulus saya baik-baik saja, tetapi bagaimana cara mengetahui dari mana input berasal? Jika saya melewatinya fungsi, oke, saya bisa membayangkan apa yang akan dilakukannya, tetapi turunan dari angka selalu nol ...?

Apakah ini hanya penskalaan? Seperti, ini akan diskalakan ke sepersepuluh dari ukurannya pada jarak ini, sehingga mengembalikan sepersepuluh? Tapi itu tidak membutuhkan input ...

Dapatkah seseorang memberikan penjelasan singkat tentang apa yang sebenarnya terjadi?


2
ddxdan ddylakukan sihir yang tidak bisa kamu lakukan sendiri. Mereka memiliki akses ke informasi tambahan dari pipa rasterisasi yang tidak dapat Anda peroleh dari dalam pixel shader. Saya tidak yakin formula mana yang mereka gunakan; Saya dituntun untuk percaya bahwa mereka menggunakan teknik estimasi, tetapi saya tidak tahu pasti.
Sean Middleditch

Itu sangat aneh, tapi tetap saja. Apa yang sebenarnya mewakili ddx (5)? Jika dikatakan .1, bagaimana saya harus menafsirkannya? Atau -6?
Richard Rast

1
ddx(5)agak tidak berguna. Gunakan dengan nilai input, dan itu akan memberi Anda turunan dari nilai itu sehubungan dengan piksel tetangga di blok. Sekali lagi, saya tidak tahu bagaimana tepatnya menghitung nilai, tetapi meminta turunan dari non-input mungkin hanya perilaku yang tidak terdefinisi dan menghasilkan sampah. Lihat fgiesen.wordpress.com/2011/07/10/10/... untuk informasi lebih banyak daripada yang bisa saya berikan.
Sean Middleditch

Saya tidak yakin tetapi mungkin bahwa kompiler HLSL sebenarnya melakukan diferensiasi simbolis penuh dari ekspresi yang Anda sampaikan ke ddx / ddy. blogs.msdn.com/b/chuckw/archive/2011/03/08/… research.microsoft.com/pubs/146019/…
Ziriax

Apa fungsinya? The HANYA hal yang sedikit wajar, jelas.
MickLH

Jawaban:


32

Secara internal, GPU tidak pernah menjalankan pixel shader satu per satu. Pada tingkat granularitas terbaik, mereka selalu menjalankan 32-64 piksel pada saat yang sama menggunakan arsitektur SIMD. Dalam hal ini, piksel disusun lebih lanjut menjadi paha 2x2, sehingga setiap kelompok 4 piksel berturut-turut dalam vektor SIMD sesuai dengan blok piksel 2x2 di layar.

Derivatif dihitung dengan mengambil perbedaan antara piksel dalam satu kuad. Misalnya, ddxakan mengurangi nilai dalam piksel di sisi kiri quad dari nilai di sisi kanan, dan ddyakan mengurangi piksel bawah dari yang atas. Perbedaan tersebut kemudian dapat dikembalikan sebagai turunan dari keempat piksel dalam kuad.

Karena pixel shader berjalan di SIMD, dijamin bahwa nilai yang sesuai berada di register yang sama pada saat yang sama untuk semua piksel dalam quad. Jadi ekspresi atau nilai yang Anda masukkan ke apapun ddxatau ddy, akan dievaluasi di keempat piksel quad, maka nilai dari piksel yang berbeda dikurangi seperti dijelaskan di atas.

Jadi mengambil turunan dari nilai konstan akan memberikan nol (seperti yang Anda harapkan dari kalkulus, kan?) Karena itu adalah nilai konstan yang sama di keempat piksel.

Perhatikan juga bahwa ada turunan "kasar" dan "baik", ddx_coarse/ ddy_coarsedan ddx_fine/ ddy_fine. Penjelasan tentang perbedaan diberikan di sini . Hanya polos ddx/ ddyalias untuk versi kasar.

BTW, alasan fungsi ini ada adalah bahwa GPU secara internal harus mengambil turunan dari koordinat tekstur untuk melakukan pemilihan mipmap dan penyaringan anisotropik. Karena perangkat keras memerlukan kemampuan itu (Anda dapat menggunakan sembarang ekspresi untuk koordinat tekstur dalam shader), itu cukup mudah untuk juga mengeksposnya ke programmer shader secara langsung.


+1; Saya menemukan ini berguna ketika menerapkan efek gangguan pada tekstur; texcoords yang terganggu memberikan distorsi warna, tetapi menggunakan tex2Dgrad dengan turunan dari texcoords asli (tidak terganggu) memberikan hasil yang tidak terdistorsi.
Maximus Minimus

Baiklah, setelah beberapa pemikiran saya pikir saya menemukan kebingungan saya. Dalam pikiran saya, ddxberfungsi seperti fungsi lainnya dalam bahasa pemrograman tradisional; Anda mengevaluasi input, mengubahnya menjadi float atau apa pun, lalu lakukan fungsi luar ( ddx) untuk itu. Tetapi ini berbeda - dibutuhkan string input , mengevaluasinya di beberapa tempat, menghitung turunan, dan melaporkan hasilnya. Apakah itu benar?
Richard Rast

1
@RichardRast Benar. Anda dapat menganggapnya ddxsebagai operasi pada ekspresi yang Anda masukkan ke dalamnya, bukan nilainya .
Nathan Reed

Tapi lihat, itu cukup aneh sehingga harus ada dalam dokumentasi. Saya tidak dapat memikirkan waktu lain dalam kehidupan pemrograman saya di mana itu terjadi.
Richard Rast

Nathan Reed menyebutkan bahwa GPU menggunakan fungsi-fungsi ini untuk pemilihan mipmap. Anda juga dapat menggunakannya untuk memaksa GPU untuk memilih level mipmap yang diinginkan atau untuk mencegah artefak dari pemilihan level-mip yang salah. Prosesnya dijelaskan pada halaman 163 dan 164 dari Shader X3.
JamesHoux
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.