2016-03-23 3 views
1

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

Выход вытяжки шейдера:

layout(location = 0) out vec4 outColor; 

Вывод выбор шейдера:

layout(location = 0) out vec4 selectionInfo0; 
layout(location = 1) out ivec4 selectionInfo1; 

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

Выход объединенного шейдера:

layout(location = 0) out vec4 outColor; 
layout(location = 1) out vec4 selectionInfo0; 
layout(location = 2) out ivec4 selectionInfo1; 

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

Могу ли я написать некоторые фрагменты, а не другие?

void main() 
{ 
    if(Mode == 1){ 
     outColor = vec4(1, 0, 0, 1); 
    } 
    else { 
     selectionInfo0 = vec4(0.1, 0.2, 0.3, 0.4); 
     selectionInfo1 = ivec4(1, 2, 3, 4); 
    } 
} 

Это законный подход? Есть ли что-то, о чем я должен беспокоиться?

+0

Посмотрел, что вы отредактировали, и этот подход в порядке. * но *, по-прежнему взгляните на то, что я упомянул о ветвлении в шейдерном коде. Это медленный процесс, поэтому, по крайней мере, осознавайте беспокойство о скорости, если вы начнете добавлять дополнительные операторы if, так как вы хотите получить решение «один-шейдер для всех» – WearyWanderer

+1

Вставка упоминания ветви здесь, потому что мой ответ больше не был релевантным после редактирования .- "(зачем редактировать два шейдера, когда вы можете редактировать их?)« не всегда хорошее мышление. Здесь хорошо, но вам не нужно иметь одну огромную программу шейдеров для выполнения всех ваших различных операций. Ветвление в шейдерах является очень неэффективным и медленным, и его обычно следует избегать, даже если это означает создание двух отдельных шейдеров для двух различных форм функциональности. – WearyWanderer

+0

[Здесь] (http://stackoverflow.com/questions/30581719/opengl-glsl-uniform-branching-vs-multiple-shaders) соответствующий вопрос по этому вопросу. – AbleArcher

ответ

1

Это законный подход?

Это зависит от того, как вы определяете «законный». Его можно сделать до функции.

Фрагмент discardedполностью или его нет. Если он отбрасывается, то фрагмент имеет (в основном) эффект. Если он не отбрасывается, то все его выходы либо имеют определенные значения (то есть: вы написали им), либо имеют неопределенные значения.

Однако неопределенные значения могут быть в порядке, в зависимости от другого состояния. Например, frambuffer's draw buffer state направляет FS выходные цвета в фактические цветные вложения. Он также может направлять их до GL_NONE, что отбрасывает их. Аналогично, вы можете использовать color write masks для каждого приложения, отключая записи в приложениях, которые вы не хотите писать.

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

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

Что касается характеристик ветвления, то это зависит от Mode. Если это uniform, вы не должны беспокоиться. Современные графические процессоры прекрасно справляются с этим. Если это что-то еще ... ну, вся ваша схема перестает работать по причинам, которые уже были детализированы, поэтому нет причин беспокоиться об этом;)

Что бы я ни говорил, я бы посоветовал такую ​​сложность , Это путаный способ обработки вещей с точки зрения водителя.Кроме того, поскольку вы полагаетесь на то, на что другие приложения не полагаются, вы открываете себя для ошибок драйверов. Ваша идея отличается от традиционной Ubershader, потому что ваши варианты принципиально меняют характер целей и результатов рендеринга.

Так что я предлагаю вам попробовать сделать что-то как можно обычным способом. Если вы действительно хотите свести к минимуму количество отдельных файлов, с которыми вы работаете, используйте #ifdef s и просто исправьте шейдерную строку с помощью #define, исходя из причины, по которой вы ее загружаете. Итак, у вас есть один файл шейдера, но из него построены 2 программы.

+0

'Mode' - это форма. Я пытаюсь решить проблему с дублированием шейдерного кода (количество файлов). Другим является дублированный код приложения, который устанавливает примерно одинаковые формы при вызове двух разных программ. Можете ли вы сказать больше о «Это путаный способ справиться с вещами с точки зрения водителя»? – AbleArcher

+1

@thethuthinnang: * * дублированный код приложения, который устанавливает примерно одинаковые формы при вызове двух разных программ * «Для этого нужны единые буферы. –

+0

Спасибо за помощь. Я всегда благодарен за чтение ваших ответов. – AbleArcher

Смежные вопросы