Гладкий шейдер в OpenGL для импорта OBJ?

Я использую загрузчик OpenGL OBJ, который можно скачать Вот!

Я экспортировал модель OBJ из Blender.
Проблема в том, что я хочу добиться плавного затенения.
Как видите, здесь не все гладко.
Как мне этого добиться? Может, что-то не так у обычного векторного калькулятора?

float* Model_OBJ::calculateNormal( float *coord1, float *coord2, float *coord3 )
{
/* calculate Vector1 and Vector2 */
float va[3], vb[3], vr[3], val;
va[0] = coord1[0] - coord2[0];
va[1] = coord1[1] - coord2[1];
va[2] = coord1[2] - coord2[2];

vb[0] = coord1[0] - coord3[0];
vb[1] = coord1[1] - coord3[1];
vb[2] = coord1[2] - coord3[2];

/* cross product */
vr[0] = va[1] * vb[2] - vb[1] * va[2];
vr[1] = vb[0] * va[2] - va[0] * vb[2];
vr[2] = va[0] * vb[1] - vb[0] * va[1];

/* normalization factor */
val = sqrt( vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2] );

float norm[3];
norm[0] = vr[0]/val;
norm[1] = vr[1]/val;
norm[2] = vr[2]/val;return norm;
}

И glShadeModel (GL_SMOOTH) установлен.

Есть идеи?

0

Решение

Если вы хотите сделать плавное затенение, вы не можете просто вычислить нормаль для каждой вершины треугольника для каждого треугольника, как вы это делаете сейчас. Это привело бы к плоскому затенению.

Чтобы сделать плавное затенение, вы хотите суммировать вычисленные для каждого треугольника нормали к соответствующим вершинам, а затем нормализовать результат для каждой вершины. Это даст своего рода усредненный вектор, который указывает в гладком направлении.

В основном возьмите то, что вы делаете, и добавьте получившийся нормальный треугольник ко всем его вершинам. Затем нормализуйте суммированные векторы для каждой вершины. Это будет выглядеть примерно так (псевдокод):

for each vertex, vert:
vert.normal = vec3(0, 0, 0)

for each triangle, tri:
tri_normal = calculate_normal(tri)
for each vertex in tri, vert:
vert.normal += tri_normal

for each vertex, vert:
normalize(vert.normal)

Однако это обычно не требуется при загрузке из файла OBJ, подобного этому, и модели с твердой поверхностью, подобной этой, обычно требуется доля складок и острых углов, чтобы смотреть туда, где нормали не являются абсолютно гладкими и непрерывными везде. Файлы OBJ обычно хранят нормали для каждой вершины внутри, так как художник хотел, чтобы модель выглядела. Поэтому я бы посмотрел на ваш загрузчик OBJ и увидел, как правильно извлечь из него нормали, содержащиеся в файле.

1

Другие решения

Спасибо, приятель! В Blender я нашел возможность экспортировать нормальные векторы, поэтому теперь я полностью переписал структуру данных, чтобы управлять и обычными векторами. Теперь это выглядит гладко! образ

0