Почему gl_FragCoord.z ​​отличается от ((pos.z / pos.w) + 1,0) * 0,5? - PullRequest
0 голосов
/ 09 мая 2018

Кто-нибудь знает, почему «глубина» (vertShader) отличается от «gl_FragCoord.z» (отображается из opengl)? Особенно с уменьшением z разница становится больше. Возможно ли, чтобы «глубина» была при более высоких значениях z более точной?

.vsh
out float depth;
void main (void) {
    vec4 pos = mvpMatrix * vertex;
    depth = ((pos.z / pos.w) + 1.0) * 0.5;
    gl_Position = pos;
}

.fsh
in float depth;
void main(void) {
    gl_FragDepth = depth;// or gl_FragCoord.z;
}

1 Ответ

0 голосов
/ 09 мая 2018

Есть несколько проблем с вашим подходом, с основными моментами:

  1. gl_FragCoord.z - это значение гиперболически искаженного пространства окна z. Однако гиперблическое значение z/w для каждой вершины просто линейно интерполируется в экранном пространстве для каждого фрагмента. Но когда вы используете переменную out float depth = (pos.z / pos.w), GL выполнит интерполяцию с коррекцией перспективы, которая будет нелинейной. Вы можете исправить это, используя flat out float depth.

  2. (pos.z/pos.w) даже не имеет смысла. Подумайте об этом: если точка лежит в плоскости, где находится камера, вы получите pos.w=0, и никакого действительного результата. gl_FragCoord.z не имеет этой проблемы, потому что отсечение выполняется до деления, и оно выполнит деление для новой вершины, которая лежит на ближней плоскости, и которую вы никогда не увидите (нет вызова вершинного шейдера для что).

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

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