Передача больших данных вокселей в шейдер GLSL - PullRequest
2 голосов
/ 19 февраля 2012

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

В настоящее время я храню данные вокселей в 32x32x32 блоках по 4 бита в каждом:

struct MapData {
    char data[32][32][16];
}

MapData *world = new MapData[(width >> 5) * (height >> 5) * (depth >> 5)];

Что яЯ пытаюсь сделать с этим, это отправить его в мои вершинные и фрагментные шейдеры для обработки и рендеринга.Я видел несколько различных способов сделать это, но я не знаю, какой из них будет лучше для этого.

Я начал с формата sampler1D, но это приводит к выводу с плавающей запятой между 0и 1. У меня также было подозрение, что он хранит его как 16 бит на воксель.

Что касается объектов с единым буфером, я пытался и не смог реализовать это.

Моя самая большая проблема со всемииз этого не нужно отправлять всю карту в GPU каждый кадр.Я хочу иметь возможность загружать карты размером до ~ 256 МБ (1024x2048x256 вокселов), поэтому мне нужно иметь возможность отправить их все один раз, а затем повторно отправить только те блоки, которые были изменены.

Что такоелучшее решение для этого краткого написания OpenCL для обработки видеопамяти для меня.Если есть лучший способ хранения моих вокселей, который облегчает это, я открыт для других форматов.

1 Ответ

7 голосов
/ 19 февраля 2012

Если вы просто хотите получить доступ к большому блоку памяти в шейдере, вы можете использовать текстуру буфера . Очевидно, что для этого требуется более поздняя версия GL (3.0 или выше), поэтому вам нужно аппаратное обеспечение DX10 или лучше.

Концепция довольно проста. Вы делаете буферный объект, который хранит ваши данные. Вы создаете текстуру буфера, используя типичную команду glGenTextures, а затем glBindTexture ее целевое значение GL_TEXTURE_BUFFER. Затем вы используете glTexBuffer, чтобы связать ваш буферный объект с текстурой.

Теперь вы, похоже, хотите использовать 4 бита на воксель. Таким образом, ваш формат изображения должен быть одноканальным 8-битным целым форматом без знака. Ваш glTexBuffer вызов должен быть примерно таким:

glTexBuffer(GL_TEXTURE_BUFFER, GL_RUI8, buffer);

где buffer - буферный объект, в котором хранятся ваши данные вокселей.

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

Вы привязываете буферную текстуру для рендеринга, как и любая другая текстура.

Вы используете usamplerBuffer тип сэмплера в своем шейдере, потому что это беззнаковая целочисленная буферная текстура. Вы должны использовать команду texelFetch для доступа к данным из нее, которая принимает целочисленные координаты текстуры и игнорирует фильтрацию. Что, конечно, именно то, что вы хотите.

Обратите внимание, что текстуры буфера имеют ограничения по размеру. Однако ограничения по размеру часто составляют большой процент видеопамяти.

...