(-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)
Cube normals
I've got a cube with its points:
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?
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
Illco
Really? Well, I called it per-vertex because I'm using vertex arrays in OGL.
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?
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?
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
What i recommend is to create a cube using 8 vertices, 8 normals (not perpendicular to any xyz plane) and an indexbuffer
If you want flat shading you either have to specify each unique vertex (vertex meaning position and normal), resulting in 24 vertices:
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:
Disclaimer: neither of these are tested!
Enigma
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
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!
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!
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement