gpt4 book ai didi

c - 顶点法线的图形问题

转载 作者:太空宇宙 更新时间:2023-11-04 07:49:21 24 4
gpt4 key购买 nike

我已经在此处和其他页面中检查了几种用于计算顶点法线的解决方案。似乎最适合我自己的呈现 3D 地形的实现的常见解决方案是计算面法线,这不是问题。然后遍历每张脸并将其添加到构成它的顶点上,然后在完成后将其归一化。它似乎在大多数情况下都有效,但我有一些奇怪的图形问题,主要是光线从亮到暗的过渡,你可以分辨出脸在哪里。在下图中,您可以在这座山的顶部右下角附近看到它。

所以我想知道是什么导致了这种奇怪的模式。这与我计算法线的方式有关,但我只是看不出问题出在哪里。任何帮助,将不胜感激。 Lunar terrain render

计算法线的代码是...

// Calclulate surface normals
vec3 v1, v2, v3, vec1, vec2;
for(GLuint i = 0; i < terrain->NumFaces; i++) {
v1 = terrain->Vertices[terrain->Faces[i].vert_indices[0]];
v2 = terrain->Vertices[terrain->Faces[i].vert_indices[1]];
vec1 = vector(&v2, &v1);

v3 = terrain->Vertices[terrain->Faces[i].vert_indices[2]];
vec2 = vector(&v3, &v1);

terrain->Faces[i].surface_normal = crossProduct(&vec1, &vec2);

normalize(&terrain->Faces[i].surface_normal);
}


// Calculate vertex normals...
// Add all the surface normals to their attached vertex normals
for(GLuint currentFace = 0; currentFace < terrain->NumFaces; currentFace++) {
vec3 *f = &terrain->Faces[currentFace].surface_normal;
for(GLuint faceVertex = 0; faceVertex < 3; faceVertex++) {
vec3 *n = &terrain->Normals[terrain->Faces[currentFace].vert_indices[faceVertex]];
*n = vec3Add(n, f); // adds vector f to n
}
}

// Go over all vertices and normalize them
for(GLuint currentVertice = 0; currentVertice < terrain->NumVertices; currentVertice++)
normalize(&terrain->Normals[currentVertice]);

我在上面的代码中使用的其他实用函数是...

// Returns the vector between two vertices
vec3 vector(const vec3 *vp1, const vec3 *vp2)
{
vec3 ret;
ret.x = vp1->x - vp2->x;
ret.y = vp1->y - vp2->y;
ret.z = vp1->z - vp2->z;
return ret;
}


// Returns the normal of two vectors
vec3 crossProduct(const vec3 *v1, const vec3 *v2)
{
vec3 normal;
normal.x = v1->y * v2->z - v1->z * v2->y;
normal.y = v1->z * v2->x - v1->x * v2->z;
normal.z = v1->x * v2->y - v1->y * v2->x;

return normal;
}


// Returns the length of a vector
float vec3Length(vec3 *v1) {
return sqrt(v1->x * v1->x + v1->y * v1->y + v1->z * v1->z);
}


// Normalizes a vector
void normalize(vec3 *v1)
{
float len = vec3Length(v1);
if(len < EPSILON) return;
float inv = 1.0f / len;
v1->x *= inv;
v1->y *= inv;
v1->z *= inv;
}


// Adds vector v2 to v1
vec3 vec3Add(vec3 *v1, vec3 *v2)
{
vec3 v;

v.x = v1->x + v2->x;
v.y = v1->y + v2->y;
v.z = v1->z + v2->z;

return v;
}

最佳答案

使用面法线的平均值计算顶点法线的一个问题是计算出的法线可能有偏差。例如,假设有一条南北走向的山脊。山脊顶上的一个顶点在东边有三个多边形,在西边有两个多边形。顶点法线将向东倾斜。当照明来自西方时,这会导致该点的照明变暗。

一个可能的改进是对每个面的法线应用权重,与面角在该顶点处的角度成正比,但这不会消除所有偏差。

关于c - 顶点法线的图形问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54856040/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com