CS488 - Introduction to Computer Graphics - Lecture 9

Public Service Announcements

  1. Assignment 2 due 4 June, one week from today.

Perspective Projection


Mouse Interface

Model-View-Controller

Model

The application logic

View

Presentation of the model to the user

Controller

Provision of interpreted (more or less) input to the user

Complication

Usually the view knows where in screen coordinates it put each scene element

Picking

For assignment 3 you need to be able to select graphical objects with the mouse

The simple principle

  1. Mouse gives (x, y).
  2. Render pixel at (x, y ) keeping track of the polygon it comes from.
  3. Associate polygon with object

For the assignment let GL do it for you.

See the notes.

Rotation

For assignment 3 you need to be able to rotate with the mouse

The virtual trackball

You need to modify the sample code.


Hierarchical Models

What we have

How to render any polygon anywhere

  1. Put the polygon where you want it to be in world coordinates
  2. Transform to view coordinates
  3. Perspective transform
  4. Clip in normalized device coordinates.
  5. Scan convert each polygon in any order, using z-buffer to remove occuded pixels

What we want to have

Objects made of polygons that we can feed into the rendering pipeline.

Argument by example

  1. A Forest consists of many trees, each at a different location, scale and orientation
  2. Each Tree has a Trunk (in a TkCS) and a Root (in an RCS)
  3. Each Trunk has several branches, each with a BCS
  4. Each branch has many twigs, each having a TgCS
  5. Each twig has several leaves, LCS

Aside. It seems to me that we have, rather glibly, required a lot of choosing and defining

  1. We defined one polygon mesh for each version of a tree element: 5(types of element) x 10(versions per type) = 50 meshes to model.
  2. We choose a set of each type from the versions: 10(elements per set) x 10(choices per element) = 100
  3. We define a matrix for each element: 1(trunk) x 1(root) x 10(branches) x 10(twigs) x 10(leaves) = 1000

This should seem like a lot of work, because it is. Remember this when I tell you that your project has too much modelling.

This seems like work a computer could do better than a human. Much research has been done with -- usually -- disappointing results. We have not yet found good algorithms that put in the right amounts of randomness and order. The human visual system seems to be very finally tuned to expect a correct

How do we render a leaf?

  1. Transform points from LCS to TgCS (MLTg)
  2. Transform points from TgCS to BCS (MTgB)
  3. Transform points from BCS to TkCS (MBTk)
  4. Transform points from TkCS to TCS (MTkT)
  5. Transform points from TCS to WCS (MTW)
  6. Transform points to view coordinates (MWV)
  7. Perspective Transform points to the image plane (MVIp)

Make up the matrix M = MVIp * MWV * MTW * MTkT * MBTk * MTgB * MLTg1

How do we render the second leaf?

  1. Multiply again: M2 = MVIp * MWV * MTW * MTkT * MBTk * MTgB * MLTg2

    Too much work.

  2. Do less work: M2 = M * (MLTg1)^-1 * MLTg2

    Accumulating round-off error.

  3. Keep around

    We like this approach because we can do it with a stack.

Scene Graph

Render a scene using a matrix stack.

Render a forest

proc forest(  )
  unitMatrix( )
  multMatrix(MVP)
  multMatrix(MWV)
  pushMatrix( )
    multMatrix(MTW1)
    tree1( )
  popMatrix( )
  pushMatrix( )
    multMatrix(MTW2)
    tree2( )
  popMatrix( )
  etc.
 

Render trees

proc tree1( )
  pushMatrix( )
    multMatrix(MTTk11)
    trunk1( )
  popMatrix( )
  pushMatrix( )
    multMatrix(MTR12)
    root2( )
  popMatrix( )

proc tree2( )
  pushMatrix( )
    multMatrix(MTTk21)
    trunk1( )
  popMatrix( )
  pushMatrix( )
    multMatrix(MTR22)
    root2( )
...

We don't want always to write a program, so we encapsulate the program as data.

Traverse a DAG

traverse( root )

proc traverse( node ) {
  if ( drawable( node ) ) {
    draw( node )
  }
  for each child {
    traverse( child )
  }
  return
}

Build a DAG

scene = gr.transform( )

tree1 = gr.transform( )
gr.add_child( tree1, scene )
gr.set_transform( tree1, gr.translation(...)*gr.rotation(...)*...)
...

root = gr.transform( )
rootshape = gr.cylinder( )
gr.add_child( root, tree1 )
gr.set_transform( root, gr.scaling(...)*... )
gr.addchild( rootshape, root )
gr.setmaterial( rootshape, rough_bark )

trunk = gr.transform( )
gr.add_child( trunk, tree1 )
gr.set_transform( trunk, gr.scaling(...)*... )
trunkshape = gr.cylinder( )
gr.add_child( trunkshape, trunk )
gr.add_material( trunkshape, roughbark )
// The code below is repeated for each branch
  branch = gr_transform( )
  gr.add_child( branch, trunk )
  gr.set_transform( branch, gr... )
  branchshape = gr_cylinder( )
  gr.add_child( branch, branchshape)
  gr.setmaterial( branchshape, mediumbark )
    twig = grtransform( )
    ...

column1 = gr.transform( )
gr.add_child( temple1, column1 )
gr.set_transform( column1, gr.translation(...)*gr.scaling(...)
...

which generates the DAG:

forest
|
tree1------------------------------tree2----------tree3--...
|                                  |              |
trunk1--root1                      trunk2--root2
|                                  |
branch11--branch12--branch13--...  branch21--...
|                                  |
twig111--twig112--twig113--...     twig211--...
|                                  |
leaf1111--leaf1112--leaf1113--...  leaf2111--...

Colour

What is needed for colour?

  1. An eye.
  2. A source of illumination.
  3. A surface.

How is colour created?

  1. Source of illumination emits light (photons of differing wavelength).
  2. Surface modifies light.
  3. Eye compares surfaces and notices different modifications.

How do we represent colour?

To the rescue,

But,

More precise requires illumination as well


Return to: