По поводу ортогонализации - это зачем? Ненадо там ничего ортоганизировать, испортишь только картинку. Все находится однозначно через математику которая описана здесь: http://www.gamedev.ru/code/forum/?id=121050#m6
Код я так понимаю там стандартного расчёта, просто через матрицу, а потом из неё уже забираются вектора. Аналогично можно сразу вектора собирать. Но этот алгоритм я уже изучил, там всё понятно более-менее.
Почему ортогонализация возникает - потому что в шейдере вектексом я же перевожу вектор направления света через dot(lightDir,tan), dot(lightDir,bitan), dot(lightDir,norm). По сути это равносильно произведению на матрицу, составленную из этих трёх векторов, но я так понял, что это работает только если все три вектора tan,bitan и norm взаимноперпендикулярны.
Про разворот нормали - спасибо. Уточню это. Я всё не мог понять, что в западных статьях они называют mirror-face, теперь буду знать.
А если при расчёте получается так, что тангент по результатам вычисления оказывается совпадающим по оси с нормалью. Что тогда делать? Ведь мы тангент и битангент рассчитываем без учёта нормали и так может статься, что направление одного или другого совпадёт с нормалью.
Нормаль мы трогать не можем, значит надо тогда тангент брать как cross нормали и битангента или, если битангент то аналогично с ним?
N = normalize(cross(tangentX, tangentY));
if (dot(cross(F, G), N)>0.0) { N = undo(N); };
Вот тут не очень понял.
Если это опора на вот этот код http://www.gamedev.ru/code/forum/?id=121050#m6
То получается F и G - это должны быть вектора-стороны треугольника.
То есть в том коде
Vector3 P = F - E;
Vector3 Q = G - E;
P и Q, потому что F,G - это координаты вершин треугольника.
И приведённый там код рассчитан на tangent-space для треугольника, подразумевая, что в каждой вершине его будет один tangent-space.
А что делать, если soft-грани, то есть нормаль берётся как сумма нормалей?
Всё, сам ответил себе. Надо рассчитать с инверсией для треугольника, а потом уже делать суммирования там где нужно.
MrShoor
> Шутка такая? Четырехугольник = два треугольника.
Я не хочу вычислять для четырёхугольника, я хочу вбить в код готовые циферки. Я уже написал, как у меня располагаются вершины прямоугольника несколько моих постов назад. Это вообще самый примитивный случай, и я на нём хочу сам понять, какими эти векторы должны быть и протестировать свой бампмэппинг. Вот перечислите мне 4 тройки чисел, пожалуйста. Вот когда всё заработает, тогда уже следующим этапом будет реализация расчёта касательного пространства автоматически. Тогда будет, на чём его тестировать. А то у меня не работает и не могу понять, то ли тангенты неправильные, то ли шейдер, то ли в шейдер что-то не так передаётся.
gammaker
Метод отличный, ты просто что-то сделал не так.
Кстати, если у тебя больше 4-х источников света в сцене - советую обратить внимание на deferred shading.
bazhenovc
> Метод отличный, ты просто что-то сделал не так.
Ну не знаю, скопировал код, запихнул туда те векторы, которые надо, а получил во-первых что-то не то, а во-вторых с тормозами. Я так и не понял, зачем для TBN нужен view vector?
gammaker
Как можно было неправильно скопировать код? о_О
А может кто сподвигнется библиотечку сделать? Опенсорсную на гитхабе или гугл-коде. А потом люди туда закомитят разные варианты и можно будет выбирать алгоритм....
bazhenovc
> Как можно было неправильно скопировать код?
А ты что, скопировал и всё получилось?
>Кстати, если у тебя больше 4-х источников света в сцене - советую обратить внимание на deferred shading.
Пока три источника. Про deferred shading знаю, но сам ни разу не реализовывал.
Пробовал три варианта:
1. Eric Lengyel
2. CryTek
3. Morten S. Mikkelsen
Остановился на последнем, т.к. с ним швы исчезли. Но надо подправить шейдеры слегка. Как бонус - он является дефолтным в xNormal, поэтому при запекании получается идентичный TBN.
FROL
а есть острая необходимость?
gammaker
> А ты что, скопировал и всё получилось?
Прикинь, с первого раза :) Может у тебя нормалмапа в другом формате?
bazhenovc
> Прикинь, с первого раза :) Может у тебя нормалмапа в другом формате?
Да у меня тогда вообще был не готов NormalMap. Я думал, что сейчас сопру шейдер, добавлю туда генерацию TBN и всё заработает. В итоге решил передавать тангенты, а бинормали делать cross'ом. Пока вроде нормальное работает. Их можно в один атрибут с нормалями уместить, если хранить по две компоненты, так что лучше передать 4 лишних байта (ushort'а ведь им выше крыши?), чем считать кучу всего лишнего во фрагментном шейдере. А так этот шейдер получился простой и понятный, я даже ещё параллакс прикрутил, а FPS вообще даже не уменьшился.
Я мог бы теперь снова попробовать тот метод и наверняка бы заработало, но меня теперь свой устраивает на все 100, поэтому не буду.
Normalmap'а оказалась и в правду не в том формате, в котором она обычно встречается. У меня поменяны y и z, из-за чего она светло-зелёная.
gammaker
Ну ок, пусть будет по твоему :)
-Alex-
что это работает только если все три вектора tan,bitan и norm взаимноперпендикулярны.
Нет, это работает в любом случае. Если будешь ортоганализировать TBN - то потеряешь непрерывность на границах треугольника, и получишь странные артефакты. Т.е. T и B вполне могут оказаться не взаимноперпендикулярными. Такое произойдет если текструа сжимается или разжимается если идти по граням от вершины.
А если при расчёте получается так, что тангент по результатам вычисления оказывается совпадающим по оси с нормалью.
Такое может получиться только в одном случае, если у тебя вектора текстурных координат параллельны для двух сторон треугольника, но тогда у тебя там будет не текстура - а растянутое хрен пойми что. Тогда после cross мы получим вектор нормали = 0, а при нормализации он улетит в INF.
Нормаль мы трогать не можем, значит надо тогда тангент брать как cross нормали и битангента или, если битангент то аналогично с ним?
Ну у нас ведь и нормали нет изначально. Можешь обрабатывать такие ситуации если хочешь. Если нормаль после сross (T, B) вышла с нулевой длинной, до задать её через cross(P, Q).
Вот тут не очень понял.
Если это опора на вот этот код http://www.gamedev.ru/code/forum/?id=121050#m6
То получается F и G - это должны быть вектора-стороны треугольника.
То есть в том коде
Vector3 P = F - E;
Vector3 Q = G - E;
Все правильно, сорри я ошибся. Конечно там должны быть P Q. Просто набирал код прям тут, и ессно не проверял (оригинал у меня на делфи просто, и у меня там промежуточные переменные называются по другому)
Нет, это работает в любом случае. Если будешь ортоганализировать TBN - то потеряешь непрерывность на границах треугольника, и получишь странные артефакты. Т.е. T и B вполне могут оказаться не взаимноперпендикулярными. Такое произойдет если текструа сжимается или разжимается если идти по граням от вершины.
Я сейчас остановился на варианте крайтековском. У них там идёт ортогонализация и смотрится лучше, чем без оной. Проверил.
Пока артефактом недоволен только одним
Это отзеркаленная грань. Низ самой плашки идёт hard.
Нормали
В Майе такой проблемы нет
Остальная часть хороша.
Вот с этим сейчас ищу, в чём проблема.
bazhenovc
Острой наверное, но наверное можно было бы попробовать сделать либу с более качественными алгоритмами о которых тут шла речь...
Тема в архиве.