CS 446: Real-Time Rendering
Assignment #3
Synopsis: Build the basic underpinnings of a 3D scene-graph engine.
Your program should be able to import 3D models with hierarchical
transformations, place them into a scene graph, and render the scene. Your
scene graph should support multiple traversals (for example, to render the scene
from multiple interactively controlled cameras), along with basic view-frustum
culling and basic LOD. Finally, your group should decide on and propose
the game you will build.
Due: This assignment has multiple components, each quite challenging
in its own right. To help you organize your effort, we will check your
progress midway through:
Feb 23, 2006 Checkpoint: Load and
fly around multiple models (40%)
Mar 2, 2006 Final assignment:
Everything else (60%)
Details: This is where you start: in this assignment your group will build a
basic scene-graph renderer that will become the base of your game engine.
Your renderer should support:
- Importing 3D models: your program will support loading multiple 3D models
in one or more file formats. Suggested file formats include .obj (alias/wavefront
objects), .md2 (QuakeII), .md3 (QuakeIII), .flt (OpenFlight), .3ds (3D Studio Max), .ma (Maya ascii). These formats are listed roughly in order of complexity.
The .obj file format is quite simple, but it will be difficult to find or
create
interesting models. The .3ds format is fairly complex, but many, many
models are publicly available.
- Hierarchical transformations: your program should support hierarchical
transformations in the organization of objects within the scene; for example,
if a statue sits on a table and the table is moved, the statue should move
with it. Your program may optionally support hierarchical transforms
within a single model, i.e. for articulated characters. Note that only
some of the file formats above (.flt, .3ds, .ma) support hierarchical models. If you
choose not to implement such a file format, you must write your own scene
description file that describes the objects in the scene and their
organization (I suggest using XML for this, as it is powerful, flexible,
extensible, and human-readable, and since tools like libxml can
alleviate much of the pain and suffering of parsing). Note that you
don't (yet) need to support loading "levels", in the sense of maps, terrains,
or background objects like walls, ceilings, etc.
- Instancing: your program should support instancing, in which a single
model can be represented (instantiated) multiple times with different
transforms and different graphics state.
- Moving objects: your program should allow the user to pick an object and
translate or rotate it within the scene (of course, hierarchical
transformations should be respected, so that any children of the selected
object are also affected by the user's actions on the parent object).
You should use the mouse to control translation and rotation (e.g., left
button translates X/Y; middle button translates Z; right button rotates) and
either use the mouse to select objects, or a keystroke to cycle through
which object is selected.
- Simple texturing and lighting: You should be able to load and display
models with simple texturing and/or lighting. The user or scene file
should be able to specify the rendering state (texture on/off, lighting
on/off, wireframe on/off) for each object or instance. The
interface is less important than the functionality here; I suggest "T", "L",
and "W" keystrokes to toggle each state for the selected objects. Directional
lighting and simple texture modes are fine for now; you should also implement
point-light sources associated with nodes in your scene graph.
- Simple distance-switched discrete LOD: Objects may be represented by
multiple LODs depending on the distance from the viewpoint to the object.
These distances can be set manually or automatically.
- Hierarchical view-frustum culling: Off-screen objects are not
drawn. Calculate and store bounding
volumes with subtrees in your scene graph, and avoid rendering off-screen
objects by testing those bounding volumes against the planes of the view
frustum. Bounding volumes should be correctly updated with object
transformations. To account for animated objects, you may either pick a
bounding volume large enough to contain the object at all steps of the
animation, or incrementally update the volume.
- Multiple viewpoints/traversals: The user should be able to switch
between multiple cameras, for instance first- and third-person perspectives.
One particular traversal you should support is a "top-down" view showing the
effects of culling (draw the view-frustum and show objects disappearing when
they leave it) and LOD (objects get simpler with increasing distance).
Note that in this kind of view, the camera used for LOD and visibility culling
is not the same one used in rendering. This top-down view is an
invaluable debugging tool that you will need throughout the class!
- Interactive camera control: Your program should provide interactive
mouse-based camera control (you may implement a keyboard interface in addition
if you wish).
- Propose your game concept: You should write a formal proposal
describing the game that your group intends to create over the course of the
semester: concept, gameplay, visuals, and core real-time rendering techniques.
Your proposal should detail the overall shape of your game, the technical
contributions that your engine will incorporate, and (where you know) who will
code what. You should include some hand-made "screenshots" to help
explain the intended gameplay and visuals. You should have a game plan for
staged development, so that if your full-fledged game proves beyond the scope
of the semester, you will still develop something fun and interesting.
In response I will provide feedback on your ideas, whether you're being too
ambitious or not ambitious enough, and perhaps some (hopefully) useful advice.
Resources: There are many places you can go to look for advice,
tutorials, details, and source code for games, from loading file formats to AI
and physics. This can be
frustrating, however, as many of the resources on the Web are the results of
enthusiastic amateurs rather than paid professionals. Some good places to
start are:
- www.gamasutra.com: Lots of useful
information on game programming here, along with the usual chaff.
- http://www.gametutorials.com: a
soup-to-nuts series of source code "tutorials" on game programming, written
for beginning programmers but containing some useful information.
The tutorials are in the form of heavily-commented source code. In
particular there are fairly good tutorials on loading some different 3D file
formats. Update: These used to be free; at a glance it looks like now
they are charging (the idea is that you buy a whole CD with all zillion
tutorials for $50, or one with all the 3D graphics tutorials for $20).
- http://lib3ds.sourceforge.net:
a library for reading .3ds files, seems fairly complete.
- www.planetquake.com/polycount: lots of models for various games.
- http://www.turbosquid.com:
Models, textures, and other assorted downloads for 3D graphics & game
development. Some stuff for free, lots of stuff for sale (often at extremely
low prices).
- 3D Studio Max files: I have purchased a collection of over 5000 models in
3D Studio .max format (not the same as .3ds), available at
\\eirene.cs.virginia.edu\3dEnc2000 in Windows. You can export these
models (for example, to .3ds format...) and create new ones using 3D Studio
Max, which is (or will be) available in 002a. You can browse these models more
conveniently at
http://www.deespona.com/3denciclopedia/menu.html.
- Note that we also have Maya, another
modeling package. If you
want to use Maya we should be able to accommodate you. There is a lot of Maya
expertise on Grounds, both here in the CS department (including your very
own TA) and in the Digital Media Lab in Clemons Library, which has lots of
FAST machines with Maya installed and employees (some anyway) who are expert
in its use.
Also, don't forget about the optional texts for the course like the GPU Gems series!
Lab: We are sharing Olsson 002a this semester. Many of you will
need to get a key from Ginny Hilton at the CS front desk (if you already have a
key, for example, to 001, check first to see if it works). There are 13
machines and ~25 students in this class, plus occasional students in other
classes using
the lab...so be courteous and don't assume you will always get a computer
exactly when you were planning to work. The machines in 002 have decent
processors and decent (ATI X600) graphics cards; I will be installing a
few GeForce 7-class cards (the latest programmable graphics cards from NVIDIA) later. My
tentative plan is to have one very high-end card installed for testing purposes,
and a bunch of low-end but latest-generation cards for development. If you would rather work
on a personal machine, that's fine too -- in fact it will take the pressure off
the lab machines. Let me know any issues you encounter -- this is an
unusual use of this lab and there will undoubtedly be software, hardware, and availability issues to
work out.
Policy on code reuse: In general you are welcome to use code that you
find elsewhere. For example, you are welcome to use the lib3ds library mentioned above,
and you are encouraged to use our in-house software tools (linked to from the
main page).
However, you will not get credit for what you didn't write. Therefore, it
is critically important that you describe in detail what code you wrote
yourself and what code you imported or adapted from elsewhere.
Furthermore, if you find a particularly helpful library, tutorial, loader, etc.,
you should post it on the forum. Obviously
if you reuse a significant amount of code, that raises the bar for the
assignment: you will be expected to do something beyond the basics mentioned
above. If you have any questions about
code reuse or attribution, please ask me.
Platform: I would prefer that your code compile and run under
Microsoft Visual Studio .NET 2003, which is what is installed in the lab. Please
don't use VS.NET 2005 beta. If your
entire group wants to develop under Linux or Macintosh,
go ahead. Any Linux projects should compile and run on the lab machines;
this may require intervention by root (to install libraries, etc) so don't put
off testing your code down there. If you go Mac, you will need to work
with me to make sure one of our few Macs can run your code. You are welcome to use
any GL extensions supported
by NVIDIA or ATI cards.
If you want to use a particular input device (joystick or whatever), talk to me first...you may have to
lend it to us so we can grade your assignment.
Turning in the assignment: Checkpoint: Demo to the instructor
or TA that you can load and fly around multiple models. Final
assignment: Put all your code and models in a folder,
along with a detailed README.txt file that describes what your group did, who in
the group did what, what code you
wrote and what code you used from elsewhere, and how to run your assignment.
Zip up the folder and e-mail the .zip file (or a link) to me and the TA.
Be sure to include workspace and project files, along with any libraries/include
files/etc, so that we can compile your code.
We will read (and grade you on) your source code, so follow good programming
practices.
Advice: If this sounds like a lot for a two-week assignment, that's
because it is a lot. An awful lot. This will be the hardest assignment
in terms of the sheer amount of code you need to write. It is particularly
important to start early because you will be building on this code for the
remainder of the course; a careful and thoughtful design now will simplify
everything down the road, whereas a rush job will introduce bugs and design
flaws that will continue to bite you throughout the semester. Now is the
time to follow good careful software engineering practices: think carefully
about your design BEFORE you start, test your classes and functions early and
often, and use CVS to back up your work for disaster recovery and revision control.