Game Programming Algorithms and Techniques Chapter 4 3D Graphics
Chapter 4 Objectives Coordinate Spaces Learn the four main coordinate spaces Using matrices to transform into these coordinate spaces Learn the difference between orthographic and perspective Lighting and Shading Adding color and other vertex attributes Four major types of lights used in games Implementing the Phong reflection model Differences between Gouraud and Phong shading Visibility Algorithms Learn why we use z-buffering for 3D scenes Quaternions Why they are better to use than Euler angles
Basic 3D Terminology Software rasterization – Set of algorithms necessary to draw 3D objects into a 2D color buffer Modern computers have a graphics processing unit (GPU) that can do most rasterization: We just have to tell the GPU what we want to draw and where. Graphical artifact – Unintended result of using an approximate algorithm.
A sample mesh made with triangles Polygons Most games use triangles. Each point on the corner of a polygon is a vertex. A sample mesh made with triangles
Coordinate Spaces Coordinate spaces provide a frame of reference to the scene. Just like the Cartesian coordinate space has a specific origin, each coordinate space has its own origin. Most important coordinate spaces are: Model World View/camera Projection
Model Space Coordinate space where the vertices are expressed relative to the model's origin: In Maya, there is an origin that the model is drawn around, which is model space. But the same can be said for a procedurally generated asset.
Model Space, Cont'd Object in model space
World Space Coordinate space relative to the entire world. Objects that were in model space are transformed to a specific position and orientation in the world. To transform into world space, we need matrices.
World Space, Cont'd Several instances of the object positioned/oriented relative to world space
Homogenous Coordinates Adding a fourth component to a 3D vector so it can be transformed by 4x4 matrices. This fourth component is the w-component. w is usually either 0 or 1: If w = 1, 3D vector is a position. If w = 0, 3D vector is a vector.
Transform Matrices Allow us to modify vectors in certain ways. These matrices are used to transform vertices from model space to world space. Common operations: Scale Rotate Translate
Scale Matrix Changes the scale along the three coordinate axes: If sx = sy = sz, it's a uniform scale.
Translation Matrix Moves a point by a set amount. Does not work if w = 0 because vectors have no position.
Rotation Matrices Different rotations, once for each coordinate axis:
Order of Transforms The order really matters. Generally, when using row-major vectors, you want:
Order of Transforms, Cont'd If we translate and then rotate, we will orbit around the origin: An object translated and then rotated about the world’s origin instead of about its own origin
View/Camera Space Coordinate space relative to the camera Camera space © York/fotolia
View/Camera Space, Cont'd One way to construct the camera matrix is a look-at matrix: L = Left U = Up F = Front T = Translation
CreateLookAt function CreateLookAt(Vector3 eye, Vector3 target, Vector3 Up) Vector3 F = Normalize(target – eye) Vector3 L = Normalize(CrossProduct(Up, F)) Vector3 U = CrossProduct(F, L) Vector3 T T.x = -DotProduct(L, eye) T.y = -DotProduct(U, eye) T.z = -DotProduct(F, eye) // Create and return look-at matrix from F, L, U, and T ... end
Projection Space Coordinate space where a 3D scene is flattened into a 2D one. Two main ways projection can be set up: Orthographic: No depth perception. (Objects further away from the camera are the same size.) Perspective: True 3D depth perception.
Orthographic Projection Top-down view of an orthographic projection (a), and the resulting 2D image onscreen (b) = Top-down view of projection = Resulting 2D image on screen
Perspective Projection Top-down view of a perspective projection (a), and the resulting 2D image onscreen (b) = Top-down view of projection = Resulting 2D image on screen
Orthographic Projection Matrix width = Width of view height = Height of view near = Distance from camera to near plane far = Distance from camera to far plane
Perspective Projection Matrix fov = Field of view angle
RGBA Color Space Separate channels for red, green, blue, and alpha (or transparency). Common implementation is 1 byte per channel, or 4 bytes per pixel. Often expressed as values from 0.0f to 1.0f.
RGBA Color Space, Cont'd Opaque red and purple in the RGBA color space (a). A transparent blue allows other colors to be visible underneath (b).
Vertex Attributes Information that is stored for every vertex Common attributes: Color Texture coordinates Vertex normal
Texture mapping with UV coordinates Uses (u,v) coordinates to represent position of texture Texture mapping with UV coordinates
Averaged vertex normals Can be average of the normal of all adjacent polygons Averaged vertex normals
Vertex Normals, Cont'd Can be different depending on which polygon the vertex is a part of Vertex A on the cube uses one of three different normals, depending on the face.
Clockwise winding order (a), and counterclockwise winding order (b) Determines which way the normal faces = Clockwise = Counter-clockwise Clockwise winding order (a), and counterclockwise winding order (b)
Winding Order, Cont'd Drawing with the wrong winding order can cause polygons to disappear! A cube rendered with the correct winding order (a), and the same cube rendered with the incorrect winding order (b)
Lights Add visual interest to the scene. Some lights affect the scene as a whole: Ambient Directional Some lights affect only parts of the scene: Point light Spot light
Example in nature of ambient light Uniform amount of light applied evenly to every side of every object in the scene Example in nature of ambient light
Example in nature of directional light No position, but emitted from a specific direction Effects every object in the scene, but only illuminates one side of each object Example in nature of directional light
A light bulb in a dark room is an example of a point light. Set at a specific point and emanates in all directions. Often the intensity of the light has a fall-off as you get further from it. A light bulb in a dark room is an example of a point light.
A spotlight on stage is an Like a point light, but has a limited angle of effect A spotlight on stage is an example of a spot light.
Phong Reflection Model One type of BRDF that represents how light bounces off of a surface. Phong reflection is a local lighting model, which means each object is lit as if it were the only object in the scene. Three components: Ambient Diffuse Specular
Phong Reflection Model, Cont'd Ambient Overall illumination of the scene Independent of the location of lights and the camera Diffuse Primary reflection of light off surface, depends on: Normal of surface Location of lights Specular Shiny highlights Depends on everything diffuse does, plus the location of the camera
Phong Reflection Model, Cont'd
Phong Reflection Model Pseudocode // Vector3 N = normal of surface // Vector3 eye = position of camera // Vector3 pos = position on surface // float a = specular power (shininess) Vector3 V = Normalize(eye – pos) // FROM surface TO camera Vector3 Phong = AmbientColor foreach Light light in scene if light affects surface Vector3 L = Normalize(light.pos – pos) Phong += DiffuseColor * DotProduct(N, L) Vector3 R = Normalize(Reflect(-L, N)) // Reflect –L about N Phong += SpecularColor * pow(DotProduct(R, V), a) end
Shading Determines: Where we compute the BRDF How we fill in the rest of the polygons Two important shading techniques: Gouraud Phong (not the same thing as Phong reflection model!)
Object drawn with Gouraud shading Compute BRDF at each vertex Interpolate colors between the vertices Object drawn with Gouraud shading
Object drawn with Phong shading Interpolate vertex normals between vertices Compute BRDF at every pixel Object drawn with Phong shading
Painter's Algorithm Redux Painter's algorithm doesn't work well for 3D scenes. We would have to sort every triangle back to front. Worse, the camera is dynamic, so we'd have to re-sort! The painter's algorithm has a lot of overdraw— redrawing the same pixel multiple times per frame.
Painter's Algorithm Failure In 3D, there is a possibility that no one triangle is the furthest back. Overlapping triangles failure case
Z-Buffering Create a new screen-sized buffer called the z-buffer. It stores the depth of every pixel that is drawn. As we draw pixels in the scene, only draw it if the depth stored in the z-buffer is greater than the depth of the current pixel.
A sample scene and its corresponding z-buffer Z-Buffering, Cont'd A sample scene and its corresponding z-buffer
Z-Buffering Pseudocode // zBuffer[x][y] grabs depth at that pixel foreach Object o in scene foreach Pixel p in o float depth = calculate depth at p if zBuffer[p.x][p.y] > depth draw p zBuffer[p.x][p.y] = depth end
Euler Angle Problems Difficult to do arbitrary rotations: We can't just point in a direction; we have to figure out the correct rotation about coordinate axes. We can't rotate about an arbitrary axis. Difficult to interpolate between orientations. Euler angles can have gimbal lock.
A 90° rotation about the z-axis causes gimbal lock.
Quaternions Can be used for lots of things, but for 3D graphics they are used to represent arbitrary rotations. We use unit quaternions (length of 1). Have a vector and scalar component. Given an arbitrary axis and an angle of rotation, we can construct a quaternion:
Quaternion Advantages Can perform an arbitrary rotation Only use four floating point values (as opposed to 16 with a matrix) Smoothly interpolate
Other Quaternion Properties To rotate by quaternion q and then quaternion p, multiply p * q, using the Grassman product: To invert a unit quaternion, negate the vector component. Identity quaternion:
Final 3D Game Object Representation class 3DGameObject Quaternion rotation Vector3 position float scale function GetWorldTransform() // Order matters! Scale, rotate, translate. Matrix temp = CreateScale(scale) * CreateFromQuaternion(rotation) * CreateTranslation(position) return temp end