Разбирался с NormalMapping, вроде всё корректно, но возникла такая ситуация:
На шар требуется наложить бамп, я вычисляю тангент-ось вне шейдера, для каждого полигона и затем передаю в шейдер. Так как нормали у полигонов сферы разведены, то и тангент и бинормаль нужны "скользящие", тоесть высчитаны относительно нормали в каждой точке.
Я поступаю так:
Так как и "скользящий" или общий для всего полигона тангент умноженный(векторно) на нормаль в каждой точке даст в любом случае "скользящую" бинормаль(даже если он идёт не по касательной), а последующее умножение высчитанной корректной бинормали на нормаль даст корректный тангент, касательный в нужной точке, я вычисляю это всё в пиксельном шейдере для каждой точки, получаю вот так:
Но в пиксельном шейдере расчитывать расточительно, потому я пытаюсь вынести расчёт в вершинный шейдер, тем более в расчётах задействована только нормаль. Выношу, но начинаются странные артефакты, на некоторых полигонах изображение выглядит так, как будто бы текстура нормалей перевёрнута(бамп не в ту сторону)
В чём может быть проблема?
шейдеры первый вариант (с расчётами в пиксельном)
шейдеры второй вариант (с вынесеными расчётами в вершинный)
UVW
Не вижу нормализаций векторов в pixel shader.
PS: Вычислять тангент и бинормаль - неблагодарное дело, т.к. 100% корректный расчет TBN реально не используется - каждый считает по-своему. Так что на моделях по-сложнее рискуешь ловить артефакты.
Нормализация векторов есть(кроме нормали из нормалмапа, да ито конечный результат нормализуется после расчёта). Вобщим заметил я что и первый результат некорректен и затенение неправильно работает при поворотах модели, может кто-нибудь показать правильный способ нормалмаппинга? запарился уже с ним, уже полнедели разобраться не могу
UVW
Не вижу нормализации бинормали и тангента перед использованием
вот же
Binormal = normalize(cross(Tangent, vec3(gl_Normal)));
SmoothTangent = normalize(cross(vec3(gl_Normal), Binormal));
Ааа, врубился, промежуточные значения передаваемые в пиксельный шейдер не будут единичной длины, поправлю, но мне кажется дело не в этом, на интенсивность света может и повлияет, но не направление затенения
Вобщем подозрения у меня, что я сдёрнул не верную формулу расчёта tangent..
Мне одному не понятно, почему тангент униформом задается?
UVW
выведи в цвет по очереди компоненты tbn и посмотри что на стыке.
DeadMeat
> Мне одному не понятно, почему тангент униформом задается?
Хм...
Мне одному не понятно, почему тангент униформом задается?
Потому что он вычисляется в проге и передаётся в шейдер, после чего вычисляется бинормаль, а затем снова перемножением векторов вычисляется "сглаженный" тангент для конкретной точки и конкретной нормали(а не для общей нормали треугольника). Расчитывается вроде правильно.
Vector3f Tan = ((t3.y-t1.y)*(p2-p1)-(t2.y-t1.y)*(p3-p1))/((t2.x-t1.x)*(t3.y-t1.y)-(t3.x-t1.x)*(t2.y-t1.y));
t - текстурные коорды, p - вершины.
Вывел линии после каждого полигона, линия вроде идёт нормально по отношению к горизонтальному направлению текстуры
UVW
> Потому что он вычисляется в проге и передаётся в шейдер
В одной переменной, сразу все тангенты для всех вершин.
Пиши технологию, руби бабло!
UVW
Ха! Ты еще текстурные координаты передавай одним юниформом!
Я ещё даже не разобрался как это всё правильнее сделать, и вообще в каком пространстве лучше всё считать, потому и спрашивал пример, хотя бы словесный порядок действий, чтобы я по нему наконец смог что то корректное увидеть на экране. Если я эту штуку не осилю, дальше вообще не стоит браться, а вся более менее подходящая инфа на англицком(
UVW
Тангент - вектор, в направлении которого увеличивается Х-координата текстуры
Бинормаль - то же, но для У
Тангент - вектор, в направлении которого увеличивается Х-координата текстуры
Бинормаль - то же, но для У
Не, ну это то ясно-понятно, меня другое немного интересует.. У меня расчёты все идут в мировой системе координат, тоесть я вот такой белибердой
vec3 BumpNormal = SmoothTangent * TexNormal.x + Normal * TexNormal.z + Binormal * TexNormal.y;
перевожу текстурную нормаль в мировую систему(как бы проецируя её составляющие на оси этой системы, а затем сложив их получаю результат), но правильно ли это? Вообще есть какой то стандарт? типа "надо делать вот так и это правильно, а остальное от лукавого". Просто куча всяких примеров совершенно с разным подходом, и ни один у меня не заработал, а этот я до ума не могу довести.
Вобщем конкретно интересуют 2 вопроса
1) Как вычислить тангент в мировой системе по трём вершинам и их текстурным координатам?(то есть вектор направленный в ту же сторону, куда увеличивается горизонтальная координата текстуры на полигоне). Бинормаль можно и как cross вычислить, не думаю что на моделях будет так скошена текстура, что и бинормаль придётся считать точно..
2) как перевести вектор из системы модели в мировую систему, с учётом всех поворотов? На какую матрицу множить и где её можно выудить?
Кажись тангент у меня не правильно считается.. если начинать вертеть(на этапе моделирования а не в проге) модель, то сразу косяки появляются..
Задавал даже изначально неправильную тангент-ось(просто от одной вершины к другой без учёта текстуры), результат похожий на тот, что при повороте
Без поворотов вроде норм
Только модель повернуть сразу вот такое
фиг знает как правильно считать для отдельного треугольника по трём вершинам
evirus
> UVW
> выведи в цвет по очереди компоненты tbn и посмотри что на стыке.
Вывел, косяк в тангенте и бинормали, чтд. Требуется формула правильная..
PS: формула верная, нашёл на форуме другую, результат тот же.. не пойму
А если в пиксельный всё занести обратно, то пропадает проблема, но тормоза..
Тема в архиве.