Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
#1

Объединение view и projection матриц - C++

19.09.2016, 11:45. Просмотров 920. Ответов 28
Метки нет (Все метки)

Здравствуйте!

Извиняюсь заранее, если "не туда" пишу, тут много разделов, выбирал между "математикой" и "играми".

Если издалека, то чтобы обработать вертексы, мы их пропускаем через transformation матрицу. Она состоит из трёх: translation, rotation и scaling. Тут есть два варианта перемножения. Либо перемножить матрицы в одну, а потом пропускать вертексы через неё либо пропустить вертексы сначала через translation матрицу, потом то, что получится через rotation и потом результат пропустить ещё и через scaling. Я провёл несколько подсчётов и убедился, что первый вариант быстрее (если в объекте больше четырёх вертексов, что почти всегда и бывает).

Дальше мы пропускаем вертексы через view и projection матрицы. И тут, я тоже подумал: "окей, вместо того чтобы перемножать вертексы на view матрицу, и потом снова новые вертексы перемножать на projection матрицу, лучше я их объединю в viewProjection матрицу и пропущу вертексы через неё".
Здесь и появляется проблема. Моя projection матрица является перспективной. А view матрица имеет перемещение по оси z (0.0f, 0.0f, 15.0f), (view матрицу мы инверсируем, в итоге получаем -15.0f). И дело в том, что я получаю разные результаты: если я сначала перемножаю вертексы на view матрицу, а потом получившиеся перемножаю на projection матрицу, то всё работает. А если я сначала перемножаю эти две матрицы и перемножаю вертексы на viewProjection матрицу, то получается... да вообще ничего не получается. Там компонента z и w совсем другая становится.

Вы не подскажете, это у меня проблема в вычислениях где-то, потому что всё должно работать одинаково независимо от метода перемножения или это известная проблема, которая не лечится и в связи с этим перемножать матрицы в одну нельзя в принципе.

Я пока код решил не скидывать, так как пока вопрос теоретический. Но, если нужен будет, то всё выложу и подробно расскажу.

Заранее спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2016, 11:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Объединение view и projection матриц (C++):

Умножение треугольных матриц«Методы обработки разреженных матриц» - C++
Нужно перемножить треугольные матрицы в обычном виде и в свёрнутом. С обычным проблем нет. Доступ к элементам свёрнутой матрицы...

Транспонирование матриц. Произведение транспонированных матриц - C++
Найти матрицу С: C=ATBTB; A=\begin{bmatrix}1\\ 1\\ 1\end{bmatrix} B=\begin{bmatrix}1 & 2 & 0 \\ 0 & 1 & 2\end{bmatrix} ...

Вычисление степени матрицы, вычисления произведения двух матриц, вычисление суммы двух матриц - C++
Здравствуйте, помогите решить, пожалуйста: Заданы две квадратные матрицы А и В. Вычислить матрицу...

Объединение матриц - Pascal
как можно объединить 2 матрицы типа char? чтобы результат второй записывался с права как на картинке я хотел так, но пишет типо...

Объединение вложенных матриц - MathCAD
Здравствуйте) не могу объединить вложенные матрицы дело в том что количество их неизвестно скриншот он возвращает матрицу...

Объединение матриц в MathCad - MathCAD
Добрый день или вечер, у меня возник такой вопрос имеется вектор размерности 3 каждый элемент которого это матрица 2 на 4 первая строка...

28
TanaTiX
Модератор
2753 / 1600 / 153
Регистрация: 19.02.2011
Сообщений: 5,787
19.09.2016, 17:43 #2
Цитата Сообщение от Pro100Tom Посмотреть сообщение
Я пока код решил не скидывать
Код на чем пишется?
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
19.09.2016, 18:23  [ТС] #3
Цитата Сообщение от TanaTiX Посмотреть сообщение
Код на чем пишется?
С++
Скинуть?
0
TanaTiX
Модератор
2753 / 1600 / 153
Регистрация: 19.02.2011
Сообщений: 5,787
19.09.2016, 18:52 #4
Цитата Сообщение от Pro100Tom Посмотреть сообщение
Скинуть?
Нет, туда сейчас тема переедет. В 3D-моделировании ей явно не место. Хотя наверняка там попросят код, так что скинуть лишним не будет.
1
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
19.09.2016, 19:14 #5
Цитата Сообщение от Pro100Tom Посмотреть сообщение
А если я сначала перемножаю эти две матрицы и перемножаю вертексы на viewProjection матрицу, то получается... да вообще ничего не получается. Там компонента z и w совсем другая становится.
Если сами матрицы построены правильно и правильно работает перемножение то все там получается. Причем произведение всех трех сразу Model*View*Projection. Именно в таком порядке. При этом обычно еще хранят произведение View*Projection потому как оно меняется обычно раз в кадр а Model меняется на каждый объект, поэтому перемножают Model * ViewProjection для экономии матричных умножений при переходе от объекта к объекту.

Добавлено через 3 минуты
Цитата Сообщение от Pro100Tom Посмотреть сообщение
view матрицу мы инверсируем, в итоге получаем -15.0f
Зачем ее инвертировать? Она при построении путем LookAt уже получается инвертированная.
2
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
19.09.2016, 19:18  [ТС] #6
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Зачем ее инвертировать?
CPU rendering, никаких дополнительных либ, всё ручками сделал, вплоть до алгоритма рисования и закрашивания треугольников.

Добавлено через 1 минуту
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Если сами матрицы построены правильно и правильно работает перемножение то все там получается.
Спасибо! Буду искать ошибку. Как вернусь с работы, скину весь проект и ключевые функции. Если кто сможет помочь найти ошибку, буду очень признателен.
0
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
19.09.2016, 19:23 #7
Цитата Сообщение от Pro100Tom Посмотреть сообщение
CPU rendering, никаких дополнительных либ, всё ручками сделал, вплоть до алгоритма рисования и закрашивания треугольников
Стоит поискать ошибку в умножении и формировании матриц.
У меня для того чтобы ошибок не было код операций между матрицами и векторами машинно-генерированный
Цитата Сообщение от Pro100Tom Посмотреть сообщение
Если кто сможет помочь найти ошибку, буду очень признателен.
Скинь код построения матриц проекции и вида
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
19.09.2016, 20:38  [ТС] #8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Points Renderer::ConvertToNDC(Vertex(&vertices)[3])
{
    Points points;
    
    for (int i = 0; i < 3; i++)
    {
        Vertex vertex = vertices[i] / vertices[i].w;
 
        Point point;
 
        point.x = (int)(vertex.x * horizontalScale + halfWidth);
        point.y = (int)(-vertex.y * verticalScale + halfHeight);
 
        points.push_back(point);
    }
 
    return points;
}
 
void Renderer::Render()
{
    Matrix4x4 viewMatrix = currentCamera.GetViewMatrix();
    Matrix4x4 projectonMatrix = currentCamera.GetProjectionMatrix();
 
    for (unsigned int j = 0; j < models.size(); j++)
    {
        Vertices tempVertices = viewMatrix * models[j].GetTransformedVertices();
        Vertices finalVertices = projectonMatrix * tempVertices;
 
        for (unsigned int i = 0; i < models[j].vertexFaces.size(); i++)
        {
            Face face = models[j].vertexFaces[i];
            Vertex polygonVertices[] =
            {
                finalVertices[face.a - 1],
                finalVertices[face.b - 1],
                finalVertices[face.c - 1]
            };
 
            Points points = ConvertToNDC(polygonVertices);
            DrawTriangle(points[0], points[1], points[2]);
        }
    }
}

C++
1
2
3
4
Vertex operator / (const Vertex& vertex, const float scalar)
{
    return Vertex(vertex.x / scalar, vertex.y / scalar, vertex.z / scalar);
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
Matrix4x4 operator * (const Matrix4x4& firstMatrix, const Matrix4x4& secondMatrix)
{
    Matrix4x4 newMatrix = Matrix4x4();
 
    newMatrix.elements[0][0] = 
        firstMatrix.elements[0][0] * secondMatrix.elements[0][0] +
        firstMatrix.elements[0][1] * secondMatrix.elements[1][0] +
        firstMatrix.elements[0][2] * secondMatrix.elements[2][0] +
        firstMatrix.elements[0][3] * secondMatrix.elements[3][0];
 
    newMatrix.elements[0][1] =
        firstMatrix.elements[0][0] * secondMatrix.elements[0][1] +
        firstMatrix.elements[0][1] * secondMatrix.elements[1][1] +
        firstMatrix.elements[0][2] * secondMatrix.elements[2][1] +
        firstMatrix.elements[0][3] * secondMatrix.elements[3][1];
 
    newMatrix.elements[0][2] =
        firstMatrix.elements[0][0] * secondMatrix.elements[0][2] +
        firstMatrix.elements[0][1] * secondMatrix.elements[1][2] +
        firstMatrix.elements[0][2] * secondMatrix.elements[2][2] +
        firstMatrix.elements[0][3] * secondMatrix.elements[3][2];
 
    newMatrix.elements[0][3] =
        firstMatrix.elements[0][0] * secondMatrix.elements[0][3] +
        firstMatrix.elements[0][1] * secondMatrix.elements[1][3] +
        firstMatrix.elements[0][2] * secondMatrix.elements[2][3] +
        firstMatrix.elements[0][3] * secondMatrix.elements[3][3];
 
 
 
 
    newMatrix.elements[1][0] =
        firstMatrix.elements[1][0] * secondMatrix.elements[0][0] +
        firstMatrix.elements[1][1] * secondMatrix.elements[1][0] +
        firstMatrix.elements[1][2] * secondMatrix.elements[2][0] +
        firstMatrix.elements[1][3] * secondMatrix.elements[3][0];
 
    newMatrix.elements[1][1] =
        firstMatrix.elements[1][0] * secondMatrix.elements[0][1] +
        firstMatrix.elements[1][1] * secondMatrix.elements[1][1] +
        firstMatrix.elements[1][2] * secondMatrix.elements[2][1] +
        firstMatrix.elements[1][3] * secondMatrix.elements[3][1];
 
    newMatrix.elements[1][2] =
        firstMatrix.elements[1][0] * secondMatrix.elements[0][2] +
        firstMatrix.elements[1][1] * secondMatrix.elements[1][2] +
        firstMatrix.elements[1][2] * secondMatrix.elements[2][2] +
        firstMatrix.elements[1][3] * secondMatrix.elements[3][2];
 
    newMatrix.elements[1][3] =
        firstMatrix.elements[1][0] * secondMatrix.elements[0][3] +
        firstMatrix.elements[1][1] * secondMatrix.elements[1][3] +
        firstMatrix.elements[1][2] * secondMatrix.elements[2][3] +
        firstMatrix.elements[1][3] * secondMatrix.elements[3][3];
 
 
 
 
 
 
 
 
    newMatrix.elements[2][0] =
        firstMatrix.elements[2][0] * secondMatrix.elements[0][0] +
        firstMatrix.elements[2][1] * secondMatrix.elements[1][0] +
        firstMatrix.elements[2][2] * secondMatrix.elements[2][0] +
        firstMatrix.elements[2][3] * secondMatrix.elements[3][0];
 
    newMatrix.elements[2][1] =
        firstMatrix.elements[2][0] * secondMatrix.elements[0][1] +
        firstMatrix.elements[2][1] * secondMatrix.elements[1][1] +
        firstMatrix.elements[2][2] * secondMatrix.elements[2][1] +
        firstMatrix.elements[2][3] * secondMatrix.elements[3][1];
 
    newMatrix.elements[2][2] =
        firstMatrix.elements[2][0] * secondMatrix.elements[0][2] +
        firstMatrix.elements[2][1] * secondMatrix.elements[1][2] +
        firstMatrix.elements[2][2] * secondMatrix.elements[2][2] +
        firstMatrix.elements[2][3] * secondMatrix.elements[3][2];
 
    newMatrix.elements[2][3] =
        firstMatrix.elements[2][0] * secondMatrix.elements[0][3] +
        firstMatrix.elements[2][1] * secondMatrix.elements[1][3] +
        firstMatrix.elements[2][2] * secondMatrix.elements[2][3] +
        firstMatrix.elements[2][3] * secondMatrix.elements[3][3];
 
 
 
 
 
 
    newMatrix.elements[3][0] =
        firstMatrix.elements[3][0] * secondMatrix.elements[0][0] +
        firstMatrix.elements[3][1] * secondMatrix.elements[1][0] +
        firstMatrix.elements[3][2] * secondMatrix.elements[2][0] +
        firstMatrix.elements[3][3] * secondMatrix.elements[3][0];
 
    newMatrix.elements[3][1] =
        firstMatrix.elements[3][0] * secondMatrix.elements[0][1] +
        firstMatrix.elements[3][1] * secondMatrix.elements[1][1] +
        firstMatrix.elements[3][2] * secondMatrix.elements[2][1] +
        firstMatrix.elements[3][3] * secondMatrix.elements[3][1];
 
    newMatrix.elements[3][2] =
        firstMatrix.elements[3][0] * secondMatrix.elements[0][2] +
        firstMatrix.elements[3][1] * secondMatrix.elements[1][2] +
        firstMatrix.elements[3][2] * secondMatrix.elements[2][2] +
        firstMatrix.elements[3][3] * secondMatrix.elements[3][2];
 
    newMatrix.elements[3][3] =
        firstMatrix.elements[3][0] * secondMatrix.elements[0][3] +
        firstMatrix.elements[3][1] * secondMatrix.elements[1][3] +
        firstMatrix.elements[3][2] * secondMatrix.elements[2][3] +
        firstMatrix.elements[3][3] * secondMatrix.elements[3][3];
 
 
    /*for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            newMatrix.elements[i][j] =
                firstMatrix.elements[i][0] * secondMatrix.elements[0][j] +
                firstMatrix.elements[i][1] * secondMatrix.elements[1][j] +
                firstMatrix.elements[i][2] * secondMatrix.elements[2][j] +
                firstMatrix.elements[i][3] * secondMatrix.elements[3][j];
        }
    }*/
 
    return newMatrix;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
Vertices operator * (const Matrix4x4& matrix, const Vertices vertices)
{
    std::vector<Vertex> newVertices;
 
    for (unsigned int i = 0; i < vertices.size(); i++)
    {
        Vertex vertex = matrix * vertices[i];
        newVertices.push_back(vertex);
    }
 
    return newVertices;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
bool BaseModel::BuildTransformationMatrix()
{
    bool changesWereMade = false;
 
    if (isTranslateRotateOutdated)
    {
        // Set translation values into translation matrix
        translationMatrix.elements[0][3] = location.x;
        translationMatrix.elements[1][3] = location.y;
        translationMatrix.elements[2][3] = location.z;
 
 
        // Prepare values and set them into rotation matrix
        float angleDeg = rotationAngle.y * Math::pi / 180.0f;
        rotationMatrix.elements[0][0] = rotationMatrix.elements[2][2] = cos(angleDeg);
 
        float result = sin(angleDeg);
        rotationMatrix.elements[0][2] = result;
        rotationMatrix.elements[2][0] = -result;
 
 
        translationRotationMatrix = translationMatrix * rotationMatrix;
        isTranslateRotateOutdated = false;
 
        changesWereMade = true;
    }
 
    if (isScaleOutdated)
    {
        // Set scale values into scaling matrix
        scalingMatrix.elements[0][0] = scale.x;
        scalingMatrix.elements[1][1] = scale.y;
        scalingMatrix.elements[2][2] = scale.z;
 
        transformationMatrix = translationRotationMatrix * scalingMatrix;
        isScaleOutdated = false;
 
        changesWereMade = true;
    }
 
    return changesWereMade;
}
C++
1
2
3
4
5
6
7
8
9
10
11
Camera::Camera()
{
    Math::Identity(viewMatrix);
    Math::Identity(projectionMatrix);
    projectionMatrix.elements[2][3] = -1.0f;
    projectionMatrix.elements[3][3] = 0.0f;
 
    SetNearFar(-1.0f, 1.0f);
    SetFov(10.0f);
    SetEye(Vertex(0.0f, 0.0f, 15.0f));
}

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void Camera::BuildProjectionMatrix()
{
    if (isProjectionOutdated)
    {
        float scale = 1 / (tanf(fov / 2 * Math::pi / 180.0f));
        projectionMatrix.elements[0][0] = projectionMatrix.elements[1][1] = scale;
 
        float difference = farPlane - nearPlane;
        projectionMatrix.elements[2][2] = -(farPlane / difference);
        projectionMatrix.elements[3][2] = -(farPlane * nearPlane / difference);
        isProjectionOutdated = false;
    }
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
float Math::CalculateDeterminant(const Matrix3x3& matrix)
{
    return matrix.elements[0][0] * (matrix.elements[1][1] * matrix.elements[2][2] - matrix.elements[1][2] * matrix.elements[2][1]) -
        matrix.elements[0][1] * (matrix.elements[1][0] * matrix.elements[2][2] - matrix.elements[1][2] * matrix.elements[2][0]) +
        matrix.elements[0][2] * (matrix.elements[1][0] * matrix.elements[2][1] - matrix.elements[1][1] * matrix.elements[2][0]);
}
 
 
float Math::CalculateDeterminant(const Matrix4x4& matrix)
{
    std::vector<int> horizontalIndexes = { 1, 2, 3 };
    float det = 0.0f;
 
    for (int j = 0; j < 4; j++)
    {
        if (matrix.elements[0][j] == 0) { continue; }
 
        std::vector<int> verticalIndexes = { 0, 1, 2, 3 };
        std::vector<int>::iterator vPosition = std::find(verticalIndexes.begin(), verticalIndexes.end(), j);
        verticalIndexes.erase(vPosition);
 
        Matrix3x3 tempMatrix;
        for (int k = 0; k < 3; k++)
        {
            for (int l = 0; l < 3; l++)
            {
                tempMatrix.elements[k][l] = matrix.elements[horizontalIndexes[k]][verticalIndexes[l]];
            }
        }
 
        int sign = j % 2 ? -1 : 1;
 
        det += matrix.elements[0][j] * CalculateDeterminant(tempMatrix) * sign;
    }
 
    return det;
}
 
 
void Math::TransposeMatrix(const Matrix4x4& inputMatrix, Matrix4x4& outputMatrix)
{
    Matrix4x4 tempMatrix;
 
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            //if (i == j) { continue; }
 
            tempMatrix.elements[i][j] = inputMatrix.elements[j][i];
        }
    }
 
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            //if (i == j) { continue; }
 
            outputMatrix.elements[i][j] = tempMatrix.elements[i][j];
        }
    }
}
 
 
void Math::CalculateCofactorMatrix(const Matrix4x4& inputMatrix, Matrix4x4& outputMatrix)
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            std::vector<int> horizontalIndexes = { 0, 1, 2, 3 };
            std::vector<int> verticalIndexes = { 0, 1, 2, 3 };
 
            std::vector<int>::iterator hPosition = std::find(horizontalIndexes.begin(), horizontalIndexes.end(), i);
            horizontalIndexes.erase(hPosition);
 
            std::vector<int>::iterator vPosition = std::find(verticalIndexes.begin(), verticalIndexes.end(), j);
            verticalIndexes.erase(vPosition);
 
            // Transpose matrix
            Matrix3x3 tempMatrix;
            for (int k = 0; k < 3; k++)
            {
                for (int l = 0; l < 3; l++)
                {
                    tempMatrix.elements[k][l] = inputMatrix.elements[horizontalIndexes[k]][verticalIndexes[l]];
                }
            }
 
            int sign = (i + j) % 2 ? -1 : 1;
 
            outputMatrix.elements[i][j] = CalculateDeterminant(tempMatrix) * sign;
        }
    }
}
 
 
void Math::DivideMatrixByScalar(const Matrix4x4& inputMatrix, Matrix4x4& outputMatrix, const float value)
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            outputMatrix.elements[i][j] = inputMatrix.elements[i][j] * value;
        }
    }
}
 
 
void Math::CalculateMatrixInverse(const Matrix4x4& inputMatrix, Matrix4x4& outputMatrix)
{
    // step 1: find the determinant
    float det = CalculateDeterminant(inputMatrix);
    Matrix4x4 tempMatrix;
 
    if (det == 0)
    {
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                tempMatrix.elements[i][j] = inputMatrix.elements[i][j];
            }
        }
 
        TransposeMatrix(tempMatrix, outputMatrix);
        return;
    }
 
    // step 2: calculate the matrix of cofactors
    CalculateCofactorMatrix(inputMatrix, tempMatrix);
 
    // step 3: transpose the matrix
    Matrix4x4 anotherTempMatrix;
    TransposeMatrix(tempMatrix, anotherTempMatrix);
 
    // step 4: divide matrix by determinant
    DivideMatrixByScalar(anotherTempMatrix, outputMatrix, 1 / det);
}
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
19.09.2016, 20:44  [ТС] #9
Тут скрин матриц (внизу).
Функция
C++
1
models[j].GetTransformedVertices()
возвращает уже трансформированные вертексы (потом изменю).
Проблема именно в цифре -8 (последняя матрица [2][2]). Из-за неё z и w компоненты "слетают" почему-то.
0
Миниатюры
Объединение view и projection матриц  
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
19.09.2016, 20:49  [ТС] #10
Тут скрин первого вертекса (два варианта), компонента z отличается из-за -15.0f, что во view матрице. А w кстати одна и та же. Мне казалось, что она тоже менялась.
0
Миниатюры
Объединение view и projection матриц  
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
19.09.2016, 22:07 #11
Такое впечатление что View транспанирована. Позиция обычно в нижней строке.

Добавлено через 26 минут
Кстати обычно подход к построению видовой матрицы абсолютно другой. Берут фрейм камеры, ось Z в качестве направления взгляда ось Y в качестве оси UP и строят LookAt матрицу. Т.е. фактически транспонируют подматрицу поворота (3x3) и вычисляют координаты ГСК в координатах фрейма, домножают на -1 и пишут в строку позиции.
Примерно вот так:
C++
1
2
3
4
5
6
7
8
9
10
        T3DUniformMatrix T3DUniformMatrix::GetViewMatrix(){
                T3DUniformMatrix R;
        R.AxeX.x = AxeX.x; R.AxeX.x = AxeY.x; R.AxeX.z = AxeZ.x; R.kx= 0;
        R.AxeY.x = AxeX.y; R.AxeY.y  = AxeY.y; R.AxeY.z = AxeZ.y; R.ky= 0;
        R.AxeZ.x = AxeX.z; R.AxeZ.z = AxeY.z; R.AxeZ.z = AxeZ.z; R.kz= 0;
    
            R.x = -(Eye*AxeX); R.y = -(Eye*Y);  R.z = -(Eye*Z); R.w = 1.0f;
        return R;
 
        }
Добавлено через 13 минут
Цитата Сообщение от Pro100Tom Посмотреть сообщение
что во view матрице
View матрица неправильно сформирована. эта -15 насколько понимаю должна быть в z. (т.е. в элементе [3][2]). Если конечно ползуешь Row Major матрицы. Если Column Major их надо перемножать в обратном порядке.
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
20.09.2016, 00:34  [ТС] #12
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Такое впечатление что View транспанирована
Тогда я запутался совсем. Почему? Вот тут описание translation матрицы. Изменения по оси x, y и z описаны справа. Значит и view матрица должна их справа описывать. Может у меня inverse не работает правильно, надо проверить. Буду гуглить еще раз view матрицу.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Если конечно ползуешь Row Major матрицы
Первый индекс это ряд, второй - колонка.
0
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
20.09.2016, 01:10  [ТС] #13
Вот проектик. Разбил на четыре части, потому что больше десяти мб не разрешает загружать форум.
0
Вложения
Тип файла: rar 3D_Renderer_2016_August_09.part01.rar (10.00 Мб, 1 просмотров)
Тип файла: rar 3D_Renderer_2016_August_09.part02.rar (10.00 Мб, 1 просмотров)
Тип файла: rar 3D_Renderer_2016_August_09.part03.rar (10.00 Мб, 1 просмотров)
Тип файла: rar 3D_Renderer_2016_August_09.part04.rar (6.88 Мб, 1 просмотров)
Pro100Tom
69 / 28 / 7
Регистрация: 29.10.2012
Сообщений: 331
20.09.2016, 01:15  [ТС] #14
Тут вот ещё в чём дело. Если я не перемножнаю на projection матрицу вообще, то всё работает. И если я изменяю z view матрицы, то объект либо "отдаляется" либо "приближается" в зависимости от значения. View матрица работает.
0
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
20.09.2016, 17:40 #15
Цитата Сообщение от Pro100Tom Посмотреть сообщение
Изменения по оси x, y и z описаны справа.
Это в Column-major матрице так. В Row Major оси записаны в строках в нижней оси позиция. в правом столбце проекция. В Column-Major в первых трех столбцах оси в последнем столбце позиция в нижней колонке проекция.
0
20.09.2016, 17:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.09.2016, 17:40
Привет! Вот еще темы с ответами:

Объединение нескольких матриц в одну - MathCAD
Здравствуйте. Имеется 4096 матриц порядка 8х8. Необходимо объединить их в одну квадратную матрицу так, чтобы в получилась матрица...

Объединение трёх матриц в цикле - Matlab
Имеется три матрицы x,y,z X = X11 X12 X13 X21 X22 X23 X31 X32 X33 Y= Y11 Y12 Y13 Y21 ...

Hibernate projection for nested entity - Java БД
Добрый день! Возникла такая проблемка. У меня есть две таблицы с кучей полей, связаны один-к-одному. Хочу я вытянуть только первую,...

В чем разница (View view) и (View v) - Программирование Android
Я только начинаю изучать программирование под андроид (до этого вобще программированием не занимался), по гуглу удалось найти только...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru