Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / GL-Проекция

GL-Проекция

Advanced: Тема повышенной сложности или важная.
Страницы: 1 2 Следующая »
eDmkУчастникwww9 авг. 201810:40#0
Всем привет!

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

+ Показать

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

+ Показать

Правка: 9 авг. 2018 10:43

vindastПостоялецwww9 авг. 201815:21#1
Если честно, я не понимаю как ты проектируешь. У тебя искажена перспектива из-за того, что у тебя не участвует гомогенная координата в вычислениях.

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

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;

Правка: 9 авг. 2018 15:37

skalogryzУчастникwww9 авг. 201817:01#2
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 обсчитывать и при деление там же выполнять)

Правка: 9 авг. 2018 17:02

eDmkУчастникwww14 авг. 201817:32#3
В общем непонятно как проекция происходит.
По разному пробовал, а надо так как после поворота (см. видео):
+ Показать

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

+ Показать

Правка: 14 авг. 2018 17:35

eDmkУчастникwww15 авг. 201820:38#4
В прямой проекции проблем нет:
+ Показать

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

Правка: 15 авг. 2018 20:42

vindastПостоялецwww15 авг. 201820:42#5
eDmk, хочешь скину заведомо рабочий код матрицы перспективной проекции? На с++, я же объяснял в чем ошибка.
У тебя матрица вида есть?

Правка: 15 авг. 2018 20:46

eDmkУчастникwww15 авг. 201820:46#6
У меня есть. Он работает 100%. Причем их целых 2. С тангенсом и катангенсом.
Их OpenGL нормально принимает. Тут другая хитрость. OpenGL делает инверсию камеры после проекции.
Т.е мы видим сцену в прямой проекции со стороны -Z. Причем не двигая камеру никуда. Вот этот эффект и нужен.
Это эффект инверсной камеры через проекцию. Может отрицательный Z-Buffer?
eDmkУчастникwww15 авг. 201820:47#7
> У тебя матрица вида есть?
>
Да. Она нормальная абсолютно.
+ Показать

Правка: 15 авг. 2018 20:47

skalogryzУчастникwww15 авг. 201820:51#8
а почему положение 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 матрицей совпадает.

Правка: 15 авг. 2018 20:53

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

Правка: 15 авг. 2018 21:02

skalogryzУчастникwww15 авг. 201820:58#10
vindast
> Смотрим мы в сторону z+
кстати , в opengl по-умолчанию мы смотрим в сторону z-
(т.е. видны объекты только с отрицательной координатой z. чем отрицательнее, тем дальше)

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

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

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

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

Правка: 15 авг. 2018 21:18

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

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

Правка: 15 авг. 2018 21:48

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

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

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

Правка: 15 авг. 2018 22:07

Страницы: 1 2 Следующая »

/ Форум / Программирование игр / Графика

2001—2018 © GameDev.ru — Разработка игр