CSC48206820 Computer Graphics Algorithms Ying Zhu Georgia State University PowerPoint PPT Presentation

presentation player overlay
1 / 66
About This Presentation
Transcript and Presenter's Notes

Title: CSC48206820 Computer Graphics Algorithms Ying Zhu Georgia State University


1
CSC4820/6820 Computer Graphics AlgorithmsYing
ZhuGeorgia State University
  • Lecture 08 and 09
  • View Projection

2
Outline
  • Camera and view transformation
  • View volume and projection transformation
  • Orthographic projection
  • Perspective projection
  • Perspective division
  • View port transformation

3
Outline
4
3D Scenes and Camera
  • In computer graphics, we often use terms that are
    analog to theatre or photography
  • A virtual world is a scene
  • Objects in the scene are actors
  • There is a camera to specify viewing position
    and viewing parameters.
  • Viewing and projection is about how to position
    the camera and project the 3D scene to a 2D
    screen.

5
Viewing
  • In modeling tools, you can create multiple
    cameras
  • But in OpenGL, there is only one camera
  • Camera can be animated too
  • The 3D scene is rendered through the viewpoint of
    the camera
  • Its important to make sure your objects are
    visible through the camera
  • Note the difference between a camera in computer
    graphics and a real camera

6
Camera in computer graphics
  • Computer graphics uses the pinhole camera model
  • This results in perfectly sharp images
  • No depth of field or motion blur
  • Real cameras use lenses with variable aperture
    sizes
  • This causes depth-of-field out-of-focus objects
    appear blurry

7
Depth of field
  • Depth of view is an important part of the
    storytelling process
  • Direct viewers eyes to a certain area of the
    scene
  • Depth of view can be faked in CG, but needs extra
    work

8
Motion Blur
  • Camera in computer graphics does not generate
    motion blur either
  • Again, it can be faked in CG but performance may
    suffer

9
Aspects of Viewing
  • There are three aspects of the viewing process
  • Positioning the camera
  • Setting the model-view matrix
  • Selecting a lens
  • Setting the projection matrix
  • Clipping
  • Setting the view volume

10
Positioning the camera
  • Each camera has a location and a direction
  • The purpose of viewing transformation is to
    position the camera.
  • In OpenGL, by default the camera is located at
    origin and points in the negative z direction

11
Positioning the camera
  • What if your camera is not at the origin, facing
    Z axis?
  • You use gluLookAt() function call to specify
    camera location and orientation
  • http//pyopengl.sourceforge.net/documentation/manu
    al/gluLookAt.3G.html
  • Note the need for setting an up direction
  • Example

glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluL
ookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0., 1.0. 0.0)
12
Viewing Transformation in OpenGL
  • gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx,
    upy, upz)
  • atx, aty, atz will be mapped to the center of the
    2D window

13
Moving the Camera
  • No matter where the camera is initially,
    eventually it needs to be transformed to the
    origin, facing Z axis
  • in order to make the subsequent stages in the
    graphics pipeline very efficient
  • But the picture taken by the (virtual) camera
    should be the same before and after the camera
    transformation
  • How to achieve this?
  • Construct a view transformation matrix to
    transform the camera to the origin, facing -Z
  • Apply the view transformation matrix to every
    object in the virtual scene
  • This view transformation is not visible
  • Internally gluLookAt() creates such a matrix

14
What does gluLookAt() do?
  • gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx,
    upy, upz) is equivalent to
  • glMultMatrixf(M) // post-multiply M with current
    model-view matrix
  • glTranslated(-eyex, -eyey, -eyez)
  • Where M
  • u, n, v are unit vectors.

15
What does gluLookAt() do?
  • Internally OpenGL creates a view matrix and
    post-multiplies it with the current model-view
    matrix (normally an identity matrix)
  • void reshape (int w, int h)
  • glViewport (0, 0, (GLsizei) w, (GLsizei) h)
  • glMatrixMode (GL_PROJECTION)
  • glLoadIdentity ()
  • gluPerspective(65.0, (GLfloat) w/(GLfloat) h,
    1.0, 20.0)
  • glMatrixMode(GL_MODELVIEW)
  • glLoadIdentity()
  • gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.,
    1.0. 0.0)
  • Current_MV_matrix ? current_MV_matrix
    view_matrix

16
gluLookAt()
  • gluLookAt() should be called before any OpenGL
    model transformation function calls
  • Thats why gluLookAt() is normally placed in
    reshape() because reshape() is called before
    display()
  • Normally model transformation calls are placed in
    display() function
  • If you place transforms calls in other functions,
    pay attention to the call sequence

17
gluLookAt()
  • Why?
  • Because the view transformation matrix needs to
    be applied to every object (vertices) in the
    virtual scene
  • All the model transformations have to be finished
    before the view transformation.
  • Otherwise the realism is lost
  • That means the view transformation matrix must be
    post-multiplied to the current modelview matrix
    before any model transformations
  • p I x V x T x R x p

18
View transformation
  • Again, there are matrix multiplications behind
    each gluLookAt() call
  • Normally at the start of your display() function,
    your current model-view matrix should be the view
    matrix
  • Be careful when you call glLoadIdentity() in you
    display() function, you may unintentionally wipe
    out the view matrix

19
Example
  • void reshape (int w, int h)
  • glViewport (0, 0, (GLsizei) w, (GLsizei) h)
  • glMatrixMode (GL_PROJECTION)
  • glLoadIdentity ()
  • gluPerspective(65.0, (GLfloat) w/(GLfloat) h,
    1.0, 20.0)
  • glMatrixMode(GL_MODELVIEW)
  • glLoadIdentity()
  • gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0., 1.0.
    0.0)
  • void display(void)
  • glLoadIdentity() // You just wipe out the view
    matrix

20
A safer approach
  • void reshape (int w, int h)
  • glViewport (0, 0, (GLsizei) w, (GLsizei) h)
  • glMatrixMode (GL_PROJECTION)
  • glLoadIdentity ()
  • gluPerspective(65.0, (GLfloat) w/(GLfloat) h,
    1.0, 20.0)
  • glMatrixMode(GL_MODELVIEW)
  • glLoadIdentity()
  • gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0., 1.0.
    0.0) // current model-view matrix is view matrix
  • void display(void)
  • glPushMatrix() // current model-view matrix
    (i.e. view matrix) is pushed into matrix stack
  • glPopMatrix() // current model-view matrix is
    view matrix again

21
The bottom line
  • Understanding the transformations (and matrix
    multiplications) behind the OpenGL calls can save
    you a lot of trouble
  • Dont blindly follow the code pattern in sample
    programs
  • Understand the relationship among
  • Current model-view matrix
  • Camera transformations
  • Model transformations
  • OpenGL matrix stack
  • You should be able to trace the current
    model-view matrix in your code, if needed
  • E.g. Assignment 1, question 2

22
Projection Transformation
  • Viewing transformation transform the camera to
    the origin and look-at direction with negative Z
    axis.
  • Before one can actually render a scene, all
    relevant objects in the scene must be projected
    to some kind of plane or into some kind of simple
    volume
  • After that, clipping and rendering are performed
  • Projection transformation maps all 3D objects
    onto the viewing plane to create a 2D image.

23
Projection Transformation
  • The previous section described how to compose the
    desired modelview matrix so that the correct
    modeling and viewing transformations are applied.
  • Now we explain how to define the desired
    projection matrix, which is also used to
    transform the vertices in your scene

24
Projection transformation
25
View volume (frustum)
  • We need to define a view volume for projection
  • Everything inside the view volume will be
    projected to the 2D plane
  • Everything outside the view volume will be
    clipped and ignored
  • The job of projection transformation is to
    transform the view volume (and everything in it)
    to a canonical view volume
  • Canonical view volume a unit cube centered at
    origin
  • It has minimum corner of (-1, -1, -1) and maximum
    corner of (1, 1, 1)

26
View volume (frustum)
27
Canonical view volume
  • The coordinates in this volume is called
    Normalized Device Coordinates (NDC)
  • The reason for transforming into the canonical
    view volume is that clipping is more efficiently
    performed there
  • especially in hardware implementation
  • The canonical view volume can also be
    conveniently mapped to 2D window by view port
    transformation

28
Projection transformation
  • Two basic projections in OpenGL
  • Orthographic projections
  • Useful in applications where relative length
    judgment are important
  • Can also yield simplifications where perspective
    would be too expensive, e.g. in some medical
    visualization applications
  • Perspective projections
  • Used in most interactive 3D applications

29
Orthographic Projection
  • Projection lines are orthogonal to projection
    surface

30
Orthographic Projection
  • Projection plane parallel to principal face
  • Usually form front, top, side views

isometric (not multiview orthographic view)
front
in CAD and architecture, we often display three
multiviews plus isometric
side
top
31
Orthographic Projection
  • Preserves both distances and angles
  • Shapes preserved
  • Can be used for measurements
  • Building plans
  • Manuals
  • Cannot see what object really looks like because
    many surfaces hidden from view
  • Often we add the isometric view

32
Orthographic Projection in OpenGL
  • Specify an orthographic view volume in OpenGL
  • glOrtho(left,right,bottom,top,near,far)
  • Anything outside the viewing frustum is clipped.

near and far are distances from camera
33
Orthographic Projection in OpenGL
  • The orthographic view volume is a rectangular
    volume
  • The orthographic view volume is along the
    negative Z axis
  • Remember that projection transformation happens
    after the view transformation
  • At this point, the camera is at the origin,
    pointing to the negative Z axis

34
What does glOrtho() do?
  • Internally OpenGL will create the following
    matrix
  • where
  • tx - (right left) / (right - left)
  • ty - (top bottom) / (top - bottom)
  • tz - (zFar zNear) / (zFar - zNear)
  • The current projection matrix is multiplied by
    this matrix and the result replaces the current
    projection matrix

35
glOrtho()
  • There is a current projection matrix in OpenGL
  • Before calling glOrtho(), you need to tell OpenGL
    that you are modifying the projection matrix.
  • glMatrixMode(GL_PROJECTION)
  • glLoadIdentity()
  • glOrtho(left, right, bottom, top, near, far)
  • glMatrixMode(GL_MODELVIEW)
  • After calling glOrtho(), you want to set the
    current matrix to GL_MODELVIEW matrix so the
    subsequent transformation calls wont affect the
    projection matrix

36
Orthographic projection
  • The matrix created by glOrtho() will transform
    the orthographic view volume to canonical view
    volume
  • A cube that extends from -1 to 1 in x, y, z.
  • This is often called the clip space.
  • The next steps are clipping, perspective
    division, and view port transformation
  • Well discuss clipping later

37
Perspective Projection
  • Projectors converge at center of projection

38
Advantages Disadvantages
  • Objects further from viewer are projected smaller
    than the same sized objects closer to the viewer
  • Make images look realistic
  • Equal distances along a line are not projected
    into equal distances
  • Angles preserved only in planes parallel to the
    projection plane
  • More difficult to construct by hand than
    orthographic projection (but not more difficult
    by computer)

39
Perspective Projection in OpenGL
  • We define the perspective view volume by calling
  • glFrustum(left,right,bottom,top,near,far)
  • Again, near and far are distances from camera
  • However, with glFrustum it is often difficult to
    get the desired view

40
Perspective Projection in OpenGL
  • gluPerpective(fovy, aspect, near, far) often
    provides a better interface
  • However, it assumes that viewing window is
    centered about the negative Z axis

aspect w/h
41
Perspective Projection
  • Unlike the orthographic view volume, the
    perspective view volume is a like truncated
    pyramid
  • The perspective view volume is also along the
    negative Z axis
  • Remember that projection transformation happens
    after the view transformation
  • At this point, the camera is at the origin,
    pointing to the negative Z axis

42
Perspective Projection
  • The job of perspective projection is to transform
    this view volume (and everything in it) to a
    canonical view volume
  • Everything outside of this volume will be clipped
    and ignored

43
Perspective Projection
  • Unfortunately there is no 4x4 matrix that can
    achieve the perspective transformation
  • But there is a workaround called perspective
    division
  • Use a 4x4 matrix to generate a different kind of
    homogeneous points.
  • Then divide the first 3 components with the 4th
    component (w)
  • This is why homogeneous coordinates are used in
    3D graphics it allows matrix multiplications
    being used in projection transformation
  • Well see an example later

44
What does glFrustum() do?
  • Internally OpenGL creates the following matrix
  • A (right left) / (right - left)
  • B (top bottom) / (top - bottom)
  • C -(zFar zNear) / (zFar - zNear)
  • D (-2 zFar zNear) / (zFar - zNear)
  • The current projection matrix is multiplied by
    this matrix and the result replaces the current
    projection matrix

45
What does gluPerspective() do?
  • Internally OpenGL creates the following matrix
  • The current projection matrix is multiplied by
    this matrix and the result replaces the current
    matrix

46
Perspective Projection in OpenGL
  • There is a current projection matrix in OpenGL
  • Before calling gluPerspective(), you need to tell
    OpenGL that you are modifying the projection
    matrix
  • The following code would normally be part of the
    initialization routine
  • glMatrixMode(GL_PROJECTION)
  • glLoadIdentity()
  • gluPerspective(fovy, aspect, near, far)
  • glMatrixMode(GL_MODELVIEW)

47
Aspect Ratio
  • The aspect ratio in gluPerspective should match
    the aspect ratio of the associated viewport
  • Normally, gluPerspective(fov, w/h, near, far)
  • W is the width of your window, h is the height of
    your window
  • You want the aspect ratio of your perspective
    view volume to match the aspect ratio of your
    window
  • Otherwise, your final image will look distorted
  • E.g. if you set aspect ratio to be a constant
    value, then when you resize your window, your
    image will look distorted

48
Perspective projection
  • The matrix created by glFrustum() or
    gluPerspective() will transform the perspective
    view volume to a canonical view volume
  • A cube that extends from -1 to 1 in x, y, z.
  • This is often called the clip space.
  • The next steps are clipping, perspective
    division, and view port transformation
  • Well discuss clipping later

49
The journey of a vertex so far
  • The vertex will be transformed first by the
    model-view matrix and then by the projection
    matrix
  • p P x V x M x p

E.g. glTranslatef() glRotatef()
E.g. gluLookAt()
E.g. gluPerspective()
50
After the perspective projection
  • As the result of the these transformations,
    vertex p is transformed to p
  • After perspective projection, the 4th element of
    the homogenous coordinates of p may not be 1 any
    more
  • We have to homogenize it to get the real
    coordinates
  • Divide every element by the 4th element (called
    w)

Normalized Device Coordinates
After perspective transformation
51
Perspective division
  • This operation is also called perspective
    division
  • The homogenized coordinates are called Normalized
    Device Coordinates
  • This is the coordinates for point p in the
    canonical view volume
  • Now we are ready to map this point to the window

52
View port transformation
53
View port transformation
  • View port transformation transforms x and y from
    normalized device coordinates to window
    coordinates
  • Note that z value of the normalized device
    coordinates are not transformed in this stage
  • Because z axis is orthogonal to the window (2D
    plane) and Z values have no effect in the mapping
  • Remember our eye is looking down negative Z
  • But this z value is not lost. It will be passed
    down to the rasterizer stage
  • Will be used in scan conversion and depth buffer
    test

54
View port transformation in OpenGL
  • glViewport(GLint x, GLint y, GLsizei width,
    GLsizei height)
  • x, y Specify the lower left corner of the
    viewport rectangle, in pixels. The initial value
    is (0,0).
  • width, height Specify the width and height of
    the viewport.

55
What does glViewport() do?
  • Let (xnd, ynd) be normalized device coordinates.
    Then the window coordinates (xw, yw) are computed
    as follows
  • xw (xnd 1)(width / 2) x
  • yw (ynd 1)(height / 2) y
  • Its a matrix multiplication too.
  • Now we know where to place this particular vertex
    in the final 2D image

56
glViewport()
  • glViewport(GLint x, GLint y, GLsizei width,
    GLsizei height)
  • X and y are normally set to (0, 0)
  • Width and height are normally set to window width
    and height
  • This means your 2D image size matches your window
    size
  • You can make your image smaller or bigger than
    the window by adjusting those values
  • E.g. put multiple images in one window

57
The journey of a vertex
58
Why do we spend so much time on transformations?
  • Because thats where many people find OpenGL
    programs hard to understand
  • You need to know those low level details when you
    write vertex shader programs
  • Your vertex shader, not OpenGL, are supposed to
    handle the model, view, and projection
    transformations
  • In your vertex shader, youll have to deal
    directly with transformation matrices and matrix
    multiplications

59
Example
  • / planet.c/
  • include ltGL/glut.hgt
  • static int year 0, day 0
  • void init(void)
  • // Specify the color (black) used to clear the
    frame buffer (but not actually do it)
  • glClearColor (0.0, 0.0, 0.0, 0.0)
  • glShadeModel (GL_FLAT) // choose shading
    model

60
Example
  • void display(void)
  • glClear (GL_COLOR_BUFFER_BIT) // Actually
    clear the frame buffer
  • glColor3f (1.0, 1.0, 1.0) // set the color
    for each vertex
  • glPushMatrix() // current modelview matrix is
    the view matrix
  • glutWireSphere(1.0, 20, 16) // draw sun,
    internally call glVertex3f()
  • glRotatef ((GLfloat) year, 0.0, 1.0, 0.0) //
    Multiply modelview matrix with a //
    rotation matrix
  • glTranslatef (2.0, 0.0, 0.0) // Multiply
    current modelview matrix with a
  • // translation matrix
  • glRotatef ((GLfloat) day, 0.0, 1.0, 0.0) //
    Multiply current modelview matrix // with a
    rotation matrix
  • glutWireSphere(0.2, 10, 8) // draw smaller
    planet, internally call // glVertex3f()
  • glPopMatrix() // current modelview matrix is
    view matrix again
  • glutSwapBuffers() // swap double buffers

61
Example
  • void reshape (int w, int h)
  • glViewport (0, 0, (GLsizei) w, (GLsizei) h)
    // Define view port transformation
  • glMatrixMode (GL_PROJECTION) // Were going
    to modify current projection matrix
  • glLoadIdentity () // initialize projection
    matrix to the identity matrix
  • // create perspective projection matrix and
    post-multiply it with the current // projection
    matrix gluPerspective(60.0, (GLfloat)
    w/(GLfloat) h, 1.0, 20.0)
  • glMatrixMode(GL_MODELVIEW) // Were going to
    modify current model-view matrix
  • glLoadIdentity() // initialize modelview
    matrix to identity matrix
  • // place camera, internally generates a view
    matrix and
  • // then post-multiply the current modelview
    matrix with the view matrix
  • gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0,
    1.0, 0.0)

62
Example
  • void keyboard (unsigned char key, int x, int y)
  • switch (key)
  • case 'd'
  • day (day 10) 360
  • glutPostRedisplay() // force a call to
    display()
  • break
  • case 'D'
  • day (day - 10) 360
  • glutPostRedisplay()
  • break
  • case 'y'
  • year (year 5) 360
  • glutPostRedisplay()
  • break
  • case 'Y'
  • year (year - 5) 360
  • glutPostRedisplay()
  • break

63
Example
  • int main(int argc, char argv)
  • glutInit(argc, argv)
  • glutInitDisplayMode (GLUT_DOUBLE GLUT_RGB)
  • glutInitWindowSize (500, 500)
  • glutInitWindowPosition (100, 100)
  • glutCreateWindow (argv0)
  • init () // clear frame buffer and select
    shading model
  • glutDisplayFunc(display) // register event
    handlers
  • glutReshapeFunc(reshape)
  • glutKeyboardFunc(keyboard)
  • glutMainLoop() // Start the event loop
  • return 0

64
Summary
  • Viewing and projection is about how to position
    the camera and project the 3D scene to a 2D
    screen.
  • In OpenGL, view transformation is conducted by
    manipulating modelview matrix.
  • Projection transformation is conducted by
    manipulating projection matrix.
  • Viewport transformation is conducted by
    glViewport()

65
Readings
  • OpenGL Programming Guide chapter 3
  • OpenGL FAQ on Viewing
  • http//www.opengl.org/resources/faq/technical/view
    ing.htm

66
Next Lecture
  • Lighting and shading
  • Now we know where to place the vertices in the
    final 2D image, the next step is to calculate
    their colors
Write a Comment
User Comments (0)
About PowerShow.com