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

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

Страницы: 1 2 3 49 Следующая »
#15
3:47, 28 фев. 2019

san
> Э... А как мне задать mirrorMatrix?
translation компонента этой матрицы — любая точка на поверхности зеркала. базисные векторы — нормаль, тангент и бинормаль к поверхности зеркала.


#16
(Правка: 4:09) 3:57, 28 фев. 2019

foxes
> Вектор UP нужно также взять как отраженный вектор от текущей матрицы камеры.
Так, это не работает. Стало даже хуже, теперь картинка зависит от наклона головы.  Кроме того, все стало отражаться наоборот (т.е. не зеркально как надо). Но даже без этого видно, что это не то.

#17
4:05, 28 фев. 2019

Suslik
> translation компонента этой матрицы — любая точка на поверхности зеркала.
> базисные векторы — нормаль, тангент и бинормаль к поверхности зеркала.
Трансляцию я уже сделал - вон выше на предыдущей странице:
XMMATRIX mirrorMatrix = XMMatrixTranslation(mirrorPos.x, mirrorPos.y, mirrorPos.z);

Что мне с вращением-то делать? Нормаль у меня есть.  Тангент и бинормаль могу вычислить если надо.
Ты не мог бы показать как создать эту матрицу в микрософтовской нотации, через XMMATRIX?

#18
4:31, 28 фев. 2019

san
> А подробнее можно?
1. Построить 3 точки можно просто прибавив к ним вектора:
vec3 at_pt = Eye_Pos + View_Dir;
vec3 up_pt = Eye_Pos + Up;
ну и третья точка - это собственно Eye_Pos

2.
Есть плоскость зеркала (из предыдущей твоей темы ты знаешь как найти эту плоскость): vec4 plane
нормализуешь её по xyz:
plane /= length(plane.xyz);

Далее тебе надо отразить точки:
берешь точку pt, и находишь расстояние до плоскости:
float d = dot(plane.xyz, pt) + plane.w;
и строишь отраженную точку:
vec3 pt_ref -= palne.xyz * d * 2;

3. Полученные отраженные точки подставляешь в XMMatrixLookAtRH и получаешь "отраженную" матрицу вида.

#19
(Правка: 5:10) 4:50, 28 фев. 2019

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

Вот тут я нашел упоминание об этой проблеме: http://steps3d.narod.ru/tutorials/render-reflection-tutorial.html

Там сказано: "Однако получившаяся таким образом текстура не может быть наложена на отражающую грань обычным образом, поскольку она уже содержит изображение сцены с учетом перспективного преобразования.  Поэтому если ее просто наложить на грань, то получится, что к отражению перспективное преобразование будет примененным дважды, что даст некорректное отражение. Для того, чтобы избежать вторичного применения перспективного преобразования обычно применяется специальный способ вычисления текстурных координат."

Это весьма похоже на то, что у меня получается. К сожалению дальше в статье идет довольно невнятный текст:

"Подобное проектирование текстуры как бы инвертирует перспективное преобразование и в результате своего применения дает полностью корректное изображение отраженной  сцены. Для задания такого способа вычисления текстурных координат проще всего смоделировать проектирование, при помощи которого строилось отражение. Возьмем в качестве текстурных координат исходные трехмерные координаты вершин (используя для задания текстурных координат функцию glTexCoord3f), а в качестве матрицы преобразования текстурных координат используем произведение модельной и проектирующей матриц, использованных при построении отражения."

Извлечь отсюда полезную информацию я не сумел, но по смыслу это напоминает то, что предлагает Suslik. Осталось понять как это сделать.

#20
5:10, 28 фев. 2019

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

#21
(Правка: 5:13) 5:12, 28 фев. 2019

san
MrShoor
Нет у меня стенсил буфера, я же это сразу сказал. Мне нужно рендерить в текстуру, которая лежит на поверхности зеркала. Отсюда и проблема.

#22
5:55, 28 фев. 2019

san
> Мне нужно рендерить в текстуру, которая лежит на поверхности зеркала.
Не нужно тебе этого. Ты таким образом сам создаешь себе проблемы, которые потом будешь еще долго решать. Даже если сейчас ты сделаешь нормальную камеру для такой текстуры, то твоей следующей проблемой будет: "а надо менять разрешение текстуры динамически, потому что когда я стою далеко, то текстуру алиазит дико (ведь она без мип уровней), а когда подхожу близко - то вижу пиксели". Потом будет проблема - когда я смотрю под углами вблизи - я вижу пиксели, а в далеке алиазит.

Нафиг такое. Проще завести стенсил буфер и иметь идеальное зеркало с pixel perfect точностью.

#23
(Правка: 6:18) 6:16, 28 фев. 2019

MrShoor
> Не нужно тебе этого.
Давай я сам буду решать, что мне нужно, а что нет. Дизайн проекта таков, что необходимо использовать текстуру. Задача имеет решение, это понятно. Но моих знаний недостаточно. Интуитивно я вижу, что дело похоже в проекционной матрице, поскольку изображение сформированное на плоскости перпендикулярной лучу "камера-середина зеркала" должна проецироваться на поверхность лежащую к нему под углом, т.е картинка будет растянута. Плюс надо компенсировать двойные перспективные искажения. Я не знаю как это делается.

Пока что-то разумное предложил только Suslik. Но он к сожалению пока пропал и не довел дело до конца.
Вообще меня удивляет отсутствие материалов в инете по этой теме, вроде решение то должно быть достаточно простым. Чистая математика.

#24
6:46, 28 фев. 2019

san
> Дизайн проекта таков, что необходимо использовать текстуру.
Используй. Это screen space текстура. Если прям очень хочется без стенсила, то можно и без стенсила. Делаешь скринспейс текстуру, и в экранном пространстве её накладываешь на зеркало.

> Пока что-то разумное предложил только [b]Suslik[/b].
Суслик тебе так же предлагал в контексте скринспейс текстуры.

#25
6:55, 28 фев. 2019

MrShoor
> Делаешь скринспейс текстуру, и в экранном пространстве её накладываешь на зеркало.
Код слабо показать? Желательно на основе того, что в первом посте. Пока что совет "делаешь текстуру и накладывашь её на зеркало" мне мало что дает.  Я потому и тему открыл, что не знаю как это сделать.

#26
(Правка: 7:09) 7:07, 28 фев. 2019

san
стенсил используется просто в качестве оптимизации, то же самое можно делать и рендером в текстуру. идея в том, чтобы при рендеринге отражения получить не текстуру, которую потом натягивать на зеркало, используя не его UV(это сложно, зависит от его uv-развёртки и так никто не делает), а UV экранных координат твоей основной камеры. для этого зеркало рендерится в 2 прохода — первым проходом ты помечаешь на своём экране пикселы, которые занимает зеркало(которые ты потом заменишь на отражение), а вторым прохом ты рендеришь сцену с твоей матрицей проекции и матрицей камеры, код которой я привёл выше, но применяя его только к тем пикселам, которые ты пометил ранее.

классически операция рендеринга только в пикселы, которые занимает зеркало, делается через стенсил из соображений производительности, но если тебе очень хочется, можно просто рендерить в отдельную текстуру и потом discard'ить те пиксели, которые не помечены.

san
> Код слабо показать
код рендеринга плоских зеркал — это достаточно инвазивный код, который делается не в одну строку и его реализация (как, например, shadow mapping) существенно зависит от используемого графического фреймворка, так как включает несколько пассов.

#27
(Правка: 8:09) 7:36, 28 фев. 2019

Suslik
> для этого зеркало рендерится в 2 прохода
Блин... Ты уверен что нет прямого алгоритма? Задача то вроде несложная....

> существенно зависит от используемого графического фреймворка, так как включает несколько пассов.
Я вообще то работаю на DX12, но в данном случае речь вроде идет о чистой математике. Зачем там два прохода, я не пойму?

>делается через стенсил из соображений производительности,
Дело в том, что я не хочу менять рендер - он сделан для Окулуса и вставлять в основной цикл что-то специфическое, только для зеркал я бы не хотел. А так есть зеркало, нет его - цикл не меняется. Появилось зеркало, просто изменяется текстура одного обьекта. Основной рендер этого не замечает. Но он сам рендерит не на экран, а в окуловский буфер, и уже их внутренний процесс выводит изображение. Потому я и не хочу использовать стенсил - это придется делать лишний пасс для всего, добавлять текстуру размером в экран и постоянно копировать его в окуловский буфер. Короче геморрой и потеря производительности. Но родной окуловский десктоп (назовем его так, визуально это такая комната) имеет отличный полированный пол, стол и еще некоторые поверхности, значит задача решается.

#28
9:14, 28 фев. 2019

san
> Код слабо показать?
Код чего? Накладывания текстуры в экранном пространстве? Я думал это очевидно:

struct PS_Input {
  float4 Position: SV_Position;
};

struct PS_Output {
  float4 Color: SV_Target0;
};

Texture2D mirrored_screen;

PS_Output main(PS_Input In) {
  PS_Output Out;
  Out.Color = mirrored_screen.Load(int2(In.Position.xy));
  return Out;
}
#29
9:39, 28 фев. 2019

san
> Я вообще то работаю на DX12, но в данном случае речь вроде идет о чистой
> математике. Зачем там два прохода, я не пойму?
один проход рендерит сцену с позиции отражённой относительно зеркала камеры, второй — рендерит основную сцену вместе с отражением в зеркале. за один проход это отрендерить, ясное дело, нельзя, как нельзя за один проход отрендерить shadow map и lighting shader.

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