Эффективность затенения OpenGL с помощью FBO

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

Исходный код:

geometryPassFBO = createFBO(); // position texture, normal texture, colour texture and depth buffer
while (1)
{
bind geometryPassFBO.
allObjects.draw();

bind systemFBO();
for each light
send light info
draw light sphere sampling from position, normal and colour textures.

blit depth buffer from geometryFBO to systemFBO

for each light
light.draw(); // draw a cube to represent the light

2DObjects.draw(); // frame rate, etc...
}

Я находился в процессе настройки трафаретного теста, чтобы проход прохода освещения выполнялся только в том случае, если пиксель установлен во время прохода геометрии (т. Е. Фон с нормальным = 0,0,0 и позицией = 0,0,0 и цветом = 0 , 0,0.

Однако мне было трудно скопировать объединенный буфер глубины / трафарета в буфер глубины / трафарета по умолчанию. Очевидно, это не очень хорошо работает, так как мы не знаем, какой формат использует системный буфер глубины / трафарета. Итак, я прочитал, что было бы лучше настроить другое FBO, где мы можем указать формат буфера глубины / трафарета, выполнить рендеринг к нему, а затем либо перетащить, либо отобразить экранный квад, чтобы вывести его на экран.

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

Мой новый код теперь выглядит так:

geometryPassFBO = createGeometryFBO(); // position texture, normal texture, colour texture and depth buffer
lightingPassFBO = createLightingFBO(); // colour texture and depth buffer
while (1)
{
bind geometryPassFBO.
allObjects.draw();

bind lightingPassFBO();
for each light
send light info
draw light sphere sampling from position, normal and colour textures.

blit depth buffer from geometryFBO to lightingPassFBO

for each light
light.draw(); // draw a cube to represent the light

2DObjects.draw(); // frame rate, etc...

bind systemFBO;
render screen quad sampling from colour texture.
}

Это работает как ожидалось. Чего не ожидалось, так это того, что моя частота кадров подскочила с 25 до 45 кадров в секунду.

Почему это? Как сделать дополнительный проход шейдера для квадрата экрана более эффективным, чем не делать?

Быстрый ответ на вопрос. Что является более эффективным рендерингом четырехъядерных экранов с использованием простого вершинного и фрагментного шейдера для выборки текстуры, основанной на gl_FragCoord, или прерывание цветовой привязки непосредственно к системному FBO?

0

Решение

Ну, это наверное так:

буфер глубины резкости от геометрии FBO до освещенияPassFBO

Как вы указали, преобразование формата может быть медленным. Но так как вы определяете входной и выходной буферы для этой операции blit, они, вероятно, используют один и тот же формат глубины. Таким образом, операция блитинга может продолжаться намного быстрее.

Кроме того, вы, вероятно, даже не должны делать этот блядь. Просто прикрепите geometryFBOбуфер глубины / трафарета lightingPassFBO прежде чем вы сделаете ваши легкие кубики. Просто не забудьте удалить вложение после рендеринга источников света (иначе ваш отложенный проход будет иметь неопределенное поведение, предполагая, что вы читаете из буфера глубины в своем отложенном проходе).

Что касается вашего вопроса о блиттинге против полноэкранного четырехугольника, у меня есть вопрос получше: почему вы накапливаете более 20 источников света в сцене и не используя освещение с высоким динамическим диапазоном? Потому что последний проход для рендеринга на экран должен также использовать тональное отображение для преобразования вашего изображения HDR в LDR для отображения.

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]