Шейдер вершин GLSL отменяет рендеринг

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

5 ответов


вы не можете завершить рендеринг пикселя в вершинном шейдере (он не имеет дело с пикселями), но вы можете в шейдере фрагментов использовать удалить инструкция.


Я предполагаю, что вы сказали " рендеринг для вершинный быть прекращено". И нет, вы не можете; OpenGL очень строг о соотношении 1:1 входных вершин к выходам для VS. Кроме того, это не будет означать то, что вы хотите, так как вершины не отображаются. примитивы do, и примитив может состоять из нескольких вершин. Например, что значит отбросить вершину в середине треугольной полосы.

вот почему геометрия Шейдеры имеют возможность "отбирать" примитивы; они имеют дело конкретно с примитивом, а не только с одной вершиной. Это делается просто не испуская никаких вершин; GS должны явно испускать вершины, которые он хочет вывести.


вершинные шейдеры теперь имеют возможность отбирать примитивы. Это делается с помощью функция "отбраковки расстояния" OpenGL 4.5. Это как gl_ClipDistance, только вместо отсечения он отбраковывает весь примитив, если одна из вершин переступить порог.


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

но нет, отмена вершины почти бессмысленна. Это фундаментальная единица, на которой построены примитивы. Если вы просто удалите одну вершину, то вы измените растеризованный вывод неопределенными способами.

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


обновление:

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

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

самые дешевые фрагмент-это тот, который вам никогда не придется обрабатывать:)


Я разрабатываю ответ Andon M. Coleman, который заслуживает того, чтобы ИМХО был отмечен как правильный.

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

и для записей сделать всю геометрию отброшенной действительно очень просто: просто напишите вершину вне (-1, -1, -1),(1,1,1) куб,

gl_Position = vec4(2.0, 2.0, 2.0, 1.0);

...и вперед!

надеюсь, что это помогает


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

EDIT: при рендеринге треугольной полосы вы, вероятно, также захотите начать новый примитив, когда вершина будет удалена; вы увидите, почему, если вы исследуете geom. шейдерный. С GL_POINTS было бы меньше проблемы.

и да, если вы посылаете треугольную полосу только из 2 вершин, например, тогда вы действительно ничего не можете сделать - так же, как вы сделали бы, если бы вы прошли в такой вырожденной полосе в первую очередь. Однако это не означает, что поток вершин не может быть изменен на стороне GL.

надеюсь, что это поможет > том