You are on page 1of 13

Visible Surface Detection

Soon Tee Teoh CS 116B

Motivation
We want to only draw the visible surfaces. Motivation 1: Correctness. If Surface A is in front of Surface B, then Surface B should not be seen. If it is rendered, then it produces a wrong picture. Motivation 2: Speed. Trying to render an invisible surface and later eliminating it is a waste of time.

Back-Face Culling
If we want to render front faces only, we can eliminate all the back-facing polygons. How to detect back-facing triangles?
To determine if a triangle is back-facing, take the dot product between its normal N, and the view vector V.
V = P E, where P is the position of a vertex on the triangle, and E is the position of the eye/camera.

If V.N > 0, then it is a back-facing triangle, and should not be rendered. Otherwise, it is a front-facing triangle and should be rendered.

Eye position E

Triangle

P
Triangle normal N

OpenGL Back-Face Culling


Enable back-face removal with glEnable(GL_CULL_FACE); Disable back-face removal with glDisable(GL_CULL_FACE); Then, select which polygons to remove with one of the following functions:
glCullFace(GL_BACK); glCullFace(GL_FRONT); glCullFace(GL_FRONT_AND_BACK);

The default is GL_BACK, so that the back-facing polygons are removed. However, remember that in a polyhedron, the convention is to specify the triangles such that the outward face is the front face. Therefore, if the camera happens to be inside the polyhedron, we would use glCullFace(GL_FRONT) to get rid of the front-facing polygons, so that we see the back-facing ones only.

Depth Buffer Method


The Depth Buffer Method (also called the z-buffer method) is used to handle occlusion, so that only the surface that is closest to the camera position is shown. Using this approach, two frame buffers need to exist. One is the color buffer, which keeps the color for each pixel. The other is the depth buffer, which keeps the depth of each pixel.

Depth Buffer Method (continued)


When scan-converting a triangle, use surface rendering method to calculate the color at each pixel. Also, calculate the normalized depth of the pixel. The normalized depth of each vertex of each triangle is automatically generated by the viewport normalization matrix. Use the incremental method (explained in the following slide) to calculate each pixel depth from the vertex depths. Next, compare the new pixel depth with the depth stored for this pixel in the depth buffer. If the new pixel depth is smaller than the stored depth, it means that the new pixel is nearer to the viewer. Therefore, the new color replaces the stored color for this pixel in the color buffer, and the new depth replaces the old depth for this pixel in the depth buffer. Otherwise (if the new pixel depth is greater than the stored depth), the new pixel is ignored. Color and depth buffers for this pixel are not changed.

Depth Buffer Method (continued)


The incremental method for calculated depth of a pixel
Given: The depths of each vertex of a triangle. Objective: Get the depth of each pixel rendered for the triangle. Suppose that were using the scan-line approach. Suppose that we have calculated the depth z of the first pixel (x,y) Suppose the plane equation of the triangle is Ax + By + Cz + D = 0 Then, z = ( Ax By D)/C Now, we want to find the depth z of the next pixel (x+1,y) on the scan-line. Now, z = ( A(x+1) By D)/C Simplifying, z = z A/C. Now, A/C is a constant for each surface, so we just need one simple subtraction to get the depth of each successive pixel along the scanline.

Disadvantages of the Depth Buffer Method


Need a lot of memory for the depth buffer.
Suppose we need 16 bits depth for each pixel, and there are 1024 x 1024 pixels, then we would need 2 MB of space for the depth buffer.

Can possibly waste a lot of time calculating the color of each pixel of a triangle, and then later get completely obscured by another triangle. Precision is less for the depths of triangles further away from the camera position. (The depth calculated by the viewport transformation is only the pseudo-depth.)

Using Depth Buffer in OpenGL


// tell glut to give you a depth buffer glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
// need to reset the depth buffer before drawing each frame glClear(GL_DEPTH_BUFFER_BIT); // need to enable depth testing glEnable(GL_DEPTH_TEST); // set the depth function. GL_LESS means that the incoming pixel // passes the depth test if its z-value is less than the currently stored // value. GL_LESS is the default anyway (so, the following line need // not be called). glDepthFunc(GL_LESS);

BSP Tree Method


A BSP (Binary Space-Partitioning) tree is formed by first choosing a triangle from the set of all triangles in the scene. The plane that contains this triangle is called P. Classify all other triangles into two groups: One group in front of P, and the other group behind P. All triangles that are intersected by P are split into multiple smaller triangles, each of which is either in front of P or behind P. Within each group, recursively pick another triangle and partition all the triangles in this group into two subgroups. Do this until there is only one triangle in each group. The result is a tree.

BSP Tree Example

Using BSP Tree for Hidden Surface Removal


Goal: Render the triangles from back to front Algorithm:
Go down a BSP tree. At each node, check whether the view point is in front of the node plane or behind.* Descend the far side subtree first and output triangles. Then, render the triangle at the node. Then, descend the near side subtree and output triangles.

Advantage compared to depth buffer:


No need to keep depth buffer (save memory), always overwrite color buffer Triangles are rendered back to front, so can do transparency

Disadvantage remains:
May possibly waste a lot of time rendering triangles which will eventually be occluded.

*How to check if a point is in front of the plane: Substitute the coordinates of the point into the plane expression Ax+By+Cz+D. If the result is greater than zero, the point is in front of the plane.

F B E H C A J I

D
Is this a valid BSP tree? G C D B J I A H F D A Is this a valid BSP tree? G C B J E I B D G H F A Is this a valid BSP tree? J C E I H F

You might also like