400 likes | 407 Views
Learn about different ways of creating views and why we need them. Explore orthographic, axonometric, oblique, and perspective views. Understand the positioning of the camera frame and the concept of hidden surface removal.
E N D
Computer Graphics - Chapter 5 Viewing • Objectives are to learn about: • Different ways of creating different types of views. • Why do we need different types of views? • The viewing process has two parts: • 1) In the first part, we use the model-view matrix to switch from the world frame in which we define our objects to their representation in a frame in which the camera is at the origin. • 2) This part deals with the type of projection; we prefer (parallel or perspective) and the part of world that we wish to image (the clipping or view volume).
Viewing We have: Objects a viewer projectors, and projection plane. Center Of Projection (center of camera lens, origin of the camera frame)
Movement of the center of projection (COP) to infinity As we move the COP to infinity, the projectors become parallel and the COP can be replaced by a direction of projection (DOP). As the COP moves to infinity, the size of the image remains about the same. Views with a finite COP are called perspective views. Views with a COP at infinity are called parallel views.
Orthographic Projections Projectors are perpendicular to the projection plane. In a multiview orthogonal projection, the projection plane is parallel to one of the principal faces of the object. Temple and three multiview orthogonal projections Orthographic Projections Both distances and angles are preserved by the view.
Axonometric Views Projectors are still orthogonal to projection plane, but the projection plane can have any orientation with respect to the object. If the projection plane is placed symmetrically with respect to the three principal faces that meet at a corner of our rectangular object, we have a isometric view. Dimetric view? Trimetric view? Construction of trimetric view Top view Side view
Oblique Projections The most general parallel views. We allow the projectors to make an arbitrary angle with the projection plane. Angles in planes parallel to the projection plane are preserved. Construction of oblique view Top view Side view
Perspective Viewing All perspective views are characterized by diminution of size. When objects are moved farther from the viewer, their images become smaller. The classical perspective views are: one-, two, and three point perspectives. What is the difference? Three-point perspectives Two-point perspectives One-point perspectives
Positioning of the Camera Frame The original matrix (-1,1,1) is correctly transformed to by the above matrix. If we add a translation (0, 0, -d), the matrix becomes TR. glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -d); glRotatef(35.26, 1.0, 0.0, 0.0); glRotatef(45.0, 0.0, 1.0, 0.0); Cube after rotation about x axis, (a) View from positive z axis, (b) View of y, z plane
The Look-At Function A camera is located at a point e called the eyepoint, specified in the world frame, and it is pointed at a second point a, called the at point. These points determine a view-point normal (VPN) and a view-reference point (VRP). The VPN is given by the vector formed by point subtraction between the eyepoint and the at point. Vpn = e – a. gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx, upy, upz); Look at positioning VUP – fixes the camera
Perspective in OpenGL In OpenGL we have two functions for specifying perspective views and one for specifying parallel views. The camera view can be defined as: glFrustum(xmin, xmax, ymin, ymax, near, far); Example: glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(xmin,xmax, ymin, ymax, near, far);
Perspective in OpenGL using angle or field of view gluPerspective(fov, aspect, near, far); Where angle fov is the angle between the top and bottom planes of the clipping volume.
Parallel Viewing in OpenGL The only parallel-viewing function provided by OpenGL is the orthogonal (orthographic) viewing function: glOrtho(xmin, xmax, ymin, ymax, near, far); Orthographic viewing
Hidden-Surface Removal We wish to remove the surfaces that should not be visible and display the parts that are supposed to be visible. There are two ways to remove hidden surfaces: 1) order surfaces in a correct order so that it produces the correct images. 2) use the projection process and find the relationship between objects points on each projector. The z-buffer algorithm is of this type. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glEnable(GL_DEPTH_TEST); One can clear buffer as necessary for a new rendering by using: glClear(GL_DEPTH_BUFFER_BIT);
Walking Through a Scene – Cube example In the rotating cube example, the cube rotated about the origin. We used an orthographic projection and did not point the camera in a particular direction (default). Now, we wish to learn to generate perspective viewing and allow users to move the camera by depressing the x, X, y, Y, z, and Z keys on the keyboard. We want the camera to point to the center of the cube. The gluLookAtfunction provides a simple way to reposition and reorient the camera. We will create an array view[3]to hold the camera position. Its contents are altered by the keyboard callback function keys. void keys(unsigned char key, int x, int y) {/* Use x, X, y, Y, z, and Z keys to move viewer */ if(key == 'x') viewer[0]-= 1.0; if(key == 'X') viewer[0]+= 1.0; if(key == 'y') viewer[1]-= 1.0; if(key == 'Y') viewer[1]+= 1.0; if(key == 'z') viewer[2]-= 1.0; if(key == 'Z') viewer[2]+= 1.0; display(); }
Walking Through a Scene – Cube example The Display function calls LookAt using viewerfor the camera position, and uses the origin for the “at” position. The cube is rotated as before. Note: the order of function calls is very important. void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Update viewer position in modelview matrix */ glLoadIdentity(); gluLookAt(viewer[0],viewer[1],viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); /* rotate cube */ glRotatef(theta[0], 1.0, 0.0, 0.0); glRotatef(theta[1], 0.0, 1.0, 0.0); glRotatef(theta[2], 0.0, 0.0, 1.0); colorcube(); glFlush(); glutSwapBuffers(); }
Walking Through a Scene – Cube example The glFrustum in the reshape callback specifies the camera lens: void myReshape(int w, int h) { glViewport(0, 0, w, h); /* Use a perspective view */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) glFrustum(-2.0, 2.0, -2.0 * (GLfloat) h/ (GLfloat) w, 2.0* (GLfloat) h / (GLfloat) w, 2.0, 20.0); else glFrustum(-2.0, 2.0, -2.0 * (GLfloat) w/ (GLfloat) h, 2.0* (GLfloat) w / (GLfloat) h, 2.0, 20.0); /* Or we can use gluPerspective */ /* gluPerspective(45.0, w/h, -10.0, 10.0); */ glMatrixMode(GL_MODELVIEW); } Note that the mouse buttons could be used to move forward and backward instead of rotating around different axis. What if we want the viewer to look toward the direction to which we are moving?
Parallel Projection Matrix We take an approach called projection normalization, which converts all projections into orthogonal projections: by first distorting the objects such that the orthogonal projection of the distorted objects is the same as the desired projection of the original objects. We learned that projection converts points in 3-D space to points on the projection plane, and that the transformation that does this operation is singular. All points along a projector project into the same point on the projection plane. Our approach is to break the Projection into two parts: Perspective view Orthographic projection Of distorted object Normalization Transformation
Orthogonal-Projection Matrices Our approach is to break the projection into two parts: Part 1: Converts the specified viewing volume to standard volume by nonsingular homogeneous coordinate transformation. This part is done by concatenating the transformation matrix with the model-view matrix. Part 2: Objects are distorted to create the desired projection. This is an orthogonal projection on the transformed objects and volume: xp = x, yp= y, zp = 0. Note that OpenGL distinguishes between the screen coordinates (2-D without depth) and windows coordinates (3-D). In OpenGL, the projection matrix and the subsequent perspective division convert vertices to window coordinates. For orthographic projection, the simplest model is cube with its center at the origin and sides given as: glMatrixMode(GL_PROJECTION); glLoadIdentity( ); The canonical view volume glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); near far Front Back
Orthogonal-Projection Matrices Suppose we define: glOrtho(xmin, xmax, ymin, ymax, near, far); What does this mean? The projection matrix that OpenGL sets up is the matrix that transforms this volume to the cube centered at the origin with sides of length 2. This matrix converts the vertices that specify the objects to vertices within this canonical view volume, by scaling and translating them. The projection matrix is determined by the type of view and the view volume specified in glOrtho, and that all these specifications are relative to the camera. The positioning and orientation of the camera is determined by the model-view matrix. These two are concatenated to make the transformed matrix. (right, top, -far) (1,1,-1) (-1,-1,1) (left, bottom, -near)
Orthogonal-Projection Matrices To find the transformation matrix, we need to do two things: 1) We need to move the center of the specified view volume to the center of the canonical view volume (the origin) by a translation. 2) we must scale the sides of the specified view volume so that each have length of 2. zmax=far zmin=near xmin=left xmax=right ymin=top ymax=bottom glOrtho(left, right, bottom, top, near, far);
(right, top,-near) Example: Suppose the orthographic view volume is defined as: glOrtho(-2, 4, -2, 4 , -2, 0); glOrtho(left, right, bottom, top, near, far); Compute the transformation to its canonical view volume. Then compute the Location of a point p(-2, 2, -1). (1,1,-1) (-1,-1,1) (left, bottom,-far)
glOrtho(left, right, bottom, top, near, far); (right, top, -near) Example: Suppose the orthographic view volume is defined as: glOrtho(left, right, bottom, top, near, far); glOrtho(-2, 4, -2, 4 , -2, 0); Compute the transformation to its canonical view volume. (1,1,-1) (-1,-1,1) (left, bottom, -far)
Oblique Projections OpenGL, through glOrtho provides a limited class of parallel projections for which the projectors are orthogonal to the projection plane. An oblique projection can be characterized by the angle that the projectors make with the projection plane. The view volume for an oblique projection has the near and far clipping planes parallel to the view plane, and the right, left, top, and bottom planes parallel to the direction of projection.
Oblique Projections Using the equation for the projection plane: zp = 0, we can write Pas shown below: Then we can break P into the products of two matrices: Shearing Orthogonal Projection
Oblique Projections Now we need to take care of a very important part. The view volume created by the shear is not our canonical view volume. We need to apply the same scaling and translation that we used before to fix the problem: This must be inserted after the shear and before the final orthographic projection, so we get: P = Morth ST H.
Orthogonal Projection Canonical view converter Shearing
Example (Oblique Projection): Suppose the orthographic view volume is defined as: glOrtho(-2, 4, -2, 4 , -2, 0); Compute the transformation to its canonical view volume in an oblique projection with x-z and y-z angles: respectively.
Perspective-Projection Matrices We will use a very similar method as we used in parallel projection: 1) We find the transformation that, by distorting the vertices of our objects, allows us to do a simple canonical projection to obtain the desired image. 2) Then we introduce a new transformation, the perspective- normalization transformation, that converts a perspective projection to an orthogonal projection. 3) Then we drive the perspective-projection matrix used in OpenGL. Perspective Normalization (1,1,-1) (-1, -1, -1)
OpenGL Perspective Transformations The OpenGL function glFrustum does not restrict the view volume to a symmetric (or right) frustum. (right, top, -near) (left, bottom, -far) • The process is similar to the conversion of an oblique parallel view to an orthogonal view. • First to convert the asymmetric frustum to a symmetric one • Second to scale the sides of the frustum to • The shear angle is determined by our desire to shear the point:
OpenGL Perspective Transformations The shear matrix is defined as: The resulting frustum is described by the planes: The next step is to scale the sides of this frustum to:
OpenGL Perspective Transformations The scaling matrix is: S(-2*near/(right – left) , -2*near/(top – bottom), 1) To get the far plane to the plane z = -1 and the near plane to z = 1after applying a projection normalization, we use the projection-normalization matrix N: The resulting projection matrix is:
Example (Perspective Projection): Suppose the orthographic view volume is defined as: glFrustum(-2, 4, -2, 4 , -2, 0); Compute the transformation to its canonical view volume in an perspective projection.
Projection and Shadow The creation of simple shadows is an interesting application of projection matrices. Note that a point is in the shadow if it is not illuminated by any light source, i.e., if a viewer at that point cannot see any light sources. If the only light source is at the center of projection, there is no visible shadow, because shadows are behind visible objects. This is lighting strategy is called the “flashlight in the eye” model. Shadow from a light source moved to the origin Shadow from a single polygon Shadow from a light source Shadow at y = 0
Projection and Shadow The transformation matrix that takes the light source from (xl, yl, zl) is: T(-xl, -yl, -zl) Then we have a simple perspective projection through the origin: L(xl, yl, zl) P2(x,y,z) P3(x,y,z) P1(x,y,z) PP2(xp ,yp ,zp) PP3(xp ,yp ,zp) Finally, we translate everything back with T(xl, yl, zl). The concatenation of this matrix and the two translation matrices projects the vertex (x, y, z) to: However, in OpenGL we can alter the model-view matrix to form the desired polygon. PP1(xp ,yp ,zp)
Example: Suppose we have a triangle that is defined by the following three vertices: v1(2, 4, 2), v2(-2, 4, 2), and v3(0, -3, 1). Compute the projection of this triangle on the y-z plane (y = 0) for a light source located at (Lx, Ly, Lz) = (0, 10, 4).
Example: The same problem, suppose we have a triangle that is defined by the following three vertices: v1(2, 4, 2), v2(-2, 4, 2), and v3(0, -3, 1). Compute the projection of this triangle on the x-y plane (z = 0) for the same light source located at (Lx, Ly, Lz) = (0, 10, 4).
Few Remarks, then an Example You should be able to convert gluLookAt to equivalent glTranslatef and glRotatef transformations, and vice versa. For example, if we want to view the cube bounded by (0,0,0) and (1,1,1) along it's main diagonal from a distance of 5 units from the origin, we could use: glTranslate(0,0,-5); glRotatef(35.2,1,0,0); //35.2 is acos(sqrt(2)/sqrt(3)) in degrees glRotatef(-45,0,1,0); or equivalently gluLookAt(x,x,x,0,0,0,0,1,0); The value 35.2 is the angle with a cosine of sqrt(2)/sqrt(3), which is the ration of the projection of the main diagonal into the x-z plane to the main diagonal. To determine x, we must have x*x + x*x +x*x = 5*5, or x = 5/sqrt(3).
Few Remarks, then an Example Next we looked at shadows. A shadow is just another projection (parallel for distant light sources such as the sun, otherwise perspective). One strategy is to create an image of an object entirely in black from a certain vantage point. Then clear the depth buffer glClear(GL_DEPTH_BUFFER_BIT); change the vantage point, then draw the object in its proper colors. Clearing the depth buffer essentially makes every point in the image "infinitely" far away. When we draw new points, they will always win the depth contest. This will put the shadow behind the object.
Glfloat m[16]; //Shadow projection Matirx for(I = 0; I < 15; I++) m[I] = 0.0; m[0] = m[5] = m[10] = 1.0; m[7] = -1.0/yl; glColor3fv(polygon_color); glBegin(GL_POLYGON) // draw the polygon normally … glEnd(); glMatixMode(GL_MODEVIEW); glPushMatrix(); //save state glTranslatef(xl, yl, zl); // Translation back glMatrixf(m); //Project glTranslate(-xl, -yl, -zl); //Move light to origin glColor3fv(shadow_color); glBegin(GL_POLYGON); //draw the plogon again .. glEnd(); glPopMatrix(); Note: Projection is done with respect to the light source.