Как добиться гладких касательных пространственных нормалей?
Я пытаюсь добавить функциональность рельефного отображения в свое приложение, но получаю очень граненые модели:
Причина, по которой это происходит, заключается в том, что я вычисляю тангенциальные, бинормальные и нормальные значения для каждого лица и полностью игнорирую нормали, полученные из файла модели.
В настоящее время в вычислениях используются два ребра пространственных векторов треугольника и текстуры для получения тангенса и бинормаля, которые затем используются для вычисления нормали по кросс-произведению. Все это выполняется на процессоре, как только модель загружается, а затем значения сохраняются как часть геометрии модели.
vector1 = vertex2.coords - vertex1.coords;
vector2 = vertex3.coords - vertex1.coords;
tuVector = vertex2.texcoords - vertex1.texcoords;
tvVector = vertex3.texcoords - vertex1.texcoords;
float den = 1.0f / (tuVector.x * tvVector.y - tuVector.y * tvVector.x);
tangent.x = (tvVector.y * vector1.x - tvVector.x * vector2.x) * den;
tangent.y = (tvVector.y * vector1.y - tvVector.x * vector2.y) * den;
tangent.z = (tvVector.y * vector1.z - tvVector.x * vector2.z) * den;
binormal.x = (tuVector.x * vector2.x - tuVector.y * vector1.x) * den;
binormal.y = (tuVector.x * vector2.y - tuVector.y * vector1.y) * den;
binormal.z = (tuVector.x * vector2.z - tuVector.y * vector1.z) * den;
D3DXVec3Normalize(&tangent, &tangent);
D3DXVec3Normalize(&binormal, &binormal);
D3DXVec3Cross(&normal, &tangent, &binormal);
D3DXVec3Normalize(&normal, &normal);
Есть ли способ либо рассчитать эти значения для каждой вершины, возможно, используя нормаль, поставляемую с моделью, либо как-то сгладить их, чтобы модель не выглядела граненой?
1 ответ
Для гладких поверхностей (без краев) я делаю это так:
создать пространство для каждой вершины
double N[3]; //normal int cnt;
для каждой вершины
N={0.0,0.0,0.0} cnt=0;
вычислить по лицу нормально
норма должна быть нормализована длина =1,0!!! Добавь это
Normal
ко всем вершинам, используемым в грани и приращенииcnt
для всех вершин, используемых в лиценормализовать каждую вершину
N/=cnt; // N = average normal from all vertex - neighbour faces
быть осведомленным
cnt=0
для неиспользуемых вершин (деление на ноль)на вершину
N
содержит нормальный вы хотитесейчас посчитаем
T,B
векторы для матрицы TBN (на вершину), как вы делаете сейчасвыходное изображение гладкое
Мой предварительный просмотр Земли (с атмосферным рассеянием, рельефом и многим другим...) находится здесь
Надеюсь, поможет