Когда я установил glStencilFunc(GL_NEVER, . . .)
, фактически отключил весь чертеж, а затем запустил мою программу с шейдером, я не получаю увеличения производительности, позволяя запустить шейдер фрагмента. Я думал, что тест трафарета произошел до программы фрагментов. Разве это не так, или, по крайней мере, не гарантировано? Замена шейдера фрагмента на тот, который просто пишет константу gl_FragColor, приводит к более высокому FPS.Выполняется ли трафаретная проверка OpenGL до или после программы фрагмента?
ответ
Взгляните на следующую схему для трубопровода DX10, это говорит о том, что проверка трафарета выполняется перед пиксельным шейдером:
и то же самое верно и в DX11:
http://4.bp.blogspot.com/_2YU3pmPHKN4/S1KhDSPmotI/AAAAAAAAAcw/d38b4oA_DxM/s1600-h/DX11.JPG
Я не знаю, было ли это предусмотрено в спецификации OpenGL, но было бы вредно для реализации не выполнять трафаретный тест перед запуском программы фрагмента.
Это на самом деле немного того и другого. Операции фрагмента должны выполняться после программы фрагмента, как вы можете видеть в этом OpenGL ES 2.0 pipeline diagram. Тем не менее, многие современные графические карты имеют ранний тест z, который отбрасывает фрагменты раньше, пока вы не записываете на глубину в шейдере фрагмента.
Адрес paper from AMD/ATI that talks about such tests. Я помню, что читал, что спецификация позволяет ранние тесты до тех пор, пока они выполняются до того, как шейдер произведет тот же результат, что и после них, поэтому вы не захотите изменять глубину или отбрасывать фрагмент в шейдере. У этого thread on OpenGL forums есть интересное обсуждение.
В дополнение к модификации глубины фрагмента есть еще несколько вещей, которые могут помешать проведению теста глубины/трафарета перед фрагментарным шейдером. Если z-записи включены, тогда любой способ прерывания фрагмента в шейдере будет делать это, например, альфа-тест или команду шейдера discard
.
Если графический процессор хочет выполнить трафарет/z-тест в той же операции, что и запись z/трафарета, он должен ждать, пока после завершения шейдера фрагмента, чтобы он знал, что фрагмент разрешен для записи в z- буфер. Однако это может различаться между разными картами. По крайней мере, должно быть легко определить, является ли это вашей текущей проблемой.
Как вы можете видеть здесь: http://www.opengl.org/wiki/Stencil_Test Испытание трафарета выполняется после фрагментаShader. Я понимаю, что это плохо для производительности.
Это ответ или комментарий? –
Согласно этой странице: http://www.opengl.org/wiki/Rendering_Pipeline_Overview#Pipeline тесты трафарета и глубины могут выполняться перед шейдером фрагмента, если глубина не изменяется в шейдере фрагмента. Однако, похоже, это не происходит в моем случае (я не пишу gl_FragDepth в шейдере фрагмента). – david