154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
1 | |
Объединение view и projection матриц19.09.2016, 11:45. Показов 2147. Ответов 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
|
19.09.2016, 11:45 | |
Ответы с готовыми решениями:
28
Объединение View из разных баз Объединение матриц Объединение вложенных матриц Объединение матриц в MathCad |
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
19.09.2016, 18:23 [ТС] | 3 |
0
|
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
|
|
19.09.2016, 19:14 | 5 |
Если сами матрицы построены правильно и правильно работает перемножение то все там получается. Причем произведение всех трех сразу Model*View*Projection. Именно в таком порядке. При этом обычно еще хранят произведение View*Projection потому как оно меняется обычно раз в кадр а Model меняется на каждый объект, поэтому перемножают Model * ViewProjection для экономии матричных умножений при переходе от объекта к объекту.
Добавлено через 3 минуты Зачем ее инвертировать? Она при построении путем LookAt уже получается инвертированная.
2
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
19.09.2016, 19:18 [ТС] | 6 |
CPU rendering, никаких дополнительных либ, всё ручками сделал, вплоть до алгоритма рисования и закрашивания треугольников.
Добавлено через 1 минуту Спасибо! Буду искать ошибку. Как вернусь с работы, скину весь проект и ключевые функции. Если кто сможет помочь найти ошибку, буду очень признателен.
0
|
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
|
|
19.09.2016, 19:23 | 7 |
Стоит поискать ошибку в умножении и формировании матриц.
У меня для того чтобы ошибок не было код операций между матрицами и векторами машинно-генерированный Скинь код построения матриц проекции и вида
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|||||||||||||||||||||||||||||||||||||||||
19.09.2016, 20:38 [ТС] | 8 | ||||||||||||||||||||||||||||||||||||||||
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
||||||
19.09.2016, 20:44 [ТС] | 9 | |||||
Тут скрин матриц (внизу).
Функция
Проблема именно в цифре -8 (последняя матрица [2][2]). Из-за неё z и w компоненты "слетают" почему-то.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
19.09.2016, 20:49 [ТС] | 10 |
Тут скрин первого вертекса (два варианта), компонента z отличается из-за -15.0f, что во view матрице. А w кстати одна и та же. Мне казалось, что она тоже менялась.
0
|
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
|
||||||
19.09.2016, 22:07 | 11 | |||||
Такое впечатление что View транспанирована. Позиция обычно в нижней строке.
Добавлено через 26 минут Кстати обычно подход к построению видовой матрицы абсолютно другой. Берут фрейм камеры, ось Z в качестве направления взгляда ось Y в качестве оси UP и строят LookAt матрицу. Т.е. фактически транспонируют подматрицу поворота (3x3) и вычисляют координаты ГСК в координатах фрейма, домножают на -1 и пишут в строку позиции. Примерно вот так:
View матрица неправильно сформирована. эта -15 насколько понимаю должна быть в z. (т.е. в элементе [3][2]). Если конечно ползуешь Row Major матрицы. Если Column Major их надо перемножать в обратном порядке.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
20.09.2016, 00:34 [ТС] | 12 |
Тогда я запутался совсем. Почему? Вот тут описание translation матрицы. Изменения по оси x, y и z описаны справа. Значит и view матрица должна их справа описывать. Может у меня inverse не работает правильно, надо проверить. Буду гуглить еще раз view матрицу.
Первый индекс это ряд, второй - колонка.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
20.09.2016, 01:10 [ТС] | 13 |
Вот проектик. Разбил на четыре части, потому что больше десяти мб не разрешает загружать форум.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
20.09.2016, 01:15 [ТС] | 14 |
Тут вот ещё в чём дело. Если я не перемножнаю на projection матрицу вообще, то всё работает. И если я изменяю z view матрицы, то объект либо "отдаляется" либо "приближается" в зависимости от значения. View матрица работает.
0
|
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
|
|
20.09.2016, 17:40 | 15 |
Это в Column-major матрице так. В Row Major оси записаны в строках в нижней оси позиция. в правом столбце проекция. В Column-Major в первых трех столбцах оси в последнем столбце позиция в нижней колонке проекция.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
20.09.2016, 18:49 [ТС] | 16 |
У меня все матрицы значит в column major записаны.
scaling - не имеет значения, она симметрична. rotation cos() 0 sin() 0 0 0 0 0 -sin() 0 cos() 0 0 0 0 1 translation 1 0 0 Tx 0 1 0 Ty 0 1 0 Tz 0 0 0 1 view 1 0 0 0 0 1 0 0 0 0 1 -15 0 0 0 1 projection s 0 0 0 0 s 0 0 0 0 a -1 0 0 b 0 где s = 1 / tan(0.5 * fov * pi / 180) a = -f / (f - n) b = -f * n / (f - n) Добавлено через 46 минут Скажите, правильно ли я понимаию стадии pipeline'а? (пошагово для удобства) 1). TransformationMatrix - пропускаем оригинальные вертекса объекта, чтобы получить вертексы в World пространстве 2). ViewMatrix - пропускаем вертексы World пространства, чтобы получить вертексы в Camera пространстве 3). ProjectionMatrix - пропускаем вертексы Camera пространства через матрицу проекции, чтобы симулировать перспективу. Для этого надо каждую компоненту каждого вертекса разделить на компоненту w. После этого просто используем x и y, предварительно проверив находятся ли они в пределах окна. Ничего не пропустил?
0
|
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
|
|
20.09.2016, 20:12 | 17 |
Ну примерно так. А если подробнее:
1) сборка примитивов. Т.е. Определение по индексам какие номера вертексов потребуются. 2) Трансформация. Т.е. умножение координат вертекса на матрицу трансформации. (произведение Model*View*Projection) (т.е. фактически то что делает VertexShader) 3) Отсечение. т.е. обрезка отрезков/треугольников/удаление точек вышедших за пределы пирамиды/куба перспективы (как минимум желательно обрезать плоскостью near) 4) Перспетивное деление. 5) Окончательное отсечение (обрезка остальными плоскостями если в пункте 3 резали только плоскостью near) 6) Масштабирование в ScreenSpace 7) Растеризация. т.е. вычисление закрашенных примитивами точек с учетом Z координаты (z интерполируется вдоль примитива) и сортировка по глубине (т.е. z-буфер). Для прошедших z-тест фрагментов вычисление освещенности (т.е. то что делает PixelShader) Для отрисовки нурбсов и т.п. либо применяют более другие виды интерполяции нежели интерполяция плоскости треугольник при растеризации (в конвейерах профессиональных карт) либо добавляют еще одну стадию конвейера для разбиения патча на треугольники (в обычных домашних ускорителях то что делают Hull и Domain шейдеры) Стадия добавляется между 2 и 3. Отсечение кстати задачка со многими неизвестными. Потому как по Near очень стоит отсекать до перспективного деления (при перспективном делении все что имеет отрицательный Z будет перевернуто вверх ногами что путает все карты при отсечении отрезков/треугольников вертексы которых лежат по разные стороны плоскости z=0, а вертексы имеющие z=0 вообще вылетят с ексекпшином или получат неопределенное значение). А с другой стороны удобнее отсекать после перспективного деления так как в результате перспективного деления пирамида отсечения превращается в куб отсечения. Ну а вообще матрицы имеют свойство накапливать трансформацию. При этом в общем то не важно они Row Major или Column Major. Важен только порядок умножения. К примеру для RowMajor нужно умножать Model*View*Projection и вектор координат умножать на матрицу. А для column Major умножать Projection*View*Model и матрицу умножать на вектор вертекса. Добавлено через 10 минут projection в RowMajor. в Translation ошибка. Должно быть 1 0 0 Tx 0 1 0 Ty 0 0 1 Tz 0 0 0 1
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
20.09.2016, 21:42 [ТС] | 18 |
Спасибо, переведу сейчас. А по поводу translation - это опечатка.
Добавлено через 29 минут Транспонировал я матрицу проекции - ни фига. Не работает! Но вот, что забавно. И обычная и траспонированная матрица проекции визуализирует объект нормально. И fov работает как надо и eye (хоть он во view), единственное отличие, так это то, что в траспонированной матрице проекции объект перевёрнут. Добавлено через 33 минуты Нашёл!!! Надо projection * view вместо view * projection!!!
0
|
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
|
|
20.09.2016, 21:56 | 19 |
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
20.09.2016, 22:03 [ТС] | 20 |
0
|
20.09.2016, 22:03 | |
20.09.2016, 22:03 | |
Помогаю со студенческими работами здесь
20
Объединение матриц по условию Объединение трёх матриц в цикле Объединение нескольких матриц в одну Hibernate projection for nested entity Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |