2015-06-05 5 views
1

Мне интересно узнать об использовании буфера трафарета в контексте отложенного рендеринга: все ли фрагментарные шейдеры на пространстве экрана используются в области «окклюзии»?Буфер трафарета и отсроченный рендеринг с использованием OpenGL и GLSL

Вот пример для сайта http://www.learnopengl.com/#!Advanced-OpenGL/Stencil-testing (всего трафарет темы буфера, никакого отношения с отложенным рендерингом):

enter image description here

вопрос: что выражение «остальные отбрасываются» означает здесь? Это означает, что ни один пиксельный шейдер не будет вызываться, где значение равно 0 в пробоотборнике маски ИЛИ для каждого фрагмента на экране будет вызываться пиксельный шейдер, но будет применено условие, отбрасывающее заполнение пикселя, если значение равно 0?

Предположим, что первое изображение слева - результат без буферизации трафарета. Поддержка информации - это квад, состоящий из двух треугольников (мы применяем метод отложенной рендеринга, и поэтому мы работаем в пространстве экрана - размер экрана 500x500). Таким образом, после растеризации он будет вызывать 500 * 500 фрагментарных шейдеров для заполнения буфера кадра, и все они будут использоваться даже в темной области, где нет света. Это означает, что если мы применим модель затенения blinn-phong, это последнее будет применено повсюду на экране EVEN на темной области, и я думаю, что это отходы для производительности.

Таким образом, логической задачей в этом случае должно быть создание маски (с использованием буфера трафарета или с использованием внешнего настраиваемого прохода маскирования с использованием другого буфера кадра для его заполнения) и, наконец, использование затенения blinn-phong модель, например, где значение пикселя в пробоотборнике маски в пространстве экрана равно 1. Таким образом, модель штрихового затенения будет применяться ТОЛЬКО в нашем примере на 2 ящика и на плоскости!

Трюки для правильной работы в первом подходе должны заключаться в том, чтобы добавить условие в шейдер фрагмента, чтобы определить, нужно ли вычислять blinn-phong shading для текущего фрагмента или нет в соответствии со значением выборки текстура маски.

void main(void) 
{ 
    if (texture(MaskSampler, TexCoord.xy).r == 1.0f) 
    { 
     //Execute here Blinn-Phing shading model... 
    } 
    //Else nothing 
} 

Но я задаюсь вопросом (если мы посмотрим на третьей картинке выше), если это возможно, чтобы сказать OpenGL API для вызова фрагмента шейдеры только заинтересованным в цветной области! (это значит, что мы не входим в основной фрагмент шейдера). В этом случае количество используемых шейдеров фреймов будет резко сокращено, а для производительности это будет лучше! Или единственное решение - поставить условие в шейдер фрагмента, как я упоминал выше?

+0

Я бы подумал, что проверка состояния вашего пикселя добавляет накладные расходы, а не просто ORing бит. Ваш GPU обрабатывает всю вашу область параллельно, поэтому вы уже обрабатываете этот пиксель.Добавление условия if добавит больше циклов, чем просто побитовое ИЛИ. –

+0

Как я могу повернуть бит? Таким образом, вы поддерживаете во всех случаях для каждого фрейма в моем примере будет вызываться 500 * 500 пиксельных шейдеров? Даже те, кто находится в темной области, если я использую буфер трафарета? – user1364743

+0

Предполагая, что сцена в изображениях, которые вы предоставили, состоит только из плоскости и двух ящиков, [почти] никакие ресурсы не потрачены впустую для рисования темной области, потому что там ничего не нарисовано. Кроме того, в большинстве случаев выяснение того, где не применять подсчет освещения и выборочно применять его, было бы большим успехом, чем просто применять его повсюду. – n0rd

ответ

1

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

Однако, в случае разветвления, предложенный вами способ работы гораздо менее сложного шейдера может также обеспечить ускорение (скажем, запустить полный шейдер для каждого пикселя). Это связано с тем, что большинство современных драйверов оптимизируют отраслевое прогнозирование на пространственную согласованность. Значение, если все пиксели в локальной области всегда принимают одну ветвь, это можно оптимизировать. В главе GPU Gems описан этот процесс. Конечно, это сильно зависит от сложности шейдера, области и реализации драйвера. Метод метода трафарета гораздо менее двусмыслен.