Public Group

Normals problem

This topic is 3080 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm trying to get some lighting working here but I get this problem. Parts of the model close to edges take on those colors shown here in this animation:

I want those triangles on the edge to be the same colour as the rest of the flat ground, not the side of the cliff

my normal calculation is done here, with 2 ways to calculate (left or right handed, i can never remember which way the strip is oriented) but neither of them seem to solve the problem:

void ClipMap::setNormals(unsigned int ii, unsigned int jj, Distant& theDistant){	normals_1[ii][jj].members[0] = 0;	normals_1[ii][jj].members[1] = 0;	normals_1[ii][jj].members[2] = 0;	normals_2[ii][jj].members[0] = 0;	normals_2[ii][jj].members[1] = 0;	normals_2[ii][jj].members[2] = 0;/*  method 1	if ( (ii < theDistant.size2n) && (jj < theDistant.size2n) )	{		normals_1[ii][jj].members[0] = (float)sectors[ii+1][jj].height - sectors[ii][jj].height;		normals_1[ii][jj].members[1] = -1;		normals_1[ii][jj].members[2] = (float)sectors[ii+1][jj+1].height - sectors[ii+1][jj].height;	}	if ( ii != 0 && jj != 0 )	{		normals_2[ii][jj].members[0] = -(float)sectors[ii-1][jj].height + sectors[ii][jj].height;		normals_2[ii][jj].members[1] = -1;		normals_2[ii][jj].members[2] = -(float)sectors[ii-1][jj-1].height + sectors[ii-1][jj].height;	}*/	if ( ii < theDistant.size2n && jj > 0)	{		normals_1[ii][jj].members[0] = (float)sectors[ii+1][jj].height - sectors[ii][jj].height;		normals_1[ii][jj].members[1] = -1;		normals_1[ii][jj].members[2] = (float)sectors[ii+1][jj].height - sectors[ii+1][jj-1].height;	}	if ( ii > 0 && jj < theDistant.size2n )	{		normals_2[ii][jj].members[0] = -(float)sectors[ii-1][jj].height + sectors[ii][jj].height;		normals_2[ii][jj].members[1] = -1;		normals_2[ii][jj].members[2] = -(float)sectors[ii-1][jj].height + sectors[ii-1][jj+1].height;	}}

and this is the drawing function that increments on j:

for (unsigned int i = 0; i < theDistant.size2n; i++)	{		glBegin( GL_TRIANGLE_STRIP );			for (unsigned int j = 0; j <= theDistant.size2n; j++)	{				int iunit = i*unit_secsize;				int junit = j*unit_secsize;...					glNormal3fv(normals_2[i+1][j].members);					glVertex3i(iunit+unit_secsize, 						sectors[i+1][j].height,						junit);					glNormal3fv(normals_1[j].members);					glVertex3i(iunit, 						sectors[j].height,						junit);...}}

the normals and heightmap exist in the clipmap class

class ClipMap{	public:	int level;	int tvect_x;	int tvect_z;	float tvect_x_secsize;	float tvect_z_secsize;	int unit;	int unit_secsize;	int half_unit_secsize;	int side;	int width;	float zBuf_inner;	float zBuf_outer;	int player_mod_x;	int player_mod_z;	unsigned int clip_l;	unsigned int clip_u;	unsigned int shiftmod_x;	unsigned int shiftmod_z;	unsigned int shiftmod_not_x;	unsigned int shiftmod_not_z;	unsigned int shiftmod_notx_notz;	unsigned int shiftmod_x_and_z;	unsigned int shiftmod_notx_and_z;	unsigned int shiftmod_x_and_notz;	Sector sectors[257][257];	Vectorf normals_1[257][257];	Vectorf normals_2[257][257];	inline void setPlayerMods(Player& thePlayer);	inline void setTvects(Distant& theDistant, World& theWorld);	inline void setClips(Distant& theDistant);	inline void setShifts(Distant& theDistant);	void setMeta(int F, Distant& theDistant, World& theWorld);	void setVars(Player& thePlayer, Distant& theDistant, World& theWorld);		void setSectors(Player& thePlayer, Distant& theDistant, World& theWorld);	void setNormals(unsigned int ii, unsigned int jj, Distant& theDistant);	void setAllNormals(Distant& theDistant);	void shiftSectors(int x, int z, Player& thePlayer, Distant& theDistant, World& theWorld);	void drawSea(Distant& theDistant, float sealevel);	void drawMap(Game& theGame, Distant& theDistant);};

(In the preview the '+' sign is not showing up in the array notation so it looks like 'i 1' but it should be 'i+1')

Share on other sites
Perhaps a bigger issue,
when I define my positional light with an array of the form
float array = {  cos(theta), -sin(theta), 0.f, 0.f   };glLightfv(GL_LIGHT0, GL_POSITION, array);

it should be a directional light source that rotates with theta around the z axis-- but whether -sin(theta) = 1 or -1 (that should mean the light is pointing straight up or straight down) the terrain is dark in both cases

negative -sin(theta) (should point down):
http://i26.tinypic.com/311qj5i.jpg

positive -sin(theta) (should point up):
http://i28.tinypic.com/vulw3.jpg

Share on other sites
This is just a guess, but you could be averaging your face normals across the "cliff" divide, giving normals that look incorrect for either the face of the cliff, or the land above. You need to keep your normals separate so that there is a clear distinction between the face of the cliff and the land above it.

If you are using indexed vertices, this may mean duplicating the vertices on the edge to allow for the separate normals and not averaging the face normals with faces over the boundary (Ie for vertices on the face of the cliff, you don't want faces on the top of the cliff to be involved in the normal calculation).

Hope that helps. Like I said, it is just a guess.

Share on other sites
I figured out I was calculating normals incorrectly

1. 1
2. 2
Rutin
16
3. 3
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• Forum Statistics

• Total Topics
633709
• Total Posts
3013477
×