Lecture 3 - Simulate the World Now
Agenda for Today
We'll cover:
- View Volume
- Recentering
- World to pixel coordinates
- Depth
- Code gotchas
- Epsilon
int/int
- Data Structures
Announcements:
- Lab 1 & 2 today!
- P1 is due 1/23 (next Tuesday). You'll zip your project and send it in Canvas
Review
Recall how we interpolate colors. Given some colors
Where all
Later, we'll go to the GPU using OpenGL
.
The Strike
This class is different since Zoe herself is a volunteer for the class (not a teacher). However, we're not going to campus. We'll be going on zoom, where they should be shorter to withold zoom fatigue.
Thursday is likely only going to be lab time.
Writing Software to Move to OpenGL
We first need to make our own rasterizer in order for us to use OpenGL
and let that handle everything for us.
To start with, notice that we work in different spaces:
Really, a point like
- We'll need to scale all the world objects such that we get our values on the pixel screen
- We'll need to shift world objects so that, you know, they're on the screen.
We need ways to use data structures to get values from our pixels:
int W2PX(float xw) {
return (C*xw + D); // scale by C and shift by D
}
int W2PY(float xy) {
return (E*xy + F); // similar...
}
So how do we solve for our unknowns
Solving the Shifts and Scales...
We, as the programmers, can control the view volume (in OpenGL
we actually get more tools to control this too!). We have a value for the:
- top/bottom plane
- left/right plane
- near/far plane
Things in video games may "pop in" since certain games may not render in items from outside the view volume.
You may want to literally name these values as the planes they represent:
float left = -1.0;
float right = 1.0;
float far = 0.0;
float near = 1.5;
//...
But we have some things to consider. We may have like a 2:3 aspect ratio, like if our window had moved. As a result, our objects may be desired to be "stetched" or "squished":
So usually, the user sets the window size (in pixels), thus the aspect ratio is also chosen by them. If we stretch in one direction, we want to still preserve the aspect ratio of the world coordinates:
// width, height are the window sizes
if (width > height)
{
L = -width/height; // w > h -> L < -1
R = width/height; // R > 1
B = -1;
T = 1;
}
else
{
L = -1;
R = 1;
B = -H/W;
T = H/W;
}
// where's the near and far? For now, we going to have near = 0 and far -> infty.
// we'll essentially just flatten the z-axis, so this won't matter as much.
Essentially, one of my volume dimensions, either
When the user changes the output, the programmer has to make the decision to:
- try to maximize the space of the window
- still try to preserve the aspect ratio of the world space
Recentering + World to Pixel
Say we have a piano at
Really, if we're given some generic obj
file, we sometimes want to, in case all the vertices are far out, normalizes the coordinates so that we can recenter the object back to our bounding box.
You'll be given most of the recentering code, but there's a tinyobj loader
. One of these things computes the bounding box by doing this recentering. The worksheet below shows this as an example!
So for world to pixel, we'll need to use:
So when we set our values L, R, ...
for our view planes, they are in world coordinates. The leftmost coordinate plane should become 0:
And for the rightmost coordinate:
And with two equations, we have two unknowns
Where
And do the exact same thing for
Once you have this, you can write your W2PX
function:
vecN<int,2> W2PX(float x_w, float y_w)
{
// solve our equation above for x
// solve our equation above for y
return vecN<int,2>(x_p, y_p);
}
int/int
Really make sure that you are casting our int/int
to floats in the intermediary. If you just divide say 1/2
you get 0
since the int
part truncates the decimal portion.
2D Image Domain
Refer mainly to [[References for week 1-2 2D coordinate transforms reference (Gortler).pdf]]. It has a lot of information regarding the 2D Image domain...
Who's in Front? (Z-buffer)
You're going to make a rasterizer following:
![[Rasterizer psuedocode.pdf]]
Coding Concepts
On the GPU, we'll need to literally send C
-style arrays! This is because it's most efficient to send a pointer and a size to the GPU, rather than copying the data structures/classes inherent data.