Отправка 2D и 3D теневых карт в шейдеры - PullRequest
1 голос
/ 13 января 2020

Я пытаюсь реализовать отображение теней для моего простого движка, и я решил, что мне следует объединить Всенаправленное отображение теней (cubemap для точечных источников света) с 2d отображением (для направленных и точечных источников света).

Мой унифицированный блок выглядит так:

#define MAX_LIGHTS 128
//...
struct Light
{
   //light data...
};
//...
layout (std140) uniform Lights
{
    int lightCount; //how many lights were passed into the shader (from 0 to MAX_LIGHTS)
    Light lights[MAX_LIGHTS];
};

У меня к вам два вопроса.

  1. Являются семплером объектами дорого? Является ли следующий код оптимальным для нескольких источников света?

    sampler2D shadowMaps2D[MAX_LIGHTS];
    samplerCube shadowCubemaps[MAX_LIGHTS];
    //...
    if (lights[index].type == POINT_LIGHT)
        CalculateShadow(shadowCubemaps[lights[index].shadowMapNr]);
    else
        CalculateShadow(shadowMaps2D[lights[index].shadowMapNr]);
    

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

  2. Если я правильно понимаю, я не должен объявлять Сэмплер в единых блоках. Так я действительно вынужден циклически проходить через все мои шейдеры и обновлять сэмплеры каждый раз, когда обновляются карты теней? Это пустая трата времени!

1 Ответ

1 голос
/ 16 января 2020

Стоит ли сэмплер объектов дорого?

Этот вопрос немного вводит в заблуждение, поскольку типы данных sampler в GLSL являются только непрозрачными дескрипторами которые ссылаются на текстурные единицы . Что дорого, так это фактическая операция отбора проб. Кроме того, количество текстурных блоков определенной стадии оттенка ограничено. Spe c гарантирует только 16. Поскольку вы не можете повторно использовать одну и ту же единицу для разных типов сэмплеров, это ограничит ваш MAX_LIGHTS до 8 *.

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

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

Если я правильно понимаю, я не должен объявлять сэмплер в единых блоках ,

Правильно.

Так я действительно вынужден циклически проходить все мои шейдеры и обновлять сэмплеры каждый раз, когда карты теней обновляются? Это пустая трата времени!

Нет. Униформы сэмплера необходимо обновлять только в том случае, если изменяется индекс единицы текстуры, из которой вы хотите произвести выборку из (что в идеале никогда). Не тогда, когда связана другая текстура, и не тогда, когда изменяется какое-либо содержимое текстуры.

...