Как передать массив структур изменения размера в шейдер glsl

Чтобы добавить динамическое освещение в свое приложение, я подумал, что могу представить каждый объект, отбрасывающий тень, как массив чисел с плавающей запятой (каждые 3 числа — это вектор, а каждые 9 — треугольник). И так, чтобы отбрасывать ВСЕ возможные тени, мне нужен массив этих массивов (если бы это был С++, я бы сделал массив векторов).

Есть ли способ создать что-то подобное в шейдере glsl, используя либо SSBO, либо униформу?

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


person Makogan    schedule 14.01.2018    source источник
comment
Как еще тогда можно было бы делать динамические тени?   -  person Makogan    schedule 15.01.2018
comment
Карты теней сегодня являются наиболее широко используемой техникой (по крайней мере, в играх ведутся активные исследования по включению мягких теней и т. д.). Shadow Volumes — еще одна техника. Должно быть довольно легко найти учебник по OpenGL, если вы погуглите их.   -  person BDL    schedule 15.01.2018
comment
Текстуры не будут работать, они требуют, чтобы оба размера были одинаковыми, что и является моей проблемой.   -  person Makogan    schedule 15.01.2018
comment
С каких это пор Текстура требует, чтобы оба измерения были одинаковыми? Вы можете создать текстуру любого размера.   -  person BDL    schedule 15.01.2018
comment
Извините, я имею в виду, что если у вас есть 2D-текстура размеров mxn, то вторым измерением всегда будет n, и я не помню текстур, допускающих произвольные изменения во вторых измерениях при их повторении.   -  person Makogan    schedule 15.01.2018
comment
Отображение теней @BDL имеет артефакты и на самом деле будет медленнее, чем то, что я планирую сделать для этого.   -  person Makogan    schedule 15.01.2018
comment
В OpenGL нет полностью динамического буфера (как и в C++ или где-либо еще). Если размер изменится, вам придется выделить память. Что вы можете сделать, так это выделить достаточно памяти для всех ситуаций, но не использовать ее всю. Можно, например, иметь дополнительный юниформ, хранящий до какой строки заполняется текстура. (То же самое относится и к SSBO или любому другому буферу).   -  person BDL    schedule 15.01.2018
comment
Если вы найдете метод рендеринга теней без каких-либо артефактов, который к тому же быстрее, чем традиционные методы (в чем я сомневаюсь, но кто знает), дайте мне знать, мне будет очень интересно, как вы это делаете. Мое текущее предположение состоит в том, что вы собираетесь использовать какую-то технику трассировки лучей, но я почти уверен, что это не сработает. Я действительно не хочу отговаривать вас от попытки, просто хочу, чтобы вы знали, что вы можете тратить много времени впустую.   -  person BDL    schedule 15.01.2018
comment
Ну, я знаю, что это быстрее, но это не вообще. По сути, я работаю над движком, который имеет соглашение о вокселизации, и я знаю, что все статические объекты находятся в определенных заранее определенных позициях, поэтому я могу минимизировать накладные расходы на трассировку лучей, потому что я могу отбросить подавляющее большинство треугольников перед вычислением. пересечение лучей. Это приводит к тому, что требуется меньше операций, чем при двукратном рендеринге сцены с последующим использованием матриц преобразования для сравнения теста глубины с отображением теней.   -  person Makogan    schedule 15.01.2018
comment
Наверняка у вас просто куча треугольников, а объекты на самом деле не имеют значения?   -  person user253751    schedule 15.01.2018
comment
Объекты имеют значение в том смысле, что мне нужны пакеты, которые хэшируются в вокселизированные координаты x, y, z в мире.   -  person Makogan    schedule 15.01.2018
comment
Что ж, похоже, вы знаете, что делаете лучше, чем кто-либо другой. Вы можете использовать текстуру и обращаться с ней как с одномерным массивом. К сожалению, 1D-текстуры весьма ограничены по размеру (16384 пикселя на моем ПК), поэтому вы сопоставляете свой 1D-массив обратно с 2D-текстурой.   -  person user253751    schedule 15.01.2018
comment
@Makogan: Я знаю, что все статические объекты находятся в определенных заранее определенных позициях, Тогда зачем вам этот массив массивов?   -  person Nicol Bolas    schedule 15.01.2018
comment
Я знаю, ГДЕ они, но я не знаю, ЧТО они, т.е. я знаю их положение, но не их геометрию.   -  person Makogan    schedule 15.01.2018


Ответы (1)


Вы думаете одновременно слишком высокоуровнево и слишком низкоуровнево. Вы говорите, что вам нужна куча массивов, но это не так. Что вам нужно, так это способ получить данные вершин для конкретного объекта в сцене. Это вовсе не обязательно кодировать как «массив этих массивов».

Вместо этого закодируйте его как единый массив данных вершин. Каждый объект имеет индексы, которые определяют расположение в этом массиве данных вершин.

layout(std430) buffer obj_data
{
  uvec2 objects[];
};

layout(std430) buffer vertex_data
{
  vec4 vertices[]; //NEVER use `vec3`s in storage blocks
};

objects — это массив, где каждый uvec2 представляет определенный объект. Компонент x этого uvec2 является смещением в vertices, где начинаются данные его вершины. А y — это количество вершин для чтения, начиная с x.

Итак, vertices[objects[10].x] — это первая вершина данных для объекта с индексом 10.

И кстати:

если бы это был C++, я бы сделал массив векторов

Если бы это был C++, я бы кодировал его более или менее так же, как для GLSL: хранил бы все данные вершин в одном массиве, и каждый объект ссылался бы на свой непрерывный фрагмент этого массива. Доступ к нему более эффективен, чем к массиву из vector, и требует гораздо меньше выделений.

person Nicol Bolas    schedule 15.01.2018