Как расчитать правильный Tangent Space? (комментарии)
Это сообщение сгенерировано автоматически.
Было бы круто если бы вместо ^ & стояли сишные функции ))))
Идеально для копипаста
Для ландшафта регулярного такое счиать каждый кадр жесть
> tangent *= tmp;
> D3DXVec3Normalize (&tangent, &tangent);
а зачем тогда вообще умножать на tmp???
Кстати да - интересный вопрос. Зачем умножать на число, если потом все-равно приводить к единичной длинне. Разве что изменить знак вектора этим числом
Sergio
> азве что изменить знак вектора этим числом
о точно! наверно ради этого. тогда не понятно, зачем перед этим с ним проводить сложную манипуляцию вроде tmp = 1/tmp....
а вообще в оригинальном алгоритме (тут на форме возникал он) нормализуется только в заключительном цикле....
Что-то не могу сообразить, функция "void CalcTangentBasis" во втором варианте аналогична написанной ниже?
void CalcTriangleBasis(const Vector3& E, const Vector3& F, const Vector3& G, float sE, float tE, float sF, float tF, float sG, float tG, Vector3& tangentX, Vector3& tangentY ) { Vector3 P = F - E; Vector3 Q = G - E; float s1 = sF - sE; float t1 = tF - tE; float s2 = sG - sE; float t2 = tG - tE; float pqMatrix[2][3]; pqMatrix[0][0] = P[0]; pqMatrix[0][1] = P[1]; pqMatrix[0][2] = P[2]; pqMatrix[1][0] = Q[0]; pqMatrix[1][1] = Q[1]; pqMatrix[1][2] = Q[2]; float temp = 1.0f / ( s1 * t2 - s2 * t1); float stMatrix[2][2]; stMatrix[0][0] = t2 * temp; stMatrix[0][1] = -t1 * temp; stMatrix[1][0] = -s2 * temp; stMatrix[1][1] = s1 * temp; float tbMatrix[2][3]; // stMatrix * pqMatrix tbMatrix[0][0] = stMatrix[0][0] * pqMatrix[0][0] + stMatrix[0][1] * pqMatrix[1][0]; tbMatrix[0][1] = stMatrix[0][0] * pqMatrix[0][1] + stMatrix[0][1] * pqMatrix[1][1]; tbMatrix[0][2] = stMatrix[0][0] * pqMatrix[0][2] + stMatrix[0][1] * pqMatrix[1][2]; tbMatrix[1][0] = stMatrix[1][0] * pqMatrix[0][0] + stMatrix[1][1] * pqMatrix[1][0]; tbMatrix[1][1] = stMatrix[1][0] * pqMatrix[0][1] + stMatrix[1][1] * pqMatrix[1][1]; tbMatrix[1][2] = stMatrix[1][0] * pqMatrix[0][2] + stMatrix[1][1] * pqMatrix[1][2]; tangentX.Set( tbMatrix[0][0], tbMatrix[0][1], tbMatrix[0][2] ); tangentY.Set( tbMatrix[1][0], tbMatrix[1][1], tbMatrix[1][2] ); tangentX.Normalize( ); tangentY.Normalize( ); }
GogenZzo
Знакомая функция - я о ней писал еще в 2007 году :)
0r@ngE
Да, это твоя функция ))) Вот интересно стало, какой метод быстрее, твой или описанный здесь.
GogenZzo
> Вот интересно стало, какой метод быстрее
На скорость этот метод точно не претендует, он ориентирован скорее на качество.
Качество еще зависит от того каким методом считается normalmap. Желательно чтобы считались одним методом.
0r@ngE
А хотя зачем мне скорость, если можно все заранее просчитать и в файл с моделью поместить
"Правильный тангент" штука рястяжимо-недостижимая.
То что тут приведено похоже на алгоритм для "сырого" tangent space который "правильный" для каждого отдельного треугольника.
У меня после него еще 5 страниц кода анализируют как смержить соседние вертексы чтобы tangent space был максимально монотонным по всей модели (без скручиваний), и при этом все швы идеально стыковались без видимых артефактов, независимо от того где и как порезано UV.
И еще есть нюансы о которых я знаю, но решать слишком сложно.
Например есть целая модель, порезаная на 2 части. Причем она должна складываться в целую, и по линии разреза - гладкая поверхность, т.е. тангент должен совпадать. Как это обеспечить? Проблема выходит за пределы обработки одной модели.
Кстати уточню: скручиванием я назвал такой тангент спейс, при котором интерполированый тангент вырождается (длина векторов=0).
Проще всего получить если взять модель с зеркальной симметрией UV и все тангенты в вертексах тупо усреднить. В результате вдоль линии симметрии все треугольники будут перекрученые.
shekh
> него еще 5 страниц кода анализируют как смержить соседние вертексы
так может поделиться с общественностью этим?
Немного пооффтоплю. Где то тут на форуме проскакивал ссылка на метод normal mapping'а без применения тангента, бинормали и текстуры с нормалями. Не могу сейчас найти.
Тема в архиве.