What is back face culling? - opengl

What exactly is back face culling in OpenGL? Can you give me a specific example with e.g. one triangle?

If you look carefully you can see examples of this in a lot of video games. Any time the camera accidentally moves through an object - typically a moving object like a character - notice how the world continues to render correctly. That's because the back sides of the triangles that form the skin of the character are not rendered; they are effectively transparent. If this were not the case then every time the camera accidentally moved inside an object either the screen would go black (because the interior of the object is not lit) or you'd get a bizarre perspective on what the skin of the object looks like from the inside.

Back face culling is where the triangles pointing away from the camera/viewpoint are not considered for drawing.
Wikipedia defines this as:
It is a step in the graphical pipeline that tests whether the points in the polygon appear in clockwise or counter-clockwise order when projected onto the screen. If the user has specified that front-facing polygons have a clockwise winding, if the polygon projected on the screen has a counter-clockwise winding it has been rotated to face away from the camera and will not be drawn.
Other systems use the face normal and do the dot product with the view direction.
It is a relatively quick way of deciding whether to draw a triangle or not. Consider a cube. At any one time 3 of the sides of the cube are going to be facing away from the user and hence not visible. Even if these were drawn they would be obscured by the three "forward" facing sides. By performing back face culling you are reducing the number of triangles drawn from 12 to 6 (2 per side).
Back face culling works best with closed "solid" objects such as cubes, spheres, walls.
Some systems don't have this as they consider faces to be double sided and hence visible from either direction.

It's only and optimization technique.
When you look at a closed object, say a cube, you only see about half the faces : the faces that are towards you (or, at least, the faces that are not towards you are always occluded by another face that points towards you)
If you skip drawing all these backwards-facing faces, it will have two consequences :
- the rendering time will be twice better (on average)
- the final render won't change (since another, front-facing face will be drawn on top of a "culled" one)
So you basically get x2 perf for free.
In order to know whether the triangle is front- or back-facing, you take v0-v1 and v0-v2, make a cross product. This gives you the face normal. If this vector is towards you ( dot(normal, viewVector) < 0), draw.

Triangles have their coordinates specificed in a specific order, clockwise IIRC.
When the graphics engine look at a triangle from a specific direction, and the coordinates are counter-clockwise, it knows that it's looking at the backside of the triangle through an object. As the front side of the object is covering the triangle, it doesn't have to be drawn.

Related

Calculating normals for lighting in opengl

I have two quads for which I need to find the normal.The co-ordinates are as follows
for quad 1:
(-2,1.25,-1)
(-2,2.2,0)
(1,2.2,0)
(2,1.25,-1)
I have got the normal as (0,.73,-.69)
for quad 2:
(-2,2.2,0)
(2,2.2,0)
(2,1.25,1)
(-2,1.25,1)
normal:(0,.73,.69)
I have already calculated the normals.Can someone please confirm whether these normals are correct?
Also I read about normal pointing inwards and outwards..would someone explain that concept to me?
Your normals basically look correct. For the first quad, I get:
(0.0, 0.725, -0.689)
For the second one:
(0.0, -0.725, -0.689)
As you can see, I got the opposite sign for the second normal. Which leads directly to the second part of your question.
The term "outwards" does not really make sense for a isolated quad. It is mostly applied to closed shapes, where it should make intuitive sense. Picture a sphere, with a normal vector drawn starting at a point on the sphere. The normal pointing "outwards" means that it points away from the center of the cube, which means that it points to the outside. "inwards" is then of course the opposite, where the normal points towards the center of the sphere, or to the inside of the shape.
There's another way of looking at it, since normals are mostly used for lighting calculations. The normals need to point to the side of the surface that you want to see lighted. Most often, you look at shapes from the outside, so you want the outside lighted. Which means that you mostly want the normals pointing outwards. If you have open surfaces that need to be lighted when viewed from either side, there are slightly more complex lighting calculations that can handle that, which are typically found under "two-sided lighting".
There's a related concept that is also important here, which is the "winding order". It defines if the vertices are arranged clockwise or counter-clockwise when viewing them from a certain direction. OpenGL uses the winding order to decide if a triangle faces the viewer. Again, you care about having the desired winding order when looking at the surface from the outside, or more generally from the side you want to see when you display the surface. OpenGL uses counter-clockwise winding by default, so you want counter-clockwise winding when looking at a surface from the side you want to be visible, which for closed shapes is mostly from the outside. You can often get away with the winding order being "wrong" if you don't eliminate backwards facing triangles, which is done with glEnable(GL_CULL_FACE). But in any case, you can save yourself from running into problems later if you always use a consisting winding order for your primitives.
This leads us back to the normal calculation. Since only the sign ended up different, none of our calculations are technically wrong. I assumed that the quads used counter-clockwise winding, which means that I see the "outside" of the quad from the direction where the vertices appear in counter-clockwise order. Since I also want the normals pointing towards the outside, I calculated the normals that way. In other words, with the normal I calculated, if you move away from the quad in direction of the normal, and then look back at the quad, the vertices would be in counter-clockwise order.

