Jump to content
  • Advertisement
Sign in to follow this  
Endar

Cube normals

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

I've got a cube with its points:
(-0.5f,  0.5f,  0.5f)
(-0.5f, -0.5f,  0.5f)
( 0.5f,  0.5f,  0.5f)
( 0.5f, -0.5f,  0.5f)
( 0.5f, -0.5f, -0.5f)
( 0.5f,  0.5f, -0.5f)
(-0.5f,  0.5f, -0.5f)
(-0.5f, -0.5f, -0.5f)

And I put its normals in the same spots, because the normals are defined per-vertex. Is this the right way so it can be seen whichever vertices are rotated and pointing at the camera? So we can see all three sides?

Share this post


Link to post
Share on other sites
Advertisement
Well in a cube each vertex is used three times -- once for each side of the cube. Each use, in this sense, requires a different normal. So if you want per vertex normals in a cube you will need 24 vertices instead of eight. The positions will be repeated.

Illco

Share this post


Link to post
Share on other sites
Really? Well, I called it per-vertex because I'm using vertex arrays in OGL.


class CVertex3d
{

CVector3d pos;
CVector3d normal;
float u,
v;
CColor color;

};



That's my vertex class.

When you say that each vertex is used three times, once for every side of the cube, do you mean that its processed 3 times? Because I thought that vertex arrays were supposed to stop that.

Or am I misunderstanding?

Share this post


Link to post
Share on other sites
one normal per vertex perpendicular to the current face will result in a flat-shaded cube and for that, 36 normals are waay overhead - if you're up for a flat-shaded cube, you can use a per-face normal.


What i recommend is to create a cube using 8 vertices, 8 normals (not perpendicular to any xyz plane) and an indexbuffer

Share this post


Link to post
Share on other sites
If you want flat shading you either have to specify each unique vertex (vertex meaning position and normal), resulting in 24 vertices:
GLfloat const positions[] =
{
-0.5, 0.5, 0.5,
-0.5, 0.5, 0.5,
-0.5, 0.5, 0.5,
-0.5, -0.5, 0.5,
-0.5, -0.5, 0.5,
-0.5, -0.5, 0.5,
0.5, 0.5, 0.5,
0.5, 0.5, 0.5,
0.5, 0.5, 0.5,
0.5, -0.5, 0.5,
0.5, -0.5, 0.5,
0.5, -0.5, 0.5,
0.5, -0.5, -0.5,
0.5, -0.5, -0.5,
0.5, -0.5, -0.5,
0.5, 0.5, -0.5,
0.5, 0.5, -0.5,
0.5, 0.5, -0.5,
-0.5, 0.5, -0.5,
-0.5, 0.5, -0.5,
-0.5, 0.5, -0.5,
-0.5, -0.5, -0.5,
-0.5, -0.5, -0.5,
-0.5, -0.5, -0.5
};

GLfloat const normals[] =
{
-1, 0, 0,
0, 1, 0,
0, 0, 1,
-1, 0, 0,
0, -1, 0,
0, 0, 1,
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 0, 0,
0, -1, 0,
0, 0, 1,
1, 0, 0,
0, -1, 0,
0, 0, -1,
1, 0, 0,
0, 1, 0,
0, 0, -1,
-1, 0, 0,
0, 1, 0,
0, 0, -1,
-1, 0, 0,
0, -1, 0,
0, 0, -1
};

GLubyte const indices[] =
{
0, 3, 21, 18,
4, 10, 13, 22,
2, 8, 11, 5,
6, 15, 12, 9,
1, 19, 16, 7,
14, 17, 20, 23
};

or you can take advantage of that fact that as long as you are drawing quads each face has more vertices than each vertex has faces and that under flat shading mode OpenGL should use the last specified vertex attribute for the entire face. In this case you should be able to use:
GLfloat const positions[] =
{
-0.5, 0.5, 0.5,
-0.5, -0.5, 0.5,
0.5, 0.5, 0.5,
0.5, -0.5, 0.5,
0.5, -0.5, -0.5,
0.5, 0.5, -0.5,
-0.5, 0.5, -0.5,
-0.5, -0.5, -0.5,
};

GLfloat const normals[] =
{
0, 0, 0, // doesn't matter
0, 0, 1,
0, 1, 0,
1, 0, 0,
0, 0, -1,
0, 0, 0, // doesn't matter
-1, 0, 0,
0, -1, 0
};

GLubyte const indices[] =
{
0, 1, 7, 6,
1, 3, 4, 7,
0, 2, 3, 1,
2, 5, 4, 3,
0, 6, 5, 2,
5, 6, 7, 4
};

Disclaimer: neither of these are tested!

Enigma

Share this post


Link to post
Share on other sites
Endar,

The thing is that if you only have the vertices declared, the polygons may be triangles, squares, whatever. You need some separate information telling you which vertices make up which polygons, like an index ^^^. Most 3d export formats take care of that. Now,

1. As you are reading in the faces, calculate face normals by doing a cross product of the vectors making up 2 sides of the polygon. Each model format has a anticlockwise or clockwise arrangement of vertices for each poly, check that out so you get the correct direction for the cross product.

2. Add the face normal to that of each vertex making up the polygon (CVector3D normal in your class).

3. Normalize the vertex normals looping through each vertex so that they have unit length.

And you're done! This way you have averaged out vertex normals - called smooth normals. Turn on smooth shading in opengl (glShadeModel), and sample the spectacular results! Have fun!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Normals aren't usually used at all in calculating which sides of the cube are visible. In OpenGL this is usually done using backface culling and/or depth buffering.

Normals are usually used for calculating lighting effects. In the case of a polyhedral object, each polygon forming that object's surface has normals that are perpendicular to that polygon, so one normal per polygon is enough.

The reason for assigning normals per vertex is for rendering objects which are only approximated by a polyhedron. For example, a sphere has normals that are always pointing away from the center, but in open GL you need to approximate it using normals. By assigning the correct normals at each vertex, the normals are interpolated across the polygons to produce shading that is close to what it would be if the polygon were actually curving. The polygon itself is still flat, but it gets shaded as if it were curved which helps significantly.

The way you describe your cube, with the per vertex normals the way they are, the result will be that the lighting will appear as if the sides were curved.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!