Как я могу сохранить в текстуре положительные и отрицательные значения?

Dec 03 2020

Я создаю программу, в которой использую графический процессор для вычислений (с помощью фрагментных шейдеров) и мне нужно хранить подписанные значения внутри текстур.

Моя текстура инициализируется с помощью GL_FLOAT, вот так:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);

И из того, что я понимаю об opengl, отдельные тексели должны находиться в диапазоне [0,1], когда используется GL_FLOAT (когда я экспериментировал с glClear, мои значения были бы обрезаны до этого диапазона). Итак, что я делал до сих пор, так это масштабировал мои значения до диапазона [-1,1] на основе их фактического диапазона, а затем преобразовывал это в [0,1] перед записью обратно в текстуру. Следующий шейдер, который должен работать с данными, считывает значение текселя и перемещает его в [-1,1] перед продолжением и так далее ...

Мой вопрос: это правильный способ справиться с отрицательными значениями? Я почти уверен, что повторяющиеся преобразования вызывают накопление ошибок fp, что явно не способствует точности.

Спасибо

Ответы

1 httpdigest Dec 03 2020 at 15:04

См. Также: Разница между форматом и внутренним форматом

Внутренний формат (третий параметр glTexImage2D) определяет , как ГПУ хранит и интерпретирует эти значения, а не тип параметра glTexImage2D(второй к последнему параметру). Этот параметр определяет, как драйвер должен интерпретировать вашу память на стороне клиента / хоста при загрузке в текстуру, которую вы в настоящее время не используете nullptr.

Вы можете использовать подписанный 8 бит GL_RGBA8_SNORMили с плавающей точкой 16-бит GL_RGBA16Fили 32-бит с плавающей точкой GL_RGBA32Fразмером внутреннего формата для текстуры.

Как правило, вы всегда должны использовать внутренний формат определенного размера , чтобы четко указать, что вы хотите и что получаете.

См. Таблицу: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml

Итак, если вам нужно только 8-битное разрешение и значения в диапазоне [-1, 1], вы можете использовать:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_SNORM, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

Предпоследний аргумент на самом деле не имеет значения, потому что мы не загружаем в текстуру какие-либо данные текселей.