ПрограммированиеФорумОбщее

Инверсия матрицы 4x4 (комментарии) (4 стр)

Страницы: 1 2 3 4 5 6 Следующая »
#45
12:13, 27 янв 2020

eDmk

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

#46
15:21, 27 янв 2020

Truthfinder
Вот SIMD-вариант

#47
17:46, 27 янв 2020

eDmk отличается от твоей LookAtMatrix двумя cross. У тебя один cross.

Matrix44f lookAt(const Vec3f& from, const Vec3f& to, const Vec3f& tmp = Vec3f(0, 1, 0)) 
{ 
    Vec3f forward = normalize(from - to); 
    Vec3f right = crossProduct(tmp, forward); 
    Vec3f up = crossProduct(forward, right); 
 
    Matrix44f camToWorld; 
 
    camToWorld[0][0] = right.x; 
    camToWorld[0][1] = right.y; 
    camToWorld[0][2] = right.z; 
    camToWorld[1][0] = up.x; 
    camToWorld[1][1] = up.y; 
    camToWorld[1][2] = up.z; 
    camToWorld[2][0] = forward.x; 
    camToWorld[2][1] = forward.y; 
    camToWorld[2][2] = forward.z; 
 
    camToWorld[3][0] = from.x; 
    camToWorld[3][1] = from.y; 
    camToWorld[3][2] = from.z; 
    camToWorld[3][3] = 1.0;
 
    return camToWorld; 
} 
#48
18:53, 27 янв 2020

ronniko

Мне кажется это неправильно.

#49
18:56, 27 янв 2020

Truthfinder
И тут тоже неправильно?
https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixlookatlh

#50
19:08, 27 янв 2020

nes
> И тут тоже неправильно?

Моё понимание происходящего. Слишком много может быть вариаций для lookat: left/right handed, transposed и так далее. Дабы не быть уже голословным:

    static mtx4 lookat1(vec3 const& eye, vec3 const& at, vec3 const& up) {
        const vec3 z = ~(eye - at), x = ~(up ^ z), y = ~(z ^ x);
        return {
            { x.x, x.y, x.z, -(eye|x) }, // left
            { y.x, y.y, y.z, -(eye|y) }, // up
            { z.x, z.y, z.z, -(eye|z) }, // forward
            { 0.f, 0.f, 0.f,      1.f } };
    }

    static mtx4 lookat2(vec3 const& eye, vec3 const& at, vec3 const& up) { // https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/lookat-function
      const vec3 fwd = ~(eye - at), side = ~(up ^ fwd), u = fwd ^ side;
      return {
            {side.x, side.y, side.z, 0.f }, // right
            {   u.x,    u.y,    u.z, 0.f }, // up
            { fwd.x,  fwd.y,  fwd.z, 0.f }, // forward
            { eye.x,  eye.y,  eye.z, 1.f } };
    }

lookatRH: https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixlookatrh
lookatLH: https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixlookatlh

+ Показать
#51
19:11, 27 янв 2020

lookat2 = transposed(inverted(lookat1))
lookat1 = transposed(inverted(lookat2))

Не знаю как вы, а я ничо не понимаю. И при этом все правы ))

#52
19:13, 27 янв 2020

nes
> И тут тоже неправильно?
> https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixlookatlh

Ну сам посмотри на нижнюю строку, там from.x,y,z
А по ссылке dot.

#53
19:22, 27 янв 2020

Уже до lookAt добрались, для полноты картины нужна перспективная матрица:

Public Sub MatrixPerspectiveFovLH(MOut As D3DMATRIX, ByVal Fov As Single, ByVal Aspect As Single, ByVal zNear As Single, ByVal zFar As Single)
  Dim yScale As Single

  yScale = Cos(Fov * 0.5) / Sin(Fov * 0.5)
  MOut.m11 = yScale / Aspect: MOut.m12 = 0:      MOut.m13 = 0:                              MOut.m14 = 0
  MOut.m21 = 0:               MOut.m22 = yScale: MOut.m23 = 0:                              MOut.m24 = 0
  MOut.m31 = 0:               MOut.m32 = 0:      MOut.m33 = zFar / (zFar - zNear):          MOut.m34 = 1
  MOut.m41 = 0:               MOut.m42 = 0:      MOut.m43 = -zNear * zFar / (zFar - zNear): MOut.m44 = 0
End Sub
#54
19:26, 27 янв 2020

Mikle с такой матрицей Project только msdn вариант.

zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)
    
 xaxis.x           yaxis.x           zaxis.x          0
 xaxis.y           yaxis.y           zaxis.y          0
 xaxis.z           yaxis.z           zaxis.z          0
-dot(xaxis, eye)  -dot(yaxis, eye)  -dot(zaxis, eye)  1

PS: Устроил подставу подстав ! :)

#55
19:31, 27 янв 2020

eDmk

А у тебя векторная библиотека ogl или d3d based?

#56
20:42, 27 янв 2020

Truthfinder
Своя солянка :) По книжкам, по учебникам и т.д.

#57
20:59, 27 янв 2020

Mikle
> для полноты картины нужна перспективная матрица:
Только для OGL матрица будет немного другая. Для reverse depth техники - опять немного другая.
Поэтому у себя я запилил более универсальное вычисление матрицы:

  function CalcPerspectiveMatrix: TMat4;
  var w, h, Q: Single;
      DepthSize: Single;
  begin
    h := (cos(fFOV/2)/sin(fFOV/2));
    w := fAspect * h;
    Q := 1.0/(NearPlane - FarPlane);
    DepthSize := DepthRange.y - DepthRange.x;

    ZeroClear(Result, SizeOf(Result));
    Result.f[0, 0] := w;
    Result.f[1, 1] := h;
    Result.f[2, 2] := DepthRange.x - DepthSize * FarPlane * Q;
    Result.f[2, 3] := 1.0;
    Result.f[3, 2] := DepthSize * NearPlane * FarPlane * Q;
  end; 

Здесь в DepthRange содержатся значения, на которые будут маппиться Near и Far плоскости. После умножения на матрицу Near примет то значение, которое было в DepthRange.x, а Far то, которое было в DepthRange.y.
Таким образом установив:
DepthRange = Vec(-1, 1) получаем матрицу под OGL
DepthRange = Vec(0, 1) получаем матрицу под DX
DepthRange = Vec(1, 0) получаем матрицу под reverse depth технику

#58
9:10, 28 янв 2020

MrShoor
> Поэтому у себя я запилил более универсальное вычисление матрицы:

Вроде как каноничная ogl матрица такая:

m[0][0] = ctg(fovy / 2) / aspect;
m[1][1] = ctg(fovy / 2);
m[2][2] = (N+F)/(N-F);
m[2][3] = -1;
m[3][2] = 2*N*F/(N-F);

Ну если aspect у тебя обратный ещё понятно (y/x вместо x/y), но m23=-1 в ogl, а у тебя всегда 1.

#59
10:36, 28 янв 2020

Truthfinder
> но m23=-1 в ogl, а у тебя всегда 1.
Потому что -1 это для правосторонней системы координат. Правосторонность никак не привязана к GAPI. Поэтому в ОГЛ можно иметь как правостороннюю, так и левостороннюю. То же самое касается и DX. Мой фреймворк заточен под правостороннюю СК, поэтому там строго 1. Но при этом он умеет в разные графические апи и техники, поэтому там DepthRange.

Страницы: 1 2 3 4 5 6 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.