If I have cube whose edges are parallel to the axes and is centered at the origin, is it correct that the normals are parallel to the axes or in other words only one component in normal vector can be non-zero and the other two components must be zero? IF x,y,z, is normal vector then if x is not zero then y and z must be zero?
In OpenGL ES application how many normals are needed for proper lighting? Do We need one normal per vertex, or one normal per triangle or one normal per surface?
These 2 lines of code are related to this question:
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glNormalPointer(GL10.GL_FLOAT, 0, mNormalBuffer);
How OpenGL ES knows which normal corresponds with which triangle, or vertex or surface of the mesh being drawn?
Normals are specified per vertex and do not have to be parallel to an axis (although they will be in your cube's case), they must be of unit length and perpendicular to the surface that your mesh is approximating.
Check out this answer to a similar question.
Related
I have two cylinders which intersect on one end. I can change the radius of the intersection separately but still they meet at one end as shown below. However, I want the intersection between these two be smooth or in other words, their normals in the intersection to be shared as mentioned here: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/.
I have set the normal updates TRUE, and also change all the y components of the normals to zero in the intersection. It is still not showing a smooth intersection. These two cylinders are made with BufferGeometry.
so part of my code that is more important: 1- since the geometry is BufferGeometry, I use two commands below first for both geometries to create the normals:
comp.mesh.geometry.computeFaceNormals();
comp.mesh.geometry.computeVertexNormals();
2- then since both geometries has same number of vertices, I set y component of all vertices to 0:
for (i=0;i<comp.mesh.geometry.attributes.position.array.length;i++){
comp.mesh.geometry.attributes.normal.array[i*3 + 1] = 0;
comp1.mesh.geometry.attributes.normal.array[i*3 + 1] = 0;
}
When I let the program show the normals, their y component of normals is 0, but the geometry is not smooth yet.
I think the only way possible to do this is to weld these points. You need to check for duplicates, and assign them the same index. Use these indecis for triangulation and for vertex normal computation.
I'm writing a WebGL program that draws a bunch of triangles to the screen. I'm using indirect addressing, so something like this:
gl.drawElements(gl.TRIANGLES, list.length, gl.UNSIGNED_SHORT, 0);
Is there any way for the vertex shader to know which vertex of a triangle it is processing? (among the three vertices in the order given by the list, i.e., the first, second or last)
You can use additional integer attribute in stride alongside with vertex coordinates, texture coordinates, normal, etc. to check ID of vertex.
If you target OpenGL ES 3+ you can use gl_VertexID - https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/gl_VertexID.xhtml
I'm using OpenGL ES 1.1 and working on converting an OBJ export from Blender into some binary files containing vertex data. I actually already have a working tool, but I'm working on changing some things and came across a question.
Even with Smooth shading, it seems that with correct normals (perpendicular to the face plane) it achieves a flat appearance for faces. With Smooth shading enabled and the proper normals (simply via edges marked as sharp in Blender and an edge-split modifier applied), I can get the affect of smooth parts and sharp edges.
Where I'm going with this brings 2 questions.
Are the "s 1" or "s off" lines where smooth or flat shading is denoted in the OBJ file completely unnecessary from a smooth shading and use of normals standpoint?
When actually set to Flat shading in OpenGL, are normals completely ignored (or just assumed to all be perpendicular to the faces)?
For a vertex to look smooth, its normal has to be the average of the adjacent face normals (or something the like), but not perpendicular to the face plane (except if you meaned the average plane of all its adjacent faces).
GL_FLAT means, the color of a face is not interpolated over the triangle, but taken from a single triangle corner (don't know which, first or last). This color comes either from vertex colors or vertex lighting, so in fact you get per-face normals, but this is not neccessarily the faces direction, but the normal of a corner vertex.
If you got per vertex normals in the OBJ file you do not need the s parts. But you can use these to compute vertex normals. The s parts are the smoothing groups and are to be interpreted as 32bit bitfields. So there are actually 32 different smoothing groups and every face can be part of more than one. So all faces after an "s 5" line are part of smoothing groups 1 and 3 (first and third bits set). When two neighbouring faces are part of the same smoothing group, the edge between them is smooth (vertices share normals). This way you can reconstruct the neccessary per-vertex normals.
Changing the mode between gl_flat and gl_smooth doesn't seem to affect my rendering when I'm using per vertex normals. Your problem from what I can tell is that each face only has one normal. For smooth shading, each face should have three normals, one for each vertex, and they should all be different. For example, the normals of a cylinder, if projected inside of the cylinder, should all intersect at the axis of the cylinder. If your model has smooth normals, then an OBJ export should export per vertex normals. It sounds like you are probably assigning per face normals. As far as rendering in OpenGL-ES, the smoothing groups aren't used, only normals.
A cube has 8 unique vertices. Is it true that each of these 8 vertex normals (unit vectors) is making 135 degree angle to each of the edges which shares that vertex? And the vertex normal pointing outward/out of the cube? Your answer should be technically correct. Or it depends on how the cube is defined (drawn) like using triangle strips or indices that define 2 triangles for each side of the cube? The purpose of the vertex normal is smooth shading and lighting in OpenGL ES application.
If the cube is defined by 8 unique vertices, then the normals will likely be making a 135 degree angle to each edge, as you mentioned.
However, a cube is often defined using 24 vertices for exactly this reason. This allows you to have vertex normals that are perpendicular to each face, by "duplicating" vertices at each corner. Defining a cube this way is, effectively, just defining 6 individual faces, each pointing outwards appropriately.
There is no point in smoothing the cube with 8 vertices in order to make it look like a sphere. You'll get an extremely ugly sphere this way. The only reasonable way to draw the cube is using 24 unique vertices.
The center-oriented normals of the eight corner vertices of a cube will actually form an angle of 125 degrees, 16 minutes with each connected edge.
There's a good discussion of this topic elsewhere on SO.
The 135 degree can be explained visually by the normal vector of each vertices point outwards and must share the same angle with each edge the vertex is part of. Since the inner angle is 90 degree 270 degrees are outward of this corner. Therefore 270 degree /2 = 135 degree.
The normal vectors of each vertex are used to calculate the normal vector of the triangle. For your 3d model being a collection of flat triangles, having only a single normal to calculate the lighting from it would result in flat shading (thou being physically correct if the object really would be that edgy). Using the vertex normals to interpolate the 'normals' for each point of the triangle gives a smooth lighting reassembling a smooth surface.
The problem with this approach is using only a single normal per vertex results in the cube to have a shading like a sphere while still being a cube.
That is basically the reason why one want to define a cube with 24 (= 6x4) vertices rather than 6. This way one can have a cube with all faces (and therefore each two of its triangles) to have correct (flat) normals.
Having 24 vertices and therefore 24 normals provide the possibility to define only forward facing normals for each triangle/face so that the normals point always in a 90 degree angle away from the triangle/face and therefore provide a flat shading throughout every triangle/face which is more correct for a cube as its surfaces are really flat.
Usually one does not want to shade a steep angle like 90 (270) degree in a smooth continuous way. The normal interpolation is only used to mimic 'organic'/'smooth' surfaces. Since these organic / smooth surfaces are the norm (think about the tea pot or a 3d-figure) the decision was made to store the vertex normals with the position and UV coordinates as it is the norm in most of the 'continuous' 3d surfaces. Normally you add more triangles to represent a smooth topology in a model. Having vertex normals is, therefore, a trade-off to minimize the amount of information for the average model.
A cube model with its all flat triangles is, therefore, the worst case. This is why each of the cube's corner needs three vertex normals, one for each face it is a vertex of.
PS: Today those 'smooth' surfaces are further defined by using normal maps baked from a higher resolution model. Using normal maps, each point in the face gets its own normal vector (or the normal vector of each point can be interpolated from the normal vector samples provided by the mapped normal map).
I'm drawing a simple cube using 8 vertices and 36 indices. No problem as long as I don't try to texture it.
However I want to texture it. Can I do that with only 8 vertices? It seems like I get some strange texture behaviour. Do I need to set up the cube with 24 vertices and 36 indices to be able to texture the cube correctly?
It just doesn't make sence to use vertices AND indices to draw then. I could just as well use vertices only.
One index refers to one set of attributes (vertex, normal, color, edge flag, etc). If you are willing to have the texture mirrored on adjacent faces of the sides of your cube, you could share both texture and vertex coordinates for the sides. However, the top and bottom faces sharing those same coordinates would not work -- one axis of the texture coordinate would not vary. Once you add other attributes (normal in particular) then a cube would need 24 individual indexes (each with vertex, texture and normal) to have "flat" sides.
Another approach that may work for you is texture coordinate generation. However, needing 24 individual vertices for a cube is perfectly normal.