Jump to content

  • Log In with Google      Sign In   
  • Create Account


[DirectX] Normale calculation


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 Plerion   Members   -  Reputation: 364

Like
0Likes
Like

Posted 24 February 2011 - 02:17 PM

Hello everyone

Its the first time im using lighting in my scene so im not that experienced with it yet. For the light im in need of normals for my terrain. My terrain is built up from several patches which overlap each other always at the edges. So calculating the normals for each face does not give the correct results at the edges of the chunks (youll see a border when lighting) and so ive decided to take the current land height at 4 points around the vertices from the terrain handler. This is very fast and gives the same accuracy as its using intersection. Thats how my algorithm looks at the moment:

void MTFChunk::RedoNormals()
{
	for(uint32 i = 0; i < m_vertices.size(); ++i)
	{
		Vector3 N1, N2, N3, N4;
		Vector3 P1, P2, P3, P4;

		P1->x = m_vertices[i].x - m_unitSize;
		P1->z = m_vertices[i].z - m_unitSize;
		if(!m_terrainMgr.GetLandHeight(P1))
			P1->y = m_vertices[i].y;

		P2->x = m_vertices[i].x + m_unitSize;
		P2->z = m_vertices[i].z - m_unitSize;
		if(!m_terrainMgr.GetLandHeight(P2))
			P2->y = m_vertices[i].y;

		P3->x = m_vertices[i].x + m_unitSize;
		P3->z = m_vertices[i].z + m_unitSize;
		if(!m_terrainMgr.GetLandHeight(P3))
			P3->y = m_vertices[i].y;

		P4->x = m_vertices[i].x - m_unitSize;
		P4->z = m_vertices[i].z + m_unitSize;
		if(!m_terrainMgr.GetLandHeight(P4))
			P4->y = m_vertices[i].y;

		Vector3 vert(m_vertices[i].x, m_vertices[i].y, m_vertices[i].z);

		N1 = (P2 - vert).Cross(P1 - vert).Normalized();
		N2 = (P3 - vert).Cross(P2 - vert).Normalized();
		N3 = (P4 - vert).Cross(P3 - vert).Normalized();
		N4 = (P1 - vert).Cross(P4 - vert).Normalized();

		Vector3 Norm = N1 + N2 + N3 + N4;
		Norm.Normalize();

		m_vertices[i].nx = Norm->x;
		m_vertices[i].ny = Norm->y;
		m_vertices[i].nz = Norm->z;
	}
}


Ive looked trough it with the debugger and seen the following:
GetLandHeight gives the correct height. It never returned false so far which means that it could determine the landheight for every vertex.

Though the result is not really satisfying:
http://www.imagr.eu/img/4d66bc165e0471

During editing of the terrain the light flickers and does weird things so obviously the above code yields completely incorrect results! To make sure the errors come not from my setup ive tasted a face based approach. This gives good results inside the chunks but makes bad borders at the chunk borders.

Greetings
Plerion 



Sponsor:

#2 Dawoodoz   Members   -  Reputation: 294

Like
1Likes
Like

Posted 24 February 2011 - 04:00 PM

A simple and reusable method is to first generate faceted normals and then let each group of vertices on the same place calculate a normalized weighted average.

A faster and better looking way would be to render the terrain to a high resolution heightmap and apply blur and noise so that you can generate a world space normal map. Just sample the normal map instead of getting the normal from vertices to get normal mapping to your shader.

My open source DirectX 10/11 graphics engine. https://sites.google.com/site/dawoodoz

"My design pattern is the simplest to understand. Everyone else is just too stupid to understand it."


#3 Plerion   Members   -  Reputation: 364

Like
0Likes
Like

Posted 26 February 2011 - 09:03 AM

Thanks for your tips!

Ive reworked my algorithm and now it looks pretty nice:
http://imagr.eu/up/4d69159ccdc7e7_ter.jpg







Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS