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

Как правильно считать касательные (tangents)?

Страницы: 1 2 3 Следующая »
#0
4:12, 31 июля 2019

Разбираюсь с normal mapping. Считаю tangents и bitangents в пиксельном шейдере:

float3x3 calcTBN(float3 p, float3 n, float2 uv) 
{
  float3 dpx = ddx(p);
  float3 dpy = ddy(p);
  float2 duvx = ddx(uv);
  float2 duvy = ddy(uv);

  float D = duvx.x * duvy.y - duvy.x * duvx.y;
  
  float3 tangent = (duvx.x * dpx - duvx.y * dpy) / D;
  tangent = tangent - n * dot(n, tangent);
  tangent = normalize(tangent);
  
  float3 bitangent = normalize(cross(tangent, n));

  return transpose(float3x3(tangent, bitangent, n));
}

Столкнулся с тем, что если UV развертка не непрерывная, то касательные "ломаются", соответственно ломаются и нормали. Как на мече на на картинке, который в развертке разрезан напополам:

tangents | Как правильно считать касательные (tangents)?

Наверняка это легко решается, но с ходу не нашел. Вроде все делают также, как и я.


#1
4:34, 31 июля 2019

polvorony
> то касательные "ломаются", соответственно ломаются и нормали. Как на мече на на
> картинке, который в развертке разрезан напополам:
С чего бы им там ломаться, если это разные треугольники?
На мече на картинке так и должно быть. У тебя острие меча идет слева направо, а часть где эфес справа налево. TBN базис должен быть разным.

#2
4:42, 31 июля 2019

MrShoor
> На мече на картинке так и должно быть.

Так на картинке выведены нормали. Получается, они переворачиваются посередине меча.

n = normalMap.Sample(textureSampler, input.uv).rgb;
n = n * 2.0 - 1.0;
n = normalize(mul(tbn, n));
return float4(n * 0.5 + 0.5, 1.0);
#3
(Правка: 5:14) 5:14, 31 июля 2019

polvorony
твой код пытается считать per-triangle TBN. то есть даже если ты его починишь, то TBN будет ломаться на каждой границе раздела треугольников. для корректного normal mapping'а любой редактор ожидает, что TBN базис между вершинами интерполируется. поэтому самый типичный способ решения — добавить tbn в формат вертекса и экспортировать его из редактора.

#4
5:26, 31 июля 2019

Suslik
Хм, я что-то думал, что если треугольники граничат в геометрии, то и касательные должны считаться нормально через ddx/ddy.

Попробую экспортировать касательные из редактора.

#5
6:24, 31 июля 2019

А вообще правильно вот так одну поверхность разбивать в развёртке на разные куски?

#6
7:11, 31 июля 2019

На картинке не нормали а нормал мап, посчитаный на основе тангентов посчитанных в приложении в котором запекался нормал мап.

Пытаться считать тангенты в пиксельном шейдере это дибилизм даже по меркам гд.

#7
7:21, 31 июля 2019

polvorony
мне кажется, каждый когда-то в жизни должен написать свой шейдер с попыткой автоматического расчёта TBN из производных. разумеется, чтобы понять, почему так никто не делает.

#8
(Правка: 8:13) 8:08, 31 июля 2019

Suslik
> то есть даже если ты его починишь, то TBN будет ломаться на каждой границе
> раздела треугольников.
Сорян, но это чушь. Ломаться будет только TB, но не N.

> для корректного normal mapping'а любой редактор ожидает, что TBN базис между
> вершинами интерполируется.
Там вон автор выше функцию привел. Она на вход принимает позицию, нормаль, и текстурные координаты. Все это интерполированное. На выходе TBN базис будет так же интерполироваться

>добавить tbn в формат вертекса и экспортировать его из редактора.
Если его экспортировать, то TB будет так же ломаться, как в случае с рассчетом из производных

> мне кажется, каждый когда-то в жизни должен написать свой шейдер с попыткой
> автоматического расчёта TBN из производных
Вот советую написать тебе такой шейдер. Чтобы заполнить этот пробел :)

polvorony
Мне лень вникать в правильность математики твоей TBN функции. Вот моя TBN из производных:

+ Показать

А вот её результат на том же арториасе, что у тебя:
artorias | Как правильно считать касательные (tangents)?
Как видишь нормаль на мече гладкая. Как и должно быть. А вот тангент и бинормаль ломается:
+ тангент
+ бинормаль

И это правильно, потому что UV ломается.
#9
(Правка: 8:21) 8:14, 31 июля 2019

MrShoor
> Сорян, но это чушь. Полная чушь. Ломаться будет только TB, но не N.
ты чего перевозбудился-то на ровном месте? я говорил про шейдер, который весь TBN базис считает из одних только производных UV. в нём весь базис будет скачком меняться на границе треугольников. если ты N будешь вместо этого из вертекса читать, то ясен пень, на него это никак не повлияет.

MrShoor
> Если его экспортировать, то TB будет так же ломаться, как в случае с рассчетом
> из производных
в графике под TBN часто понимают не формальный тензор производных UV по мировым координатам (который, кстати, формально должен меняться именно скачкообразно и интерполировать его вообще некорректно), а некоторый абстрактный базис, в котором запечён нормалмеп. да, на практике этот базис часто считается усреднением в вершинах производных UV от прилежащих треугольников, но иногда этот базис вообще может ничего общего с производными не иметь, он может быть, например, единичным, если нормалмеп запекается в мировых координатах. или художники сами могут его задать в майе или максе, например, произвольным образом. таким образом, самый надёжный способ — экспортировать TBN непосредственно из пакета, в котором запекался нормалмеп.

#10
(Правка: 8:26) 8:24, 31 июля 2019

polvorony
Фейсы на развёртке смотрят в разные стороны, а TBN-матрица считается на основе направлений текстуры и нормали.
Переверни на развёртке одну из половинок меча на 180 градусов, чтобы обе смотрели в одном направлении, и всё должно стать нормально.
И кинь результат = мне самому его интересно знать :)

#11
8:28, 31 июля 2019

Suslik
> ты чего перевозбудился-то на ровном месте?
Ну потому что ты заговнял способ рассчета TBN из производных. Но способ-то впринципе нормальный. Между "посчитать повершинно в загрузчике моделей" и "посчитать в пиксельном шейдере" разницы практически никакой. Получится +- похоже, но и то и то будет не 100% корректно.

> самый надёжный способ — экспортировать TBN непосредственно из пакета, в котором
> запекался нормалмеп.
Тут согласен. Это единственный надежный способ.

#12
8:28, 31 июля 2019

Suslik

Меня уже давно терзает один вопрос - где ты там в НЗ нашел клавиатуру с русской раскладкой?
Или пользуешь слепую печать?
#13
(Правка: 8:41) 8:31, 31 июля 2019
nes
> Меня уже давно терзает один вопрос - где ты там в НЗ нашел клавиатуру с русской раскладкой?
> Или пользуешь слепую печать?
я и забыл, что буковки-то, оказывается, иногда на кнопках нарисованы. интересно, зачем.
#14
8:41, 31 июля 2019

Новая Зиландия в Костромской области ? :)))

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