Отказывается плохо для производительности программы в OpenGL?

Я читал эту статью, и автор пишет:

Вот как написать высокопроизводительные приложения на каждой платформе в два простых шага:
[…]
Следуйте рекомендациям. В случае Android и OpenGL это включает в себя такие вещи, как «вызовы пакетной розыгрыши», «не использовать сброс в фрагментарных шейдерах» и т. Д.

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

Может ли кто-нибудь объяснить, почему и когда использование отбрасывания может считаться плохой практикой, и как отбрасывать + depthtest сравнивается с альфой + blend?

Редактирование: после получения ответа на этот вопрос я провел некоторое тестирование, создав фоновый градиент с текстурированным квадратом поверх этого.

  • Использование GL_DEPTH_TEST и фрагмента-шейдера, заканчивающееся строкой « if( gl_FragColor.a < 0.5 ){ discard; } » дало около 32 кадров в секунду .
  • Удаление инструкции if / discard из фрагмента-шейдера увеличило скорость рендеринга примерно до 44 кадров в секунду .
  • Использование GL_BLEND с функцией смешивания "(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)" вместо GL_DEPTH_TEST также привело к примерно 44 кадра в секунду .

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

Обратите внимание, что вы получите ту же проблему от включения альфа-теста.

«Отбросить» плохо для каждого метода ускорения графики – IMR, TBR, TBDR. Это связано с тем, что видимость фрагмента (и, следовательно, глубина) определяется только после обработки фрагментов, а не во время раннего Z или PowerVR's HSR (удаление скрытой поверхности) и т. Д. Дальше вниз по графическому конвейеру что-то получает до удаления, как правило, указывает на его влияние на представление; В этом случае большая обработка фрагментов + нарушение обработки глубины других полигонов = плохой эффект

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

Кстати, только аппаратное обеспечение PowerVR определяет видимость на отложенном шаге (следовательно, это единственный GPU, называемый «TBDR»). Другие решения могут быть основаны на плитке (TBR), но по-прежнему используют методы раннего Z в зависимости от порядка подчинения, как это делает IMR. TBR и TBDR делают смешение на чипе (быстрее, меньше энергии, чем в основной памяти), поэтому смешение должно быть благоприятным для прозрачности. Обычная процедура правильного отображения смешанных полигонов – это отключить запись глубины (но не тесты) и визуализировать tris в обратном порядке глубины (если операция смешивания не зависит от порядка). Часто примерная сортировка достаточно хороша. Геометрия должна быть такой, чтобы избегать больших площадей полностью прозрачных фрагментов. Более одного фрагмента по-прежнему обрабатывается на пиксель таким образом, но оптимизация глубины HW не прерывается, как с отброшенными фрагментами.

Кроме того, просто наличие инструкции «if» в вашем шейдере фрагмента может привести к большому замедлению работы некоторых аппаратных средств. (В частности, графические процессоры, которые в значительной степени конвейерны или имеют одну команду / несколько данных, будут иметь большие штрафы за производительность от инструкций от ветви.) Таким образом, ваши результаты теста могут быть комбинацией оператора «if» и эффектов, упомянутых другими.

(Для чего это стоит, тестирование на моем Galaxy Nexus показало огромное ускорение, когда я переключился на глубину, сортируя мои полупрозрачные объекты и отринув их назад, вместо рендеринга в случайном порядке и отбрасывая фрагменты в шейдере.)

Объект A находится перед объектом B. Объект A имеет шейдер, использующий «discard». Таким образом, я не могу правильно выполнить «Раннее Z», потому что мне нужно знать, какие разделы объекта B будут видны через Object A. Это означает, что Object A должен пройти весь путь через конвейер обработки до почти последнего (Пока обработка фрагмента не будет выполнена), прежде чем я смогу определить, действительно ли объект B виден или нет.

Это плохо для HSR и «Early-Z», поскольку потенциально закрытые объекты должны сидеть и ждать, пока информация о глубине будет обновлена ​​до того, как они будут обработаны. Как уже было сказано выше, это плохо для всех, или, чуть более дружелюбно, «Друзья не позволяют друзьям использовать« Отменить ».