Smooth cone normals - opengl

I'm trying to calculate smooth normals for a cone. In looking around for code samples and explanations, I consistently come across directions for face normals. I've posted a couple pictures below of what I'm doing. The first -- which basically just normalizes the vertex position -- gives me decently smooth shading, but the edges are "missing" and the bottom face isn't solid. The second has edges, but the shading is flat (face normals) and my light isn't reflecting off of them correctly.
The cone is built out of GL_TRIANGLES.
Click the images for larger versions.
(source: bantherewind.com)
(source: bantherewind.com)

At any point on the surface of a cone except the apex, there are two obvious kinds of tangent vectors: one tangent to the cross-sectional circle, or one up the slope. If you express the surface as a parametric equation with two parameters, you can get these tangent vectors as the two partial derivatives. Take the cross product of the tangents, and you get a normal vector. The order of the product determines whether the normal points inward or outward. Of course, the bottom face must be handled separately.

In addition to the answer by JWWalker I'd like to point out, that a vertex is a whole tuple of vector, that among other things includes position and normal. So if you have different normals at a single position, you got there different and multiple vertices.
In the case of the cone this is important, because the tip of the cone is not one single vertex, but a whole set of them (one tip vertex for each triangle the cone's coat. And then for the base circle you got at each position two vertices, the one for the triangle to the tip, and one for the base surface.
Both the tip and the edge are discontinuities and hence call for a be drawn using separate vertices.

Related

Mesh and cone intersection algorithm

I am looking for an efficient algorithm for mesh (set of triangles) and cone (given by origin, direction and angle from that direction) intersection. More precisely I want to find intersection point which is closest to the cone's origin. For now all what I can think about is to intersect a mesh with several rays from the cone origin and get the closest point. (Of course some spatial structure will be constructed for mesh to reject unnecessary intersections)
Also I found the following algo with brief description:
"Cone to mesh intersection is computed on the GPU by drawing the cone geometry with the mesh and reading the minimum depth value marking the intersection point".
Unfortunately it's implementation isn't obvious for me.
So can anyone suggest something more efficient than I have or explain in more details how it can be done on GPU using OpenGL?
on GPU I would do it like this:
set view
to cones origin
directing outwards
covering the bigest circle slice
for infinite cone use max Z value of mesh vertexes in view coordinate system
clear buffers
draw mesh
but in fragment shader draw only pixels intersecting cone
|fragment.xyz-screen_middle|=tan(cone_ang/2)*fragment.z
read z-buffer
read fragments and from valid (filled) select the closest one to cones origin
[notes]
if your gfx engine can handle also output values from your fragment shader
then you can skip bullet 4 and do the min distance search inside bullet 3 instead of rendering ...
that will speed up the process considerably (need just single xyz vector)

Computing normals for squares

I've got a model that I've loaded from a JSON file (stored as each tile /w lots of bools for height, slope, smooth, etc.). I've then computed face normals for all of it's faces and copied them to each of their verticies. What I now want to do (have been trying for days) is to smooth the vertex normals, in the simplest way possible. What I'm trying to do is set each vertex normal to a normalized sum of it's surrounding face normals. Now, my problem is this:
The two circled vertices should end up with perfectly mirrored normals. However, the one on the left has 2 light faces and 4 dark faces. The one on the right has 1 light face and 6 dark faces. As such, they both end up with completely different normals.
What I can't work out is how to do this properly. What faces should I be summing up? Or perhaps there is a completely different method I should be using? All of my attempts so far have come up with junk and / or consisted of hundreds of (almost certainly pointless) special cases.
Thanks for any advice, James
Edit: Actually, I just had a thought about what to try next. Would only adding a percentage of each triangle based on it's angle work (if that makes sense). I mean, for the left, clockwise: x1/8, x1/8, x1/4, x1/8, x1/8, x1/4 ???
And then not normalize it?
That solution worked wonderfully. Final result:
Based on the image it looks like you might want to take the average of all unique normals of all adjacent faces. This avoids double counting faces with the same normal.

calculating normals for quad mesh

I have a struct QUAD that stores 4 pointers to 4 VECTOR3D (which contains 3 floats) so that I can draw the quad mesh.
From what I understand is whenever I draw a mesh, I need normal as well to properly light/shade a mesh and it's relatively easy when it's a mesh laying on a plain, using normal per face.
When I have 2 by 2 quad meshes laying on XZ coordinate and tried to raise it's centre (0,0,0) by a certain point, say (0, 4, 0) it would start to form real 3D shapes, then I need to calculate normals again. I'm having hard time understanding how and what is to be to calculated normals. As expected, the 3D shape shades like it's still a flat mesh, so it does not represent real shape. One of the explanation says I need to calculate normals per vertex instead of per face.
Does it mean I need to calculate normals for all corners of mesh? once i have normals what would i do? I was still using old glBegin glEnd methods but now I feel like i need to use DrawArray method. I'm deeply confused and I'm pretty sure I don't make much sound but i'd much appreciate your help.
If you need flat looking surface then your normals will be normals to the quad plane. If you need "soft looking" surface you need to blend(read this and watch this cool simple video) normals - that will add sort of gradient.

Understanding glNormal3f

I can't understand the glNormal3f, I know that it works for 'normalize' the 'normals' of the vertex... Or something like that, but I can't understand what is the 'normal' of the vertex.
Can you explain me that function? I can't understand what 'normal' means in openGL...
The "normal" of a vertex is the vector which is "perpendicular" to the vertex. In mathematics "normal" is a generalization of "perpendicular". For a polygon, this "normal vector" is perpendicular to the polygon and is the same for all of its vertices. One reason you might assign different normal vectors to each vertex of a polygon is if you are covering a curved surface with very small triangles. In this case, you don't want the normal vectors of the three vertices of the triangle to all be the same.
Now what is this normal vector used for? The typical application is used for coloring calculations when lighting is enabled in OpenGL. The normal vector can determine whether the light from a light source hits a surface and what angle a light ray makes with the surface. This can then be used to determine whether the surface is shadowed or contains a specular highlight, for instance.
A call to glNormal will emit the normal vector to the last emitted vertex. A vertex normal is usually calculated as the normalized average of normals of the faces incident to the vertex. The normals of faces are vector so that they are perpendicular to the plane described by the face.
This function is deprecated and you really should pick up a good/tutorial or book.
See also Vertex Normal and the associated entries.
If you should not use glVertex* and the associated glNormal* functions, what should you use? Shaders and VBO's. Have a look at this question.

How to create an even sphere with triangles in OpenGL?

Is there a formula that generates a set of coordinates of triangles whose vertices are located on a sphere?
I am probably looking for something that does something similar to gluSphere. Yet, I need to color the different triangles in specfic colors so that it seems I can't use gluSphere.
Also: I do understand that gluSphere draws edges along lines with equal longitudes and lattitudes which entails the triangles being small at the poles compared to their size at the equator. Now, if such a formula would generate the triangles such that their difference in size is minimized, that would be great.
To calculate the normals and the uv map.
Fortunately there is an amazing trick for calculating the normals, on a sphere. If you think about it, the normals on a sphere are indeed nothing more than the direction from the centre of the sphere, to that point!! Furthermore, if you think it through, that means the normals literally equal the point! i.e., it's the same vector! - just don't forget to normalise the length, for the normal.
You can win bar bets on that one: "is there a shape where all the normals happen to be exactly ... equal to the vertices?" At first glance you'd think, that's impossible, no such coincidental shape could exist. But of course the answer is simply "a sphere with radius one!" Heh!
Regarding the UVs. It is relatively easy on a sphere, assuming you're projecting to 2D in the "obvious" manner, a "rectangle-style" map projection. In that case the u and v is basically just the longitude / latitude of any point, normalised to 0,1.
Hope it helps!
Here's the all-time-classic web page that beautifully explains how to build an icosphere .. http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html
Start with a unit icosahedron. Then apply muliple homogenous subdivisions of the triangles, normalizing the resulting vertices distance to the origin.