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

Кто силен в математике - помогите с матрицами!

Страницы: 1 2 38 9 Следующая »
#0
(Правка: 2:13) 2:05, 28 фев. 2019

Я тут уже писал, что делаю зеркало рендером в текстуру. И вроде сделал, все работало. Пока зеркало висело на стене.
Поскольку по комнате в шлеме VR особо не походишь, то позиция камеры была почти стационарной. Но пару дней назад я попробовал сделать зеркальную поверхность стола и понял, что я крупно облажался.
Отражение не совпадает с предметами и крутится при перемещении камеры. Явно я пролетел с проекционной матрицей и возможно не только с ней.
Алгоритм я использовал простейший - перемещаю камеру в точку за зеркалом, сообразно углу отражения, и рендерю в текстуру.
Вот как это выглядит:

  XMVECTOR Up = XMVectorSet(0, 1, 0, 0);
 
  XMVECTOR Len = XMVector3Length(Mirror_Pos - Eye_Pos);
  XMVECTOR NewPos = Mirror_Pos - XMVector3Reflect(XMVector3Normalize(Mirror_Pos - Eye_Pos), Norm)*Len;

  XMMATRIX MirrorViewMatrix = XMMatrixLookAtRH(NewPos, Mirror_Pos, Up);

  XMMATRIX Persp = XMMatrixPerspectiveFovRH(FOV, mirrorSize.x/mirrorSize.z, 0.05, 1000.f);

  XMMATRIX Final_Proj = XMMatrixMultiply(MirrorViewMatrix, Persp);
Далее Final_Proj идет в шейдер и собственно все. Но как оказалось не все...

Есть тут знатоки математики, кто имел дело и разбирается в этом предмете? Я долго копал интернет но там на удивление мало про плоские зеркала. Есть только несколько примеров многолетней давности, но все они на стенсилах что мне не подходит. Сам я в матрицах явно не силен и просто не понимаю как это можно исправить.

Вот что бы понятно было:

mirror_bug | Кто силен в математике - помогите с матрицами!

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


#1
(Правка: 2:16) 2:12, 28 фев. 2019

san
> XMVECTOR Up = XMVectorSet(0, 1, 0, 0);
Я так подозреваю что проблема вот в этом векторе. Возможно есть еще проблемы, но перво наперво это следует из вращения, вектор верха должен показывать верх у зеркала, а не верх мира и прочая математика выглядит сомнительно.
Вообще камеру отражения проще ставить в положение объекта на чью поверхность строиться отражение, так проще, у него уже есть нужная тебе матрица.

#2
(Правка: 2:24) 2:15, 28 фев. 2019

foxes
> Я так подозреваю что проблема вот в этом векторе. Возможно есть еще проблемы, но перво наперво это следует из вращения, вектор верха должен показывать верх у зеркала, а не верх мира.
Так зеркало же лежит на столе, т.е они совпадают.

> Вообще камеру отражения проще ставить в положение объекта на чью поверхность строиться отражение, так проще, у него уже есть нужная тебе матрица.
Не понял. Камеру надо ставить ЗА обьектом. Какую матрицу у зеркала ты предлагаешь использовать, позиционную? Она то тут причем? Матрица есть у камеры, хотя непонятно что это мне дает. От вращения головы отражение не зависит.

#3
(Правка: 2:28) 2:18, 28 фев. 2019

san
> Так зеркало же лежит на столе, т.е они совпадают.
Кто они? Когда зеркало лежит у него вверх - это лево, право, вперед, назад, но только не верх в мировых координатах.

#4
2:28, 28 фев. 2019

foxes
> Кто они? Когда зеркало лежит у него вверх - это лево, право, вперед, назад, но только не верх в мировых координатах.
Вектор нормали зеркала направлен вверх. В данном случае вектор UP просто показывает где верх для XMMatrixLookAt. Это не имеет отношения к предметам. Если зеркало лежит на полу, ты можешь его крутить как угодно - изображение не изменится. Вот картинка на зеркале в привязке к его углам будет вращаться. Но это проекционная матрица а не видовая, насколько я понимаю.

#5
2:35, 28 фев. 2019

san
> Но это проекционная матрица а не видовая, насколько я понимаю.
Проэкционная только задает габариты.

#6
(Правка: 2:49) 2:39, 28 фев. 2019

san
> Алгоритм я использовал простейший - перемещаю камеру в точку за зеркалом,
> сообразно углу отражения, и рендерю в текстуру
неправильно. надо отражать матрицу трансформации камеры относительно плоскости зеркала.

вот какая-то левая иллюстрация
Изображение

это можно, например, сделать так:

virtualCameraTransformMatrix = inverse(mirrorMatrix) * DiagMatrix(-1, 1, 1) * mirrorMatrix;
virtualCameraViewProjectionMatrix = cameraProjectionMatrix * virtualCameraTransformMatrix * cameraViewMatrix;

здесь правая матрица в произведении переводит точку в систему координат, связанную с плоскостью зеркала (ось x — перпендикулярна поверхности в этой системе), DiagMatrix(-1, 1, 1) отражает относительно плоскости зеркала, inverse(mirrorMatrix) возвращает точку обратно в мировые координаты.

никакой содомии с XMMatrixPerspectiveFovRH, upVector и прочей лабудой вообще быть не должно, потому что матрица для зеркала строится преобразованием матрицы камеры.

#7
(Правка: 2:51) 2:44, 28 фев. 2019

Suslik
"Ты не умничай, ты пальцем покажи!".
Я привел код, что там надо исправить или добавить? Матрица камеры (позиция, кватернион) у меня есть.

#8
(Правка: 3:14) 2:54, 28 фев. 2019

san
> XMVECTOR NewPos = Mirror_Pos - XMVector3Reflect(XMVector3Normalize(Mirror_Pos - Eye_Pos), Norm)*Len;
вот эту часть можно проще считать

XMVECTOR NewPos = Mirror_Pos - XMVector3Reflect(Mirror_Pos - Eye_Pos, Norm);
Вектор UP нужно также взять как отраженный вектор от текущей матрицы камеры. Если у тебя ось Y это вверх, значит:
XMMATRIX Camera ...
XMVECTOR Up = XMVector3Reflect(Camera.r[1], Norm);
#9
2:55, 28 фев. 2019

Suslik
> mirrorMatrix
А что такое mirrorMatrix в данном контексте?

#10
(Правка: 3:10) 3:00, 28 фев. 2019

san
> А что такое mirrorMatrix в данном контексте?
Само зеркало, объект на котором текстура отражается. Тут даже можно без текстуры обойтись и глубину не чистить, если стенсилом поверхность зеркала маскировать.

#11
3:09, 28 фев. 2019

foxes
> вот эту часть можно проще считать
Согласен. Так короче.
> Проэкционная только задает габариты.
Вот с этим не согласен. Далеко не только габариты.

Сейчас попробую то, что Suslik предложил. Интересно...

#12
(Правка: 3:12) 3:10, 28 фев. 2019

san
> Сейчас попробую то, что Suslik предложил. Интересно...
Там все тоже самое только исключительно на видовых матрицах.

#13
3:30, 28 фев. 2019

san
Самый простой вариант для тебя я думаю будет:
1. Построить 3 точки. Eye, At, Up (причем Up это не вектор, а именно точка, которую можно получить через Eye + VectorUp)
2. Отразить эти 3 точки относительно поверхности зеркала
3. Построить по ним View матрицу

#14
(Правка: 3:47) 3:39, 28 фев. 2019

Suslik
Э... А как мне задать mirrorMatrix? Ну позицию я знаю, т.е. для начала:
XMMATRIX mirrorMatrix = XMMatrixTranslation(mirrorPos.x, mirrorPos.y, mirrorPos.z);
Если бы это был меш, то я бы дальше умножил на кватернион и все. Но меня интересует только одна грань, для которой есть нормаль. А как эту нормаль в матрицу засунуть?
Пока я вот что родил:

  XMMATRIX DiagMatrix = XMMatrixTranslation(-1, 1, 1);
  XMMATRIX mirrorMatrix = XMMatrixTranslation(mirrorPos.x, mirrorPos.y, mirrorPos.z);  // тут надо как-то поворот вставить
 
  XMMATRIX virtualCameraTransformMatrix = XMMatrixInverse(nullptr, mirrorMatrix) * DiagMatrix * mirrorMatrix;
  XMMATRIX virtualCameraViewProjectionMatrix = (cameraProjectionMatrix) * virtualCameraTransformMatrix * (cameraViewMatrix);

MrShoor
> 1. Построить 3 точки. Eye, At, Up (причем Up это не вектор, а именно точка,
> которую можно получить через Eye + VectorUp)
> 2. Отразить эти 3 точки относительно поверхности зеркала
> 3. Построить по ним View матрицу

А подробнее можно? Желательно с кодом, это же всего несколько строк. А то "Отразить эти точки" и "Построить по ним матрицу" это слишком абстрактно.

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