У меня есть программа OpenGL, которая демонстрирует необычные z-боевые действия, и я не понимаю причины этого. Кажется, большинство боевых действий начинаются по краям треугольников.
Два объекта в упрощенном тестовом примере не пересекаются, как показано ниже. Я убедился, что значения z-near и z-far являются разумными (1 и 100 соответственно). Оба объекта находятся примерно в 2 единицах от начала координат, а камера на показанных изображениях удалена примерно на 10 единиц.
Никаких изменений в настройках глубины OpenGL по умолчанию не было сделано, за исключением того, что было включено тестирование глубины.
Вершинные и фрагментные шейдеры сделаны максимально простыми.
Это использование OpenTK. Я попытался явно создать окно с 32-битным буфером глубины, но это также не дало никакого эффекта.
Я изучил все четыре вопроса, перечисленные в часто задаваемых вопросах по OpenGL. Требования к буферизации глубины.
Отключение проверки глубины устраняет конфликты, оставляя объекты перекрывающимися в порядке отрисовки. В программе не используется отбраковка или трафарет.
Существуют ли какие-либо другие вероятные причины такого рода z-борьбы?
Матрица вершин создается следующим образом:
Matrix4 transform_matrix;
Matrix4.CreatePerspectiveFieldOfView((float) (45 * Math.PI / 180), aspect_ratio, 1, 100, out transform_matrix);
transform_matrix = Matrix4.Mult(transform_matrix, CameraMatrix);
и CameraMatrix является результатом этого метода:
public void TransformMatrix(out Matrix4 m)
{
var t = Matrix4.Identity;
t.Column3 = new Vector4(Offset);
var rx = Matrix4.Identity;
var sine_x = (float) Math.Sin(-RotationX * Math.PI / 180);
var cos_x = (float) Math.Cos(-RotationX * Math.PI / 180);
rx.Row1 = new Vector4(0, cos_x, -sine_x, 0);
rx.Row2 = new Vector4(0, sine_x, cos_x, 0);
var ry = Matrix4.Identity;
var sine_y = (float) Math.Sin(-RotationY * Math.PI / 180);
var cos_y = (float) Math.Cos(-RotationY * Math.PI / 180);
ry.Row0 = new Vector4(cos_y, 0, sine_y, 0);
ry.Row2 = new Vector4(-sine_y, 0, cos_y, 0);
var n = Matrix4.Mult(rx, t);
n = Matrix4.Mult(ry, n);
m = n;
}
Обновлять
Это происходит только на карте NVIDIA. Протестировал с Интелом, проблем не было.