Re: [Algorithms] Terrain Normals
Brought to you by:
vexxed72
|
From: Klaus H. <k_h...@os...> - 2000-08-14 12:06:17
|
Not sure what you mean by "horizontally dimmed banding", but I guess you are
talking about the typical Gouraud shading artifacts. This can happen, if the
light intensity at adjacent vertices differs very much (e.g. the two
vertices shared vertices of two triangles are white, and the other two
non-shared vertices of the two triangles are black).
Personally, I use pre-lit textures or lightmaps (using Phong shading) to
eliminate this effect, but the following algorithm to compute the vertex
normals should already reduce (or maybe even eliminate) those seams (Thanks
to Peter Dimov for the algorithm :).
void VertexNormal(
Vector3& normal,
long col,
long row,
float gridSpacing)
{
float nx, nz, denom;
if (col > 0 && col < m_fieldSize - 1)
{
nx = GetElev(col - 1, row) - (col + 1, row);
}
else if (col > 0)
{
nx = 2.0f * (GetElev(col - 1, row) - GetElev(col, row));
}
else nx = 2.0f * (GetElev(col, row) - GetElev(col + 1, row));
if (row > 0 && row < m_fieldSize - 1)
{
nz = GetElev(col, row - 1) - GetElev(col, row + 1);
}
else if (row > 0)
{
nz = 2.0f * (GetElev(col, row - 1) - GetElev(col, row));
}
else nz = 2.0f * (GetElev(col, row) - GetElev(col, row + 1));
gridSpacing *= 2.0f;
denom = 1.0f / sqrt(nx * nx + gridSpacing * gridSpacing + nz * nz);
normal.x = nx * denom;
normal.y = gridSpacing * denom;
normal.z = nz * denom;
}
"normal" is the unit vertex normal that is returned by the function. "(col,
row)" represents the data point in the height field for which you want to
compute the vertex normal, and "gridSpacing" is the spacing between two
adjacent vertices (normally, gridSpacing is 1, unless you decide to scale
the height field). Finally, GetElev() return a elevation of a particular
data point in the height field.
HTH,
Niki
----- Original Message -----
From: Pai-Hung Chen <pa...@ac...>
To: <gda...@li...>
Sent: Monday, August 14, 2000 8:22 AM
Subject: [Algorithms] Terrain Normals
> Hi,
>
> I've written a routine to read a bitmap heightfield and construct a
terrain
> mesh from it. I partition each set of four pixels into two triangles
along
> the upper-right-to-lower-left diagonal line. Therefore, for example, a
128
> x 128 bitmap will produce (128-1) x (128-1) x 2 = 32258 triangles using my
> method. For each triangle I caculate its unit face normal. For each
vertex
> of a triangle, I calculate its vertex normal by adding and averaging the
> face normals of all triangles that share the vertex (in my case a vertex
can
> be shared by at most six triangles and at least one triganle) and then
> normalize the averaged normal, which is used in redering. My problem is
> that there are some *horizontal dimmed banding* effects along the triangle
> edges of the mesh when rendering in D3D with light cast on it. Also,
there
> are very visible dimmed seams between triangles when light is cast on it.
> All these artifacts seem to manifest only when light is cast in large
angles
> (i.e. not directly). Is it because the arrangement of triangles in my
mesh
> is too *uniform* (actually they are extremely uniform)? Or is my
> calculation of vertex normals incorrect?
>
> Thanks in advance,
>
> Pai-Hung Chen
>
>
>
> _______________________________________________
> GDAlgorithms-list mailing list
> GDA...@li...
> http://lists.sourceforge.net/mailman/listinfo/gdalgorithms-list
>
|