Jump to content
  • Advertisement
Sign in to follow this  

Is generating normals for this impossible...?

This topic is 5470 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

... or is it just so hard that you need to be a rocket scientist. I've been spending days on this by now. This GameDev topic is my last try to, hopefully, find a solution. My problem is pretty straightforward: - When generating vertices of my heightmap, I'm immediatly separating them in chuncks of 16x16 vertices, for my quadtree - After that, my indices are generated. Now, there's just one tough nut to crack: All the vertices are generated quad wise, instead of row wise. I just cannot believe I have only found one topic/article about this on the entire gamedev forums/articles, and Google doesn't bring up anything usefull either. I mean.. if you want to use quadtrees, you have to put your vertices in an order so you can simply say: quadtree[0].StartVertex = 0 quadtree[0].VertexAmount = 100 quadtree[0].StartIndex = 1200 quadtree[0].Indices = 600 Right? Without generating your vertices to be quad wise instead of row-wise, this is impossible, as far as I can figure out. (The numbers are going wrong after 9, but it should show how everything is arranged, it's like 1/9) I've tried so many things, that showing all the code would fill pages. I only turn to GameDev when I'm really desperate :). The problem: The normals are simply generated incorrect, not taking into account the borders. I was using the code from Andy's site:
D3DXVECTOR3 CTerrain::GetTriangleNormal(D3DXVECTOR3* vVertex1,
D3DXVECTOR3* vVertex2, D3DXVECTOR3* vVertex3)
    D3DXVECTOR3 vNormal;
    D3DXVECTOR3 v1;
    D3DXVECTOR3 v2;

    D3DXVec3Subtract(&v1, vVertex2, vVertex1);
    D3DXVec3Subtract(&v2, vVertex3, vVertex1);

    D3DXVec3Cross(&vNormal, &v1, &v2);

    D3DXVec3Normalize(&vNormal, &vNormal);

    return vNormal;

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

        vNormal = GetTriangleNormal(&D3DXVECTOR3(pcvVertices[dwVertex1].x, pcvVertices[dwVertex1].y,


        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

    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;

Which worked well, until I started with the quad ordered vertices. I have tried other code, takin into account 4 positions around, using the vertex position instead of the indices, which are generated like this:
	int iCalcX = 0, iCalcY = 0;
		DWORD CurrVertex = 0;
		int QuadNum = 0;
		int VertsPerQuad = (Size * Size);
		int RowNum = 0;
		int ColsPerRow = 8;
		for (QuadNum = 1; QuadNum < 85 ; QuadNum++) {
			pNode = &objQuadTree.pNodeList[QuadNum];					
			//Is it a leaf?
			if (pNode->bType == LEAF_TYPE) {
				//Back to 8x8 grid position
				iCalcX = (pNode->vBoundingCoordinates[0].x + 1024)/256;
				iCalcY = (pNode->vBoundingCoordinates[0].z + 1024)/256;
				//Calculate row/col position
				QuadPosition = ((iCalcY * 8) + iCalcX);
				pNode->bGridRow = (BYTE)iCalcY; //Store row position
				pNode->bGridCol = (BYTE)iCalcY; //Store col position

				//Calculate start values
				pNode->StartIndices = n;
				pNode->MinVertex = (VertsPerQuad*QuadPosition);

				for (y = 0; y < 16;y++)	{
					for (x = 0; x < 16;x++)	{
						CurrVertex = (VertsPerQuad*QuadPosition)+(y*Size) + x;

						pIndices[n++] = CurrVertex;	// triangle 1
						pIndices[n++] = CurrVertex+1;	// triangle 2  
						pIndices[n++] = CurrVertex+Size;	// triangle 3
						pIndices[n++] = CurrVertex+Size+1;	// triangle 3
						pIndices[n++] = CurrVertex+Size;	// triangle 4
						pIndices[n++] = CurrVertex+1;	// triangle 5


				//Calculate end values. Divide indices by 3 already.
				pNode->IndicesLength = (n - pNode->StartIndices) /3;
				pNode->NumVertex = (VertsPerQuad*(QuadPosition+1)) - pNode->MinVertex;

(some things are hardcoded for testing) It looks all good: But the terrain is acting weird too: I hope someone can help me on this. If you need more info, simply ask. So note though: I have never access to full vertex row data, as it's organized by quadtree level. Any help appreciated, Almar

Share this post

Link to post
Share on other sites
Computing normals for vertices and placing verticies into a quadtree are two separate things. First do one, then the other.


Share this post

Link to post
Share on other sites
Note that you can compute normals without knowing anything about the neighboring vertices, if you know the data that generated those vertices. Thus, you can compute a normal per vertex by just evaluating the slope of your heighfield at the point in question; say by running a Sobel filter on the height map data around the point that generated the vertex.

Share this post

Link to post
Share on other sites
I generally find it handy to have a method of querying height values by absolute coords rather than just by trying to manually extract the vertices from whatever crazy optimised format you've got for rendering. Then normal generation will become much easier.

For the second problem of your terrain looking odd, it looks as if you've forgotten to turn on depth testing, and chunks are being drawn over the top of each other.

Share this post

Link to post
Share on other sites
I'm going to try one more time tommorow, using the heightmap directly (did that before though)

If it won't work (which will probably happen), I'm going to change my stuff row-based again, and think of a new structure. I got the theory on paper already.

As for the rendering: the Z buffer is enabled, if that's what you mean. (16 bit though, my *uch* voodoo3 doesn't like 32).

Thanks :)

Share this post

Link to post
Share on other sites

That's a lot better :). The squary look. That's the vertex lighting I guess? Still haven't found out how to solve the hills being transparant though.

Thanks :)

Share this post

Link to post
Share on other sites
You're just not enabling backface culling. Or Z-buffering. Either will fix that; you're drawing the terrain behind the hill after you draw the hill, which means it gets drawn overtop.

Share this post

Link to post
Share on other sites
Yeah, I got it fixed. somehow the Zbuffer wasn't doing very properly - But it didn't give any errors either.

Now it's time for some detail texturing :)

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!