Bagaimana cara menyimpan nilai positif dan negatif dalam sebuah tekstur?
Saya membuat program di mana saya menggunakan GPU untuk melakukan perhitungan (melalui fragmen shaders) dan perlu menyimpan nilai yang ditandatangani di dalam tekstur.
Tekstur saya diinisialisasi dengan GL_FLOAT, seperti ini:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);
Dan dari apa yang saya pahami tentang opengl, texel individu harus berada dalam kisaran [0,1] ketika GL_FLOAT digunakan (ketika saya bereksperimen dengan glClear, nilai saya akan dipotong ke kisaran ini). Jadi apa yang telah saya lakukan sejauh ini adalah menskalakan nilai saya ke kisaran [-1,1] berdasarkan kisaran sebenarnya, lalu mengubahnya menjadi [0,1] sebelum menuliskannya kembali ke tekstur. Shader berikutnya yang perlu bekerja dengan data membaca nilai texel dan memindahkannya ke [-1,1] sebelum melanjutkan dan seterusnya ...
Pertanyaan saya adalah, apakah ini cara yang tepat untuk menghadapi nilai-nilai negatif? Saya cukup yakin konversi berulang menyebabkan kesalahan fp terakumulasi yang jelas tidak baik untuk akurasi.
Terima kasih
Jawaban
Lihat juga: Perbedaan antara format dan format internal
The format internal (parameter ketiga glTexImage2D
) memutuskan berapa toko GPU dan menafsirkan nilai-nilai, bukan tipe parameter glTexImage2D
(kedua-untuk-terakhir parameter). Parameter itu memutuskan bagaimana driver harus menafsirkan memori sisi klien / host Anda saat mengunggah ke tekstur, yang saat ini tidak Anda gunakan dengan menggunakan nullptr
.
Anda dapat menggunakan format internal berukuran 8-bit GL_RGBA8_SNORM
atau 16-bit GL_RGBA16F
atau 32-bit GL_RGBA32F
berukuran floating-point bertanda tangan untuk tekstur.
Umumnya, Anda harus selalu menggunakan format internal berukuran agar eksplisit tentang apa yang Anda inginkan dan dapatkan.
Lihat tabel di: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml
Jadi, jika Anda hanya membutuhkan resolusi 8-bit, dan nilai dalam rentang [-1, 1], Anda dapat menggunakan:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_SNORM, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
Argumen kedua hingga terakhir sebenarnya tidak relevan, karena kami tidak mengunggah data texel apa pun ke tekstur.