Jump to content
  • Advertisement
Sign in to follow this  
sirob

Another problem with normals.

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm here again, and again with a normal problem. This time, I'm getting a kind of square pattern where the terrain should be darker. I guess a picture's worth a thousand words, so here are 3: First Image Second Image Third Image I'm using traingle strips to draw the terrain, and heres the code I use to calculate the normals (if it helps). (all normals are calculated before the vertices are created:)
	for(short x=m_HMBuffer; x<(m_HMSize - m_HMBuffer); x++)
	{	
		for(short y=m_HMBuffer; y<(m_HMSize - m_HMBuffer); y++)
		{
			 D3DXVECTOR3 vec;
	 		 vec.x = -(m_MapRaw[x + 1 + (y * m_HMSize)] - m_MapRaw[x - 1 + (y * m_HMSize)]) / 1500.0f / 2.0f;
			 vec.y = -(m_MapRaw[x + ((y + 1) * m_HMSize)] - m_MapRaw[x + ((y - 1) * m_HMSize)]) / 1500.0f / 2.0f;
			 vec.z = 1.0f;
			 D3DXVec3Normalize(&vec, &vec);
			 Normals[x + (y * m_HMSize)].x = vec.x;
			 Normals[x + (y * m_HMSize)].y = vec.y;
			 Normals[x + (y * m_HMSize)].z = vec.z;
		}
	};


Thanks for reading :).

Share this post


Link to post
Share on other sites
Advertisement
Well, getting a weird thing in the dead middle of the quad is quite difficult, isn't it? [lol]

Personally, I don't quite get how you're making your normals - generally I just compute multiple normals for each vertex (1 per primitive the vertex composes) then average them. But hey! *bump*

Share this post


Link to post
Share on other sites
This was a method suggested by someone on this forum, and it definatly works better than the previous method I was using (which is what you're using).

I've done my best to check it out, but it always seems perfectly correct to me, just don't get it.

Share this post


Link to post
Share on other sites
Tip: write some code to display all of your normals as small coloured lines (I usually use two colours so you can easily see which end is which). Whenever I suspect there's a problem with the way I've generated/exported/loaded normals, that's the *first* thing I do so I can *see* if they look right, I'd highly recommend you do the same!


I too am highly suspicious of your method of normal generation. A few thoughts/questions:

- I'm assuming your world coordinate system is set up so Z points up - if not, then it looks like your Z and Y should be flipped.


- if m_MapRaw is a map of integer bytes then all that division is going to create some pretty small numbers and you're in danger of losing detail/precision.


- for smooth normals, the normals of neighbouring faces should be taken into account. Depending on how you're generating the vertex positions from the height map, it doesn't look like that code will do that - the result will be a more faceted appearance or at least something which shows up face boundaries (which is what your screenshots seem to show...).


- you'll get much smoother lighting if you compute the normals properly (I experimented quite a bit with normal computation last time I did a heightmap based terrain, including crazy things like deliberate denormals to account for self shadowing etc):

a. for each vertex, find all the neighbouring faces which use that vertex (or use any other vertex at the same position).

b. for each of those faces, compute a face normal by taking the cross product of two edges of the face. Use the final vertex position rather than the height map for the edges.

c. add all of those normals together and divide by the number of faces which use that vertex to find the average face normal.

d. normalize the result, that's your vertex normal.

e. repeat for all vertices.


You can optimise the above in a number of ways - such as compute all the face normals in one pass; store adjacency information; etc

Share this post


Link to post
Share on other sites
This looks more like a "denormalized normals" problem. Vertex normals can become denormalized (have length less than one) as they are interpolated across a face. This causes the kind of intensity variations seen in your terrain. In your pixel shader, try renormalizing the normal before using it in lighting calulations (easily done in ps2.x, tricker in ps1.x). If you're not using pixels shaders, I dont think this is solvable.

joe
image space

Share this post


Link to post
Share on other sites
Hi,

You got the exact same problem as I have. I was about to start a new thread, but saw this topic near the top of the list. Unfortunatly, I'm clueless too. (I also suffer from see through vertices in my terrain. No idea how I can fix that)




The quads are really quads :). These are separate trianglelist for my quadtree, so I can render them nicely with offset+length using drawindexedprimitive.

...and it started when I added that "quad division" system. Before that it was all smooth.

I thought the problems occured because the normals weren't taking into account the other quads, but I tried this, and it's not the problem.

My code, btw. (yes, got it somewhere from a tutorial :))


for(i = 0; i < m_dwNumOfIndices; i=i+3)
{
dwVertex1 = pBufferIndices;
dwVertex2 = pBufferIndices[i + 1];
dwVertex3 = pBufferIndices[i + 2];

vNormal = GetTriangeNormal(&D3DXVECTOR3(pcvVertices[dwVertex1].x, pcvVertices[dwVertex1].y, pcvVertices[dwVertex1].z),
&D3DXVECTOR3(pcvVertices[dwVertex2].x, pcvVertices[dwVertex2].y, pcvVertices[dwVertex2].z),
&D3DXVECTOR3(pcvVertices[dwVertex3].x, pcvVertices[dwVertex3].y, pcvVertices[dwVertex3].z));


pNumOfSharedPolygons[dwVertex1]++;
pNumOfSharedPolygons[dwVertex2]++;
pNumOfSharedPolygons[dwVertex3]++;

pSumVertexNormal[dwVertex1].x += vNormal.x;
pSumVertexNormal[dwVertex1].y += vNormal.y;
pSumVertexNormal[dwVertex1].z += vNormal.z;

pSumVertexNormal[dwVertex2].x += vNormal.x;
pSumVertexNormal[dwVertex2].y += vNormal.y;
pSumVertexNormal[dwVertex2].z += vNormal.z;

pSumVertexNormal[dwVertex3].x += vNormal.x;
pSumVertexNormal[dwVertex3].y += vNormal.y;
pSumVertexNormal[dwVertex3].z += vNormal.z;
}

//Unlock the index buffer
m_pIndexBuffer->Unlock();

// For each vertex, calculate the average normal
for(i = 0; i < m_dwNumOfVertices; i++)
{
vNormal.x = (float)pSumVertexNormal.x / pNumOfSharedPolygons;
vNormal.y = (float)pSumVertexNormal.y / pNumOfSharedPolygons;
vNormal.z = (float)pSumVertexNormal.z / pNumOfSharedPolygons;

D3DXVec3Normalize(&vNormal, &vNormal);

pcvVertices.nx = vNormal.x;
pcvVertices.ny = vNormal.y;
pcvVertices.nz = vNormal.z;
}


Share this post


Link to post
Share on other sites
S1CA:
1) yes, I am using the z as up.

2) the values I use for the m_MapRaw are from a .raw containing unsigned short values (16 bit). Accuracy isn't an issue with my heightmap.

3) regarding the normal calculation, I have reviewed the code several times, and I am quite sure they are correct. At any rate, heres a small explaination of how they are calculated:

with z being up, the x value of the normal vector is only affected by the two vertices at x+1 and x-1. the x value can be calculated easily by using the difference between these two (devided by 2, but that is irrelevant, since I don't want accurate lighting - I want good looking lighting, and I modify the calculations to make the difference more visible).

I hope you understood this :).

Anyways, back to the topic, I hope you could see that the normals are generally correct, and other than the problem I specified, they are just what I want.

Also, with texturing on, they are hardly visible.

As a last resort, I'll try the straightforward calculation for the normals (though I've tried it before and have run into bigger difficulties), but I won't be able to do it in the near future though.

Scoob Droolins:

I'm not using a PS, and since the last NormalizeVector shown in my code above, I don't change the size or anything about the normals. They should be normalized.

ajoling:

I'm sorry, I don't see the resemblance. I'm not suffering from disappearing vertices, and couldn't see anything in your screenshots that has something to do with my problem.

Regarding your problem, I'd try two things:

1: make sure Z buffer is on and isn't suffering from accuracy issues (set it to 32 bit).

2: calculate the normals for the entire terrian before splitting it up into many peices. Your second screenshot reminds me of a problem I had when trying to split my terrain into an array. I had to calculate all the normals first, and then make the vertices for the terrain using the precalculated normals. Anything else I tried just didn't solve it.

Good Luck, and thanks for all the replies.

Share this post


Link to post
Share on other sites
Quote:
Original post by sirob
ajoling:

I'm sorry, I don't see the resemblance. I'm not suffering from disappearing vertices, and couldn't see anything in your screenshots that has something to do with my problem.

Regarding your problem, I'd try two things:

1: make sure Z buffer is on and isn't suffering from accuracy issues (set it to 32 bit).

2: calculate the normals for the entire terrian before splitting it up into many peices. Your second screenshot reminds me of a problem I had when trying to split my terrain into an array. I had to calculate all the normals first, and then make the vertices for the terrain using the precalculated normals. Anything else I tried just didn't solve it.

Good Luck, and thanks for all the replies.


http://www.devimg.net/UserImage.php?Post=345&Pic=Image3.jpg

Looks awfully like my situation with the lines between the quads. Well, sorry if I were wrong :)

I'll try your suggestion. Thanks! :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!