what is a clockwise face in openGL

In back face culling you may either use the face normals to see if the face is pointing away from the camera of you may do some technique with if the triangle is drawn clock wise or counter clock wise.
I am confused about this technique with the clockwise. It seems like with this method, the ordering of the vertex data that gets sent to the graphics card decides whether it is facing towards or away from the camera. I don't see how this makes sense because the camera can be looking in any direction, it's as if the vertex data would have to change based on the camera position and that is obviously not done on the CPU.
How can I understand this?
This is one triangle viewed from opposite sides:
3 points in 3D space are defining a triangle. In addition, if those points are ordered (like here) they are also determining two sides (faces) of a triangle : clockwise and counter-clockwise (they are determined by the order clock put inside a face would point its vertices)
In above example triangle is textured counter-clockwise
Now imagine this triangle is an element of a dice:
If you roll the dice (or rotate camera around it) our triangle from CCW becomes CW and we don't want it to be textured any more.
This dice would be in fact built out of 12 such triangles and if we order them properly we will be texturing only 6 that are facing camera at a time.
I'll show you this on an example quad:
(0,0)-------(1,0)
| |
| X |
| |
(0,1)-------(1,1)
Let's assume we are starting at (0,0). Now, if you wind-up (pass) the vertices in "clockwise" order, the next ones would be (1,0), (1,1) and (0,1). (1,0) lays more or less on 2 o'clock, (1,1) is 4, and so on.
Thus the data in GPU memory: 0,0, 1,0, 1,1, 0,1.
When you correlate the windup direction with your setting, you can easily distinguish what's "front" and "back" - to imagine that better, you could draw it on something transparent, then look from the other side - the wind-up direction would be reversed.
So the specification of wind-up direction is merely to tell the GPU which side is front, and which one is back, as it cannot do it by itself - both sides of a triangle are equally good, and the normal vector of given polygon can either be N or -N. However, GPU can verify which of them is aligned with proper wind-up order.
Chapter 2 of The (Old) Red Book has some nice explanation regarding OpenGL specific stuff, that's still pretty relevant today.
That's exactly the point: the vertices order doesn't have to do with camera orientation initially, when you create/draw the face! Note that a camera is merely a transform, not something by itself recognized by openGL.
So, when rendering, after you'll have 'watched' through the camera, openGL simply checks (if culling is enabled) the new order of the face vertices, now according to the new orientation (after all transformations have been applied), to display the face or not.

How to draw smooth lines without using GLSL, FSAA nor GL_LINE_SMOOTH?

