C++, OpenGL Z-буферный препасс

Я делаю простой воксельный движок (думаю, Minecraft) и в настоящее время нахожусь на стадии избавления от окклюдированных лиц, чтобы получить немного драгоценного fps. Я не очень экспериментировал с OpenGL и не совсем понимаю, как работает магия glColorMask.

Вот что у меня есть:

// new and shiny
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// this one goes without saying
glEnable(GL_DEPTH_TEST);

// I want to see my code working, so fill the mask
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

// fill the z-buffer, or whatever
glDepthFunc(GL_LESS);
glColorMask(0,0,0,0);
glDepthMask(GL_TRUE);

// do a first draw pass
world_display();

// now only show lines, so I can see the occluded lines do not display
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

// I guess the error is somewhere here
glDepthFunc(GL_LEQUAL);
glColorMask(1,1,1,1);
glDepthMask(GL_FALSE);

// do a second draw pass for the real rendering
world_display();

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

3 ответа

Решение

Похоже, вы не очищаете буфер глубины.

Вам нужно включить глубину записи (через glDepthMask(GL_TRUE);) пока вы пытаетесь очистить буфер глубины с помощью glClear, Вы, вероятно, все еще отключили его в предыдущем кадре, в результате чего все ваши очистки не выполняются в последующих кадрах. Просто переместите glDepthMask позвонить до glClear,

glColorMask и glDepthMask определяют, в какие части буфера кадра фактически записываются данные.

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

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

Если у вас есть что-то смешанное, удалите его со стадии "раннего Z".

На первом проходе вы установили

glDepthMask(1); // enable depth buffer writes
glColorMask(0,0,0); // disable color buffer writes
glDepthFunc(GL_LESS); // use normal depth oder testing
glEnable(GL_DEPTH_TEST); // and we want to perform depth tests

После завершения прохода Z вы немного меняете настройки

glDepthMask(0); // don't write to the depth buffer
glColorMask(1,1,1); // now set the color component

glDepthFunc(GL_EQUAL); // only draw if the depth of the incoming fragment
                       // matches the depth already in the depth buffer

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

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

Чтобы сохранить дальнейшую геометрию, взгляните на Окклюзионные Запросы. При запросах окклюзии вы спрашиваете, сколько GPU, если какие-либо фрагменты проходят все тесты. Это воксельный движок, вы, вероятно, используете дерево октодеев или Kd. Рисование пространственно-разделительных граней (с помощью glDepthMask(0), glColorMask(0,0,0)) ветвей дерева перед прохождением по ветке говорит вам, видна ли вообще какая-либо геометрия в этой ветке. Это в сочетании с почти-далеко отсортированным обходом и (грубым) усечением усеченного дерева даст вам ОГРОМНОЕ повышение производительности.

z-pre pass может работать с полупрозрачными объектами. если они полупрозрачные, не визуализируйте их в препассе, а затем выполните сортировку и визуализацию.

Другие вопросы по тегам