• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Hawkblood

Calculating normals

8 posts in this topic

I am using an indexed vertex buffer as a plane (10x10 sections). I can set the y-value for the vertex, but I don't know how to recalculate the normal for that vertex. I need some help with this.

0

Share this post


Link to post
Share on other sites
To calculate a normal for a single triangle you do the following.

x = cross(b - a, c - a)

where a, b, and c are points on the triangle and cross is the cross product of the two vectors.

Then to calculate a normal for a single point you simply sum up the normals for every face the point is part of then normalize it.
2

Share this post


Link to post
Share on other sites

I don't think I'm doing it correctly...... I have a plane that is subdivided into a 10x10 square grid. Each of the "squares" on the grid alternate the way the square is divided by the two triangles that make up the square (I hope I'm making sense). This will give me an alternating pattern accross the plane and will result in every other vertex being affected by 8 or 4 triangles. Here is the code so far:

			//calculate the normals
			bool rev=false;
			for (int py=1;py<10;py++){//these values will be for the interior vertexes only
				for (int px=1;px<10;px++) {

					D3DXVECTOR3 tmpv;
					if (rev){
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px-1][py-1].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px][py-1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px-1][py-1].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px-1][py].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px-1][py].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px-1][py+1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px-1][py+1].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px][py+1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px][py+1].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px+1][py+1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px+1][py+1].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px+1][py].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px+1][py].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px+1][py-1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px+1][py-1].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px][py-1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						Range0[i].vert[px][py].n/=8.0f;
					}
					else {
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px-1][py].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px][py-1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px+1][py].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px][py-1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px-1][py].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px][py+1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						D3DXVec3Cross(&tmpv,&(Range0[i].vert[px+1][py].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px][py+1].v-Range0[i].vert[px][py].v));
						Range0[i].vert[px][py].n+=tmpv;
						Range0[i].vert[px][py].n/=4.0f;
					}

					rev=!rev;

					D3DXVec3Normalize(&Range0[i].vert[px][py].n,&Range0[i].vert[px][py].n);
				}
			}

The Range0[i] is just the reference for the data of each plane. I'm only using 1 plane at the moment. This loop only normalizes the inside 9x9 verts because I will be normalizing the edge ones using data from the surounding planes of the terrain. The "rev" variable simply tells it to cycle between 8 and 4.

 

It's not coming out right, so I must be doing something wrong.....

0

Share this post


Link to post
Share on other sites

You need to normalise the result of the cross product, probably? Otherwise it's scaled by the sine of the angle between them.

 

You also don't need to divide by a constant scalar before normalising a vector, since scaling before normalisation is a waste of time.

 

EDIT: Also check that you are consistent with the order of your vectors in the cross product, since a X b = -b X a. Always go round the vertices in a consistent order (clockwise or anticlockwise).

Edited by Paradigm Shifter
1

Share this post


Link to post
Share on other sites

Have a look at this thread for calculating heightmap normals (sounds like that's what you're looking for:)

 

http://www.gamedev.net/topic/163625-fast-way-to-calculate-heightmap-normals/

(look at the 2nd post)

 

That's the simplest way and the way it's most commonly done.

 

HappyCoder's way works too, but the results you get will be dependent on the triangulation - switch the way the triangles are oriented and you'll get different results.

Edited by phil_t
1

Share this post


Link to post
Share on other sites
As Paradigm Shifter pointed out, you need to make sure the vertices are consistently being wound the correct way. If you reverse the winding then the normal would be pointing the wrong way.

I would reccomend breaking up that normalizing code. It is hard to follow. I would create a seperate method for calculating normals to begin with.
void CalculateNormal(D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV1, const D3DXVECTOR3 *pV2, const D3DXVECTOR3 *pV3)
{
D3DXVec3Cross(pOut, &(*pV2 - *pV1), &(*pV3 - *pV1));
}
Then I would calculate the normals on each face and apply them to the vertices rather than having each vertex recalculate the normal of the adjacent faces.

So the steps.

Set all vertex normals to zero.
Loop through each face and calculate the normal, then add that normal to the normals of all vertices in that face.
Loop through all the vertices and normalize them.

You can normalize each face normal as you calculate them before adding them to the vertex normal. That will give each adjacent face equal weight in calculating the vertex normal. If you don't normalize them then faces with a larger surface area will have a greater influence on the calculated normal. Depending on what you want you can go either way. If the areas are roughly the same then it wont make much of a difference.
1

Share this post


Link to post
Share on other sites

I don't just have:

    B

    |

C---O---A

    |

    D

Every other one has 8 instead of 4. I think I have it working. The only probjem occurs when (for instance) A,B,C,&D are at the same elevation. It has to have more verts to show it correctly. That's not a problem because the terrain won't vary that much within that small an area.

0

Share this post


Link to post
Share on other sites

What if you use all 8 neighbouring verts to calculate the normal in all cases (i.e. ignore the underlying triangulation and pretend there are always 8 triangles meeting at each vertex). Does that improve things?

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0