So i need a method to do smooth lines without using:
Full Screen Antialiasing (slow)
Shaders (not supported on all cards)
GL_LINE_SMOOTH (causes a crash on some cards)
Only way i could think of doing this was using a textured rectangle that is always faced at camera direction, but the problems are:
1. how do i always face the rectangle at the camera (efficiently) ?
2. how do i keep its size always the same no matter how far away my camera is looking at it?
Any other ideas?
Billboarding is a simple concept, but can be difficult to implement. A billboard is a flat object, usually a quad (square), which faces the camera. This direction usually changes constantly during runtime as the object and camera move, and the object needs to be rotated each frame to point in that direction. There are two types of billboarding: point and axis. Point sprites, or point billboards, are a quad that is centered at a point and the billboard rotates about that central point to face the user. Axis billboards come in two types: axis aligned and arbitrary. The axis-aligned (AA) billboards always have one local axis that is aligned with a global axis, and they are rotated about that axis to face the user. The arbitrary axis billboards are rotated about any axis to face the user.
http://nehe.gamedev.net/data/articles/article.asp?article=19
You can use point sprites, they are always the same size and always face the camera.
http://www.opengl.org/registry/specs/ARB/point_sprite.txt

Cylinder Normals

I'm developing an OpenGL application which right now only draws a big tube consisting of several small cylinders (kind of like a slinky). I'm getting an annoying effect when I turn the lighting and normals on, as from certain angles I get these annoying black dots on the cylinders' borders:
I belive this is a byproduct of the fact the cylinders are very thin. Basically I set the normal to (0,0,+/- 1) when setting the top/base, and then side normals are (cos(toRadian(beta)), sin(toRadian(beta)), 0).
Is it possible to remove this effect whitout getting 'fatter' cylinders? Or is there something wrong in the way I define the normals?
Thanks
This appears to be the rendering of the sides of the cylinders. The yellow in the image corresponds to the tops of the cylinders. The sides of the cylinders are at 90 degrees to the tops, so they are not lit (I'm guessing the light is in the same direction as the camera) and appear black. With the cylinders being so thin these will not fill make pixels so they don't show up much.
How to fix it? I've got a couple of ideas:
1) Just draw the tops and bottoms, not the sides - this will definitely fix the problem when viewed from this angle, but will lead to further problems if your camera moves.
2) Disable lighting, then all faces will be drawn the same colour (assuming the sides are the same colour as the top).
3) Use multi-sampling - this means most of the edges won't appear (as each pixel is more likely to be top than side due to the angle).
4) Add more lights around the scene, perpendicular to the current light.
1 & 2 are your best bet depending on what you're trying to achieve.

Opengl Depth buffer and Culling

Whats's the difference between use back face culling and a buffer of depth in OpenGL?
Backface culling is when OpenGL determines which faces are facing away from the viewer and are therefore unseen. Think of a cube. No matter how your rotate the cube, 3 faces will always be invisible. Figure out which faces these are, remove them from the list of polygons to be drawn and you just halved your drawing list.
Depth buffering is fairly simple. For every pixel of every polygon drawn, compare it's z value to the z buffer. if it's less than the value in the z buffer set the z buffer value as the new z buffer value. If not, discard the pixel. Depth buffering gives very good results but can be fairly slow as each and every pixel requires a value lookup.
In reality there is nothing similar between these two methods and they are often both used. Given a cube you can first cut out half the polygons using culling then draw them using z buffering.
Culling can cut down on the polygons rendered, but it's not a sorting algorithm. That's what Z buffering is.
A given triangle has two sides, the front face and the back face. The side you are looking at is determined by the order the points appear in the vertex list (also called the winding). Typically lists of triangles have alternating winding so that you can reuse the preceding two points but the facing of a given triangle in the strip doesn't alternate. Back face culling is the optimization step where in triangles in the scene which are oriented away from the view are removed from the list of triangles to draw.
A depth buffer (z-buffer) is used to hang onto the closest thing (the depth is relative to the view) that has already been rendered. If the thing that comes up next in the draw list is behind something that I've drawn already (ie, it has a depth that places it farther away) I can skip drawing it, as it is obstructed. If the new thing to draw is closer, I draw it and I update the depth buffer with the new, closer value.