Saya mengalami masalah dalam merender banyak nilai ke target rendert. Nilai tidak pernah berakhir dalam kisaran persis yang saya inginkan. Pada dasarnya saya menggunakan quad layar penuh dan shader piksel untuk membuat tekstur target rendert saya dan kemudian bermaksud untuk menggunakan koordinat tekstur sebagai dasar untuk beberapa perhitungan dalam shader. Koordinat tekstur rentang quad mulai dari (0,0) di kiri atas (1,1) di sudut kanan bawah ... masalahnya adalah, setelah interpolasi, nilai-nilai ini tidak sampai pada pixel shader karena itu .
Contoh: Saya membuat tekstur 4x4 dan shader dalam hal ini hanya menampilkan koordinat tekstur (u, v) di saluran merah dan hijau:
return float4(texCoord.rg, 0, 1);
Yang ingin saya hilangkan adalah tekstur di mana piksel di kiri atas adalah RGB (0,0,0) dan dengan demikian hitam, piksel di kanan atas adalah RGB (255,0,0) dan dengan demikian cerah merah dan piksel di kiri bawah adalah RGB (0,255,0) - hijau cerah.
Namun, sebaliknya saya mendapatkan ini di sini di sebelah kanan:
(render quad lurus, tidak ada koreksi)
Pixel kiri atas berwarna hitam, tapi saya hanya mendapatkan warna merah dan hijau yang relatif gelap di sudut lainnya. Nilai RGB mereka adalah (191,0,0) dan (0,191,0). Saya sangat curiga ini ada hubungannya dengan lokasi pengambilan sampel quad: piksel kiri atas dengan benar mengambil sampel sudut kiri atas quad dan mendapatkan (0,0) sebagai koordinat UV, tetapi piksel sudut lainnya tidak mengambil sampel dari sudut-sudut lain dari quad. Saya telah menggambarkan ini di gambar kiri dengan kotak biru yang mewakili quad dan titik putih koordinat pengambilan sampel atas.
Sekarang saya tahu tentang setengah piksel offset yang harus Anda terapkan pada koordinat Anda saat merender layar quads yang disejajarkan dengan Direct3D9. Mari kita lihat hasil apa yang saya dapatkan dari ini:
(quad diberikan dengan offset setengah piksel DX9)
Merah dan hijau menjadi lebih terang tetapi masih belum benar: 223 adalah maksimum yang saya dapatkan pada saluran warna merah atau hijau. Tapi sekarang, saya bahkan tidak memiliki hitam pekat lagi, tetapi sebaliknya abu-abu gelap, kekuningan dengan RGB (32,32,0)!
Yang sebenarnya saya butuhkan adalah rendering semacam ini:
(target membuat, mengurangi ukuran quad)
Sepertinya saya harus bergerak ke kanan dan batas bawah quad saya tepat satu piksel ke atas dan ke kiri, dibandingkan dengan gambar pertama. Maka kolom kanan dan baris paling bawah dari piksel semua harus mendapatkan koordinat UV dengan benar langsung dari batas quad:
VertexPositionTexture[] quad = new VertexPositionTexture[]
{
new VertexPositionTexture(new Vector3(-1.0f, 1.0f, 1f), new Vector2(0,0)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, 1.0f, 1f), new Vector2(1,0)),
new VertexPositionTexture(new Vector3(-1.0f, -1.0f + pixelSize.Y, 1f), new Vector2(0,1)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, -1.0f + pixelSize.Y, 1f), new Vector2(1,1)),
};
Namun ini tidak berhasil dan menyebabkan piksel bagian bawah dan kanan tidak render sama sekali. Saya kira pusat piksel ini tidak tercakup oleh quad lagi dan dengan demikian tidak akan diproses oleh shader. Jika saya mengubah perhitungan pixelSize dengan jumlah kecil untuk membuat quad jumlah kecil lebih besar itu berfungsi ... setidaknya pada tekstur 4x4. Itu tidak bekerja pada tekstur yang lebih kecil dan saya khawatir secara halus mendistorsi distribusi nilai uv pada tekstur yang lebih besar juga:
Vector2 pixelSize = new Vector2((2f / textureWidth) - 0.001f, (2f / textureHeight) - 0.001f);
(Saya memodifikasi perhitungan pixelSize sebesar 0,001f - untuk tekstur yang lebih kecil, misalnya tabel pencarian 1D, ini tidak berfungsi dan saya harus meningkatkannya ke 0,01f atau sesuatu yang lebih besar)
Tentu saja ini adalah contoh sepele dan saya bisa melakukan perhitungan ini lebih mudah pada CPU tanpa harus khawatir tentang pemetaan UVs ke pusat pixel ... masih, harus ada cara untuk benar-benar membuat penuh, lengkap [0, 1] jangkauan ke piksel pada target rendert !?