Мы знаем, что система координат CVV, нетрансформированные оси рисования (CVV == объем канонического вида, объем куба +/- 1, который мы изображаем на экране), имеют ПРАВИЛЬНЫЕ координаты с началом координат в центре.куба CVV, x увеличивается вправо, y увеличивается вверх, а z увеличивается наружу по направлению к вашему глазу.Но не обязательно, чтобы фрагменты с БОЛЬШОЙ, БОЛЕЕ ПОЗИТИВНОЙ Z глубиной в CVV рисовались как «ближе» к нам, а фрагменты с МАЛЕНЬКИМ, БОЛЕЕ НЕГАТИВНЫМ Z в том же месте экрана перекрывались.Почему?
WebGL (и OpenGL-ES, и OpenGL) имеет историческую причуду в иначе чувствительном методе для трехмерного рисования: он определяет «глубину» как вычисленное значение в диапазоне от 0,0 до 1,0, и это НЕпросто значение z
в координатах CVV.
По умолчанию WebGL определяет глубину как:
- 0,0 для «наименьшей» глубины, ближайшей к экрану или камере;(
z = +1
в CVV) - 1.0 для «самой большой» глубины, наиболее удаленной от экрана или камеры;(
z = -1
в CVV)
В то время как графический процессор вычисляет глубину автоматически, для правильных результатов требуются вершины, которые были преобразованы с помощью проекционной матрицы 3D-камеры для имитации объектива камеры.Иногда, если мы не определяем или не используем матрицу проекции, вычисление глубины графического процессора уменьшается до:
depth = 0.5 + 0.5*(gl_position.z / gl.position.w);
Другими словами, без этой матрицы «проецирование камеры»GPU вычисляет «глубину» в обратном направлении - вершины at z = -1
получают глубину 0, когда она ДОЛЖНА быть 1. Для получения дополнительной информации о том, как GPU вычисляет глубину, см .: Как WebGL устанавливает значения в буфере глубины?
Известно, что мы могли бы легко это исправить:1030 *;Тогда все значения z
, которые мы вычисляем, будут иметь обратный знак.(Это немного грязно в сочетании со сложным графом сцены ...).
Мы могли бы оставить значения
z
без изменений и вместо этого сказать WebGL применять другие правила для использования буфера глубины.;это более приемлемое решение.Попробуйте добавить эти строки кода
gl.enable(gl.DEPTH_TEST); // enabled by default, but let's be SURE.
gl.clearDepth(0.0); // each time we 'clear' our depth buffer, set all
// pixel depths to 0.0 (1.0 is DEFAULT)
gl.depthFunc(gl.GREATER); // gl.LESS is DEFAULT; reverse it!
// draw a pixel only if its depth value is GREATER
// than the depth buffer's stored value.
Благодарю моего профессора по компьютерной графике - Джона Э. Тумблина