2014-09-14 2 views
1

Прежде чем начать свой вопрос, немного фона. Я начал изучать OpenGL не так давно, и я узнал большую часть того, что знаю об этом here. Я только что получил прошлое 2 учебника, и да, я знаю, что мне, в конце концов, придется узнать о матрицах, но пока ничего фантастического. Так что давайте продолжим.OpenGL weird vertex shader issue

Итак, я немного упростил свою программу, но не беспокойтесь, она по-прежнему воссоздает ту же проблему. Для моего примера мы делаем фиолетовый треугольник. Я делаю обычно, инициализацию GLFW и GLEW, и создать окно со следующими подсказками:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
glfwWindowHint(GLFW_SAMPLES, 8); 

А потом я создаю мое окно:

GLFWwindow* Window = glfwCreateWindow(640, 480, "Foo", NULL, NULL); 
glfwMakeContextCurrent(Window); 
glfwSwapInterval(0); 

Это мои вершины:

float Vertices[] = { 
    0.0f, 0.5f, 1.0f, 
    0.5f, -0.5f, 1.0f, 
    -0.5f, -0.5f, 1.0f 
}; 

Мои шейдеры:

const char* vertex_shader = 
    "#version 330\n" 
    "in vec3 vp;" 
    "void main() {" 
    " gl_Position = vec4 (vp, 1.0);" 
    "}"; 


const char* fragment_shader = 
    "#version 330\n" 
    "out vec4 frag_colour;" 
    "void main() {" 
    " frag_colour = vec4 (0.5, 0.0, 0.5, 1.0);" 
    "}"; 

Все хорошо, я скомпилирую всю программу и вуаля! Фиолетовый треугольник!

Purple Triangle.png

Желтый счетчик на верхнем левом углу находится FRAPS, кстати.

Итак, в любом случае, мой мозг получает это awesome идея (не совсем), что делать, если я это делаю: vec4(vp, vp.z) в вершинном шейдере? Тогда я мог бы получить вид глубины, просто изменив свои z в моем буфере, подумал я. Обратите внимание, что я не думал о замене перспективной матрицы, это был просто своего рода эксперимент. Пожалуйста, ненавидят меня.

И это сработало, изменив значения, я получил что-то такое, что смотрел как глубина, так как в ней было похоже, что она все глубже проникает вдаль. Посмотрите, я изменил верхнюю вершину от 1,0 до 6,0:

Purple Triangle Depth

Теперь вот проблема: я изменить значение 999999999 (9 девяток), и я получаю это:

Purple Triangle Depth 2

Кажется работать. Небольшое отличие от z = 6. Измените его на 999999999999999999999999 (24 девятки)? Нет разницы. Посмотрите сами:

I have run out of ideas to call my images

Так что это странно. Большая разница в цифрах, но небольшая разница визуально. Может быть, вопросы точности? Несколько 24 девятки на 349, и я получаю тот же результат. Кикер: Умножьте 24 девятки на 350, и треугольник исчезнет. Это для меня неожиданность, потому что я думал, что изменение будет видимым и постепенным. Это явно не было. Однако изменение w вручную в вершинном шейдере вместо выполнения vp.z, похоже, дает постепенный результат, а не просто внезапно исчезает. Надеюсь, кто-то может пролить свет на это. Если вы добрались до этого, вы один потрясающий человек, который читает всю мою дерьмо, потому что я благодарю вас.

ответ

4

Ваша модель может рассматриваться как простая форма камеры-обскуры, где точкой отсчета для направления глубины является центр окна. Таким образом, линии, параллельные оси z, встречаются в центре, если они расширены. Оконный центр представляет собой точку бесконечной глубины.

Изменение компонента z (или w) вершины от 1 до 6 является очень большим изменением глубины (вершина в 6 раз дальше от камеры, чем раньше). Вот почему результирующая вершина ближе к центру экрана, чем раньше. Если вы снова удвоите компонент z, он будет немного приближаться к центру экрана (расстояние будет уменьшено в два раза). Но это, очевидно, уже очень близко к центру, поэтому это изменение вряд ли узнаваем. То же самое относится к значению глубины 999999 ....

Вы можете наблюдать это свойство большинства естественных изображений, особенно с дорогами:

Road Image [Источник: http://www.benetemps.com/road-warriors.htm]

Если вы идете по дороге - скажем - 5 метров, вы будете заканчивайтесь где-то внизу изображения. Если вы пройдете еще пять метров, вы продолжаете центр изображения. Еще через пять метров вы еще ближе. Но вы можете видеть, что расстояние на экране становится короче и короче, чем дальше.

+0

Это имеет смысл, спасибо. Я предполагаю, что вершина исчезает, когда я ударяю по плавающей запятой? – Nooble

+0

Наверное, нет. Даже если точность с плавающей запятой вызывает неточные результаты (даже если они находятся за пределами экрана), у вас все еще есть две вершины внутри экрана, и растеризатор создаст правильный треугольник из этих вершин. Не уверен, что произойдет, если у вас есть NaN или бесконечность. –

+0

Тогда почему оно исчезает? – Nooble

1

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

Ваш входной координаты имеют вид:

(x, y, z) 

С помощью vec4(vp, vp.z) в вершинном шейдере, необходимо сопоставить эти координаты:

(x, y, z, z) 

После деления на w, что происходит при преобразовании из клипа координаты к нормализованным координатам устройства, это отображается на:

(x/z, y/z, 1.0f) 

До тех пор, пока z имеет значение 1.0f, это, очевидно, все равно совпадает с (x, y, z), что объясняет, почему 2-я и 3-я вершины не изменяются в вашем эксперименте.

Теперь, применяя это к вашей первой вершины, как вы меняете значение z, он получает отображается как:

(0.0f, 0.5f, z) --> (0.0f, 0.5f/z, 1.0f) 

По мере приближения к бесконечности со значением z, то y координат сходится в направлении 0.5f/infinity, который 0.0f , Так как центр экрана находится на (0.0f, 0.0f), отображаемая вершина сходится к центру экрана.

Кроме того, вершина перемещается все меньше и меньше по мере увеличения значения z. Сбор несколько значений:

z = 1.0f --> y = 0.5f 
z = 10.0f --> y = 0.05f 
z = 100.0f --> y = 0.005f 
z = 1000.0f --> y = 0.0005f 

Например, при изменении z от 100.0f к 1000.0f, y изменения от 0.0045, или лишь немногим более 0,2% от вашей высоты окна. При высоте окна 500 пикселей это будет всего около 1 пикселя.

Почему треугольник полностью исчезает с определенным значением, несколько более загадочным. Я подозреваю, что во время отсечения это должно быть какая-то проблема переполнения/округления.

Смежные вопросы