Всё бьюсь с mirror в tangent-space.
Перечитал уже многое, про швы, про разное.
Я понимаю такую вещь, из-за того, что uv у mirror части повёрнуто, в месте стыка получается вот такая картина
(красный - tangent, зелёный - normal, синий - binormal).
То есть расчёт получается верный, потому что красный tangent идёт в u в одном случае влево, в другом вправо.
А как оно должно быть? Понятно, что должна быть "одна" вершина с одним набором normal,tangent,binormal.
Или же надо каким-то образом в шейдер передать через .w координату tangent, что он для mirror. А binormal брать через cross, а не передавать в шейдер.
MrShoor, я надеюсь ты где-то здесь в районе ходишь
Поясни вот это ещё раз для тупых.
Единственно - для транглов у которых направление обхода по координатам в пространстве не совпадает с направлением обхода по текстурным координатам (это называется зеркальные фейсы) - надо выворачивать нормаль, чтобы матрица из правой превращалась в левую и наоборот.
Я через это могу найти какие фейсы mirror и вывернуть normal?
в очередной раз предлагаю юзать nvMeshmender и не е---ть мозги
в других случаях можно получить левый базис - частным кастрированным случаем он не счтиается
Проблему решил.
Использовал handness -1.f для зеркальных. И всё сработало.
я надеюсь ты где-то здесь в районе ходишь
Я не знаю, но вроде выглядит не как отзеркаленная грань.
Я через это могу найти какие фейсы mirror и вывернуть normal?
Зеркальная грань - это такая грань, когда у тебя вершины треугольника перечисляются по часовой, а в текстурных координатах против часовой. Чтобы определить такую грань - нужно перемножить тангент^нормаль получить вектор (предполагаемую нормаль в TBN), потом получить настоящую нормаль (не для TBN базиса) и сравнить, если между настоящей нормалью и нормалью в TBN угол больше 0.5*Pi - то это зеркальная грань.
Раз пошла такая пьянка, кто может посоветовать самый быстрый способ риалтайм расчета TBN для динамического меша вида "выдавленный плейн"? Что-то типа терраина, воды, флага.
-Alex- посмотрел еще раз на твой скриншот. У тебя там вершина попала видимо в разные группы сглаживания, и там у тебя 2 вершины. Я вижу 2 красных вектора (тангент?) и два синих (бинормаль?), и почему-то только 1 вектор нормали. Проблема у тебя в этом месте в том, что 2 вершины в одной точке, и разный TBN базис для них.
-Alex- посмотрел еще раз на твой скриншот. У тебя там вершина попала видимо в разные группы сглаживания, и там у тебя 2 вершины. Я вижу 2 красных вектора (тангент?) и два синих (бинормаль?), и почему-то только 1 вектор нормали. Проблема у тебя в этом месте в том, что 2 вершины в одной точке, и разный TBN базис для них.
Я уже разобрался.
На самом деле там алгоритм правильно делал, он бил в этом месте вершину на две. Почему? Потому что там шла граница по которой зеркалили и получалось, что он видел, что в одном месте тангент идёт вправо, а в другом влево, потому что зеркальные u координаты были.
И алгоритм правильно делает, что бьёт. Если бы он не бил точку, он бы подсчитал их, просуммировал и получил бы нулевые вектора.
//
И я просто добавил вычисление этого самого handness, по сути фактора зеркала, что зеркальные фейсы, пометка, её обычно предлагают передавать через .w координату у tangent.
И всё. В шейдере просто домножаем на неё (то есть на -1) в случае зеркальных фейсов, а бинормаль через cross. И получаем верный TBN.
И хотя он вычисляется так, как на рисунке, то есть вектора малость разбегаются, но после правильных вычислений в шейдере они встают на свои места.
Пока удалось добиться очень хорошей красоты без косяков.
//
В принципе подозреваю, что можно добиться и того, чтобы вычислять верные вектора сразу, заранее, облегчить шейдер.
В любом случае, с normal-spec-gloss путь более-менее пройден.
Теперь пойду в glow эффект.
Если бы он не бил точку, он бы подсчитал их, просуммировал и получил бы нулевые вектора.
В вершинном шейдере умножаем вектор света на TBN, а в фрагментный попадает информация о интерполированном векторе между тремя вершинами. И после нормализации все бы стало там на свои места.
её обычно предлагают передавать через .w координату у tangent.
Ну да, можно и так.
а бинормаль через cross
В случае передачи зеркала в .w лучше в шейдер отправлять тангент и бинормаль, а нормаль вычислять как cross(tangent.xyz, binormal.xyz) * tangent.w. Если у тебя не так, и вычисляется бинормаль - то возьми свою же модельку, разверни текстуру на 90 градусов, и соответственно разверни текстурные координаты, а потом посмотри на шов.
В случае передачи зеркала в .w лучше в шейдер отправлять тангент и бинормаль, а нормаль вычислять как cross(tangent.xyz, binormal.xyz) * tangent.w. Если у тебя не так, и вычисляется бинормаль - то возьми свою же модельку, разверни текстуру на 90 градусов, и соответственно разверни текстурные координаты, а потом посмотри на шов.
Понял. Спасибо.
MrShoor
Проверил про нормали.
Нормаль как кросс то, что ты писал.
То есть получается
normal = cross(tangent.xyz, binormal.xyz) * tangent.w
tangent возьмём как брали, но у него будет при зеркале -1.
binormal - берём из обычных вычислений.
Если я так делаю, у меня как раз шов возвращается как был.
Я хочу добиться, что всё заранее вычислить и cross в шейдере не делать уже. Чтобы заранее рассчитать и передавать уже готовые.
Тема в архиве.