Войти
ПрограммированиеФорумГрафика

GL-Проекция

Advanced: Тема повышенной сложности или важная.

Страницы: 1 2 Следующая »
#0
(Правка: 10:43) 10:40, 9 авг. 2018

Всем привет!

Подскажите пожалуйста, как развернуть проекцию как это сделано в GL?
Вот видео как выглядит у меня после проекции через перспективную матрицу.
Контурами показана правильная проекция. Как должно выглядеть в итоге.
В общем у меня проекция «недоповернутая». Как ее повернуть?
Она вроде зеркалится как-то, но вот как - не понятно.

+ Показать

Это код проекции:

+ Показать

#1
(Правка: 15:37) 15:21, 9 авг. 2018

Если честно, я не понимаю как ты проектируешь. У тебя искажена перспектива из-за того, что у тебя не участвует гомогенная координата в вычислениях.

Должно быть крайне просто.

vec4 p = vp * vec4(v, 1.0);
Где p - координаты в пространстве камеры.
vp - матрица  проекция * вид
v - мировая координата.

В ndc (-1.0 ... 1.0):

p /= p.w;

В экранные (0.0 ... 1.0):

p = p * 0.5 + 0.5;

#2
(Правка: 17:02) 17:01, 9 авг. 2018

vindast
> У тебя искажена перспектива из-за того, что у тебя не участвует гомогенная
> координата в вычислениях.

p /= p.w;
плюсую

т.е. код должен быть как-то так:

  N := (S * FFrustumMatrix^);

  N.X := N.X / W;
  N.Y := N.Y / W;
  N.Z := N.Z / W;
 
  N.X := N.X * F.n * 0.5;
  N.Y := N.Y * F.n * 0.5 / FHorzAspect;
...если ты этого при умножении не делаешь.
Если у тебя в TVertex-е нет W, то либо нужно завести, либо при умножении (w обсчитывать и при деление там же выполнять)

#3
(Правка: 17:35) 17:32, 14 авг. 2018

В общем непонятно как проекция происходит.
По разному пробовал, а надо так как после поворота (см. видео):

+ Показать

Код проекции:

+ Показать

#4
(Правка: 20:42) 20:38, 15 авг. 2018

В прямой проекции проблем нет:

+ Показать

А сперспективной матрице начинается беда :(

#5
(Правка: 20:46) 20:42, 15 авг. 2018

eDmk, хочешь скину заведомо рабочий код матрицы перспективной проекции? На с++, я же объяснял в чем ошибка.
У тебя матрица вида есть?

#6
20:46, 15 авг. 2018

У меня есть. Он работает 100%. Причем их целых 2. С тангенсом и катангенсом.
Их OpenGL нормально принимает. Тут другая хитрость. OpenGL делает инверсию камеры после проекции.
Т.е мы видим сцену в прямой проекции со стороны -Z. Причем не двигая камеру никуда. Вот этот эффект и нужен.
Это эффект инверсной камеры через проекцию. Может отрицательный Z-Buffer?

#7
(Правка: 20:47) 20:47, 15 авг. 2018

> У тебя матрица вида есть?
>
Да. Она нормальная абсолютно.

+ Показать
#8
(Правка: 20:53) 20:51, 15 авг. 2018

а почему положение matA и matB у тебя разное в примерах?

#0

    matA := -(2.0 * f * n) / d;
    matB := -(f + n) / d;
    //Z
    FFrustumMatrix^[2, 0] := 0.0; //8
    FFrustumMatrix^[2, 1] := 0.0; //9
    FFrustumMatrix^[2, 2] := matA; //10
    FFrustumMatrix^[2, 3] := matB; //11

#3

    matA := -(f + n) / d; //Разворот Z-Buffer'а наоборот
    matB := -(2.0 * f * n) / d;

    //Z
    FM^[0, 2] := 0.0; //8
    FM^[1, 2] := 0.0; //9
    FM^[2, 2] := matA; //10
    FM^[3, 2] := matB; //11


#3 правильный, во всяком случае с OpenGL матрицей совпадает.

#9
(Правка: 21:02) 20:51, 15 авг. 2018

eDmk, стоять.
Смотрим мы в сторону z-
Ты не правильно координаты преобразуешь.
Ты после того как умножил x = vp * Vertex должен делить на w, ты просто хочешь получить линейную глубину, делать это надо не так.

#10
20:58, 15 авг. 2018

vindast
> Смотрим мы в сторону z+
кстати , в opengl по-умолчанию мы смотрим в сторону z-
(т.е. видны объекты только с отрицательной координатой z. чем отрицательнее, тем дальше)

"лечится" с помощью scale(1,1,-1)

#11
21:00, 15 авг. 2018

skalogryz, да да, напутал.

#12
(Правка: 21:18) 21:11, 15 авг. 2018

>а почему положение matA и matB у тебя разное в примерах?
Из разных книжек взял. Последняя из официальной книжки по OpenGL.
Обе версии правильные. Там проекции немного по разному делаются.
Первая: -n / P.Z * P.X
Вторая: 1.0 / P.Z.

>"лечится" с помощью scale(1,1,-1)
Да, лечится, только вектор света становится инверсным.
Это в формулах надо учитывать. В опенГл такого нет.
Там все считается в прямой проекции. В пространстве +Z.

У меня делается так: PreProjectPos := WorldPos * MVP;
А потом делается проекция. Если принимать, что Z должен быть отрицательным (для позиции отрицательной камеры),
то после умножения на MVP происходит инверсия треугольников, т.е. нормали становятся вывернутыми.
Естественно получается лажа. Видимо нужен или отрицательный z-buffer, или еще какая хитрость есть.

#13
(Правка: 21:48) 21:48, 15 авг. 2018

eDmk
> Да, лечится, только вектор света становится инверсным.
> Это в формулах надо учитывать. В опенГл такого нет.
> Там все считается в прямой проекции. В пространстве +Z.
ээ.... вектор света зависит от матрицы проекции? или как?

у тебя Delphi или Lazarus? Если последний, я бы тебе свой пример софтовой эмуляции opengl бы скинул

#14
(Правка: 22:07) 22:00, 15 авг. 2018

>
>должен делить на w
Это просто приведение к единичным координатам.
Если умножить матрицу фрустума на экранные коэффициенты,
то куб фрустума расширяется до размеров экрана и делить на W не нужно.
Это для видюхи нужно, а у меня софтрендер. Лишнее деление - тормоза.

>
>у тебя Delphi или Lazarus?
У меня и то и другое. Мне только проекция нужна, но демку вашу посмотрел бы.
Если не сложно в личном сообщении.

>
>ээ.... вектор света зависит от матрицы проекции? или как?
В том то и дело, что вектор света не зависит ни от какой матрицы. Он в +Z.
В этом и хитрость опенГл. Инверсия камеры без изменения положительных координат :)
Ты ему положительные координаты, а смотришь на объекты со стороны -Z.
Ну естественно через перспективную проекцию.
Если ОпенГл скормить прямую проекцию, то ничего не видно, т.к. скорее всего все лежит в -Z.
Куб фрустума состоит из [-1..0..1]. Проекция идет в -Z, т.е. в [-1..0].
Перспективная матрица разворачивает это в [0..1], а вот проекция остается за кадром из-за клиппера видюхи.
Фиг посмотришь что там в -Z ;)

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика