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 > |