На каком этапе рендеринга происходит отсечение? - PullRequest
1 голос
/ 01 ноября 2011

У меня есть некоторый код рисования OpenGL, который я пытаюсь оптимизировать.В настоящее время он проверяет все объекты чертежа на видимость на стороне клиента, прежде чем решить, отправлять ли данные визуализации в OpenGL.(Это проще, чем кажется. Он рисует 2D-сцену, поэтому отсечение является тривиальным: просто проверьте текущие координаты прямоугольника области просмотра.)

Мне кажется, что всю модель можно значительно упростить, передаввся сцена в OpenGL и позволяет GPU позаботиться об отсечении.Но иногда общее количество может быть очень, очень сложным, включая до 100 000 спрайтов, большинство из которых никогда не рендерится, потому что они за кадром, и я бы предпочел не убивать частоту кадров во имя простоты.

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

Ответы [ 3 ]

2 голосов
/ 01 ноября 2011

Отсечение происходит после этапа преобразования вершины до и после пространства NDC; плоскости отсечения применяются в пространстве клипа, отсечение области просмотра выполняется в пространстве NDC. Это один шаг до растеризации. Отсечение означает, что грань, видимая только частично, «обрезается» путем вставки новых вершин на границе видимости или фрагментов за пределами области просмотра, отбрасываемых. То, что вы имеете в виду, обычно называется отбраковкой. Лица, полностью находящиеся вне области просмотра, отбраковываются на одной и той же стадии, как отсечение.

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

Однако использование простой, но эффективной схемы управления данными может значительно повысить производительность на обоих концах. Например, структура пространственного подразделения, такая как дерево Kd, легко строится (вам не нужно балансировать ее). Сортируя вершины в дерево Kd, вы можете опустить (отбросить) большие части дерева, если одна ветка рядом с корнем полностью находится вне области просмотра. При подготовке рисования рамки вы перебираете видимые части дерева, строите список вершин для рисования, а затем передаете этот список команде рендеринга. Деревья Kd можно пройти в среднем за O (n log n).

2 голосов
/ 01 ноября 2011

Отсечение и отбраковка происходят перед обработкой фрагмента. http://www.opengl.org/wiki/Rendering_Pipeline_Overview

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

1 голос
/ 01 ноября 2011

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

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

Отбраковка означает полное выбрасывание чего-либо. Если треугольник не полностью виден, его можно отбраковать. OpenGL не говорит, что отбраковка должна произойти. Помните: спецификация OpenGL определяет поведение, а не производительность.

Как говорится, производители оборудования не глупы. Очевидные усилия, такие как не растеризация треугольников, находящихся вне области просмотра, легко реализуются и улучшают производительность. Практически любое существующее оборудование сделает это.

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

Ваш вопрос, по сути, один из следующих вопросов: «Сколько работы мне нужно сделать, чтобы не отображать объекты вне экрана?» Это действительно зависит от того, какая у вас сцена и как вы ее визуализируете. Вы говорите, что делаете 100 000 спрайтов. Вы делаете 100 000 вызовов отрисовки или эти спрайты являются частью более крупных структур, которые вы визуализируете с большей детализацией? Вы передаете данные вершин в GPU каждый кадр или данные вершин статичны?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...