Применение перспективы с матрицей GLSL
Я не совсем уверен, чего не хватает, но я загрузил равномерную матрицу в вершинный шейдер, и когда матрица была:
GLfloat translation[4][4] = {
{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.2, 0.0, 1.0}};
или около того, мне казалось, что я могу нормально переводить вершины, в зависимости от того, какие значения я выбрал для изменения. Однако при замене этой же однородной матрицы на проекцию изображение не появится. Я пробовал несколько матриц, таких как:
GLfloat frustum[4][4] = {
{((2.0*frusZNear)/(frusRight - frusLeft)), 0.0, 0.0, 0.0},
{0.0, ((2.0*frusZNear)/(frusTop - frusBottom)), 0.0 , 0.0},
{((frusRight + frusLeft)/(frusRight-frusLeft)), ((frusTop + frusBottom) / (frusTop - frusBottom)), (-(frusZFar + frusZNear)/(frusZFar - frusZNear)), (-1.0)},
{0.0, 0.0, ((-2.0*frusZFar*frusZNear)/(frusZFar-frusZNear)), 0.0}
};
и значения, такие как:
const GLfloat frusLeft = -3.0;
const GLfloat frusRight = 3.0;
const GLfloat frusBottom = -3.0;
const GLfloat frusTop = 3.0;
const GLfloat frusZNear = 5.0;
const GLfloat frusZFar = 10.0;
Вершинный шейдер, который, казалось, применил перевод просто отлично:
gl_Position = frustum * vPosition;
Любая помощь приветствуется.
2 ответа
Код для вычисления матрицы перспективы / усеченный выглядит мне правильно. Это устанавливает матрицу перспективы, которая предполагает, что ваша точка зрения находится в начале координат, а вы смотрите вниз по отрицательной оси Z. Ближайшие и дальние значения указывают диапазон расстояний вдоль отрицательной оси Z, которые находятся в пределах объема обзора.
Следовательно, при значениях ближнего / дальнего расстояния 5,0/10,0 диапазон значений z, находящихся в пределах объема вашего просмотра, будет от -5,0 до -10,0.
Если ваша геометрия в настоящее время нарисована вокруг начала координат, используйте перевод в виде матрицы вида (0.0, 0.0, -7.0). Это должно быть применено перед матрицей проекции.
Вы можете либо объединить матрицы вида и проекции, либо передать их отдельно в ваш вершинный шейдер. С отдельной матрицей представления, содержащей приведенный выше перевод, ваш код шейдера может выглядеть так:
uniform mat4 viewMat;
...
gl_Position = frustum * viewMat * vPosition;
Первое, что я вижу, это то, что Z ближняя и дальняя плоскости выбраны в 5, 10. Если ваши вершины не лежат между этими плоскостями, вы ничего не увидите.
Матрица проекции будет принимать все в форме пирамиды, преобразовывать и масштабировать ее в единицу объема -1,1 в каждом измерении.