This page works better with JavaScript enabled!
Virtual GPU
When I was writing a small game using
WebGL,
I found it a little difficult to wrap my head around certain things related to 3D-graphics.
Specifically, I was interested in getting a deeper understanding, how
shader programs
work on the mesh data. The matrix calculations weren't too intuitive either.
So I set out to recreate the inner workings of such a graphics accelerator in JavaScript, in order
to see first hand, what is done when and where, and how it all fits together.
The result was an
emulator
of a simple GPU, that simulates the most important steps being taken,
when a 3D image is rendered, including simulated shaders.
Page Contents
- Virtual GPU
- Page Contents
- Overview
- Goals - What should the virtual GPU actually do?
- Math for 3D Graphics
- Vector Manipulation
- Dot Product (Scalar Product)
- Algebraic Definition
- Geometric Definition
- Applications
- Angle between Vectors
- Backface culling
- Interactive Example
- Links
- Cross Product (Vector Product)
- Links
- Matrix Manipulation
- Vector-Matrix Multiplication
- Quick introduction
- Definition
- Generic Rule
- Applications
- Vector Multiplied by Identity Matrix
- Scaling
- Interactive Example
- Rotation
- Rotation Along X-Axis
- Rotation Along Y-Axis
- Rotation Along Z-Axis
- Interactive Example
- Translation
- Interactive Example
- Links
- Matrix-Matrix Multiplication
- Definition
- Algebraic Definition
- Definition via Code
- Generic Rule for a 4 × 4 Matrix
- Links
Overview
Goals - What should the virtual GPU actually do?
In order to replicate a GPU, we need to take a look at how programs are utilizing it.
This section aims to provide an introduction into the basics of 3D graphics.
Projecting from "world space" into "screen space" using the projection matrix
Math for 3D Graphics
Vector Manipulation
Dot Product (Scalar Product)
Algebraic Definition
a · b
=
a
ib
i = a
1b
1 + a
2b
2 + ...
a
nb
n
Geometric Definition
a · b
=
|a| |b| cos θ
Applications
Angle between Vectors
cos θ
=
a · b
|a| |b|
=
a
xb
x + a
yb
y
ax²
+ ay²
·
bx²
+ by²
Backface culling
The dot product tells us, how much one vector projects onto another.
It is a measure, how similar the direction of a
is to the normal vector of b.
(In 3D, it compares to the normal plane of b.)
For unit vectors, it ranges from -1 to +1, where +1 would indicate both vectors pointing in the same direction.
This can be used to determine, if a face is pointing towards or away from the camera.
For convex objects, only faces pointing to the camera need to be rendered,
because faces seen from their back are obscured anyways.
Interactive Example
The example requires JavaScript
Links
Cross Product (Vector Product)
Links
Matrix Manipulation
Vector-Matrix Multiplication
Quick introduction
Working with matrices is really simple. We use them to denote, how elements are to be combined.
Let's take a look at a simple vector-matrix multiplication, v multiplied by
a 2 × 2 matrix M.
The result is another vector r. It's elements are calculated like so:
r =
vM =
-
v1m11
+ v2m21
-
v1m12
+ v2m22
Definition
Generic Rule
a11 | a12 | a13 | a14 |
a21 | a22 | a23 | a24 |
a31 | a32 | a33 | a34 |
a41 | a42 | a43 | a44 |
=
-
x · a11
+ y · a21
+ z · a31
+ w · a41
-
x · a12
+ y · a22
+ z · a32
+ w · a42
-
x · a13
+ y · a23
+ z · a33
+ w · a43
-
x · a14
+ y · a24
+ z · a34
+ w · a44
Applications
Vector Multiplied by Identity Matrix
1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 0 | 0 | 1 |
=
- x·1 + y·0 + z·0 + w·0
- x·0 + y·1 + z·0 + w·0
- x·0 + y·0 + z·1 + w·0
- x·0 + y·0 + z·0 + w·1
=
Scaling
Interactive Example
The example requires JavaScript
Rotation
Rotation Along X-Axis
1 | 0 | 0 |
0 | cos θ | sin θ |
0 | -sin θ | cos θ |
=
- x
- y cos θ - z sin θ
- y sin θ + z cos θ
Rotation Along Y-Axis
cos θ | sin θ | 0 |
0 | 1 | 0 |
-sin θ | cos θ | 0 |
=
- x cos θ - z sin θ
- y
- y sin θ + z cos θ
Rotation Along Z-Axis
cos θ | sin θ | 0 |
-sin θ | cos θ | 0 |
0 | 0 | 1 |
=
- x cos θ - y sin θ
- x sin θ + y cos θ
- z
Translation
1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
tx | ty | tz | 1 |
=
Links
Matrix-Matrix Multiplication
Definition
Algebraic Definition
If A is an m × n matrix, and B is an n × p matrix,
A =
a11 | a12 | ⋯ | a1n |
a21 | a22 | ⋯ | a2n |
⋮ | ⋮ | ⋱ | ⋮ |
am1 | am2 | ⋯ | amn |
,
B =
b11 | b12 | ⋯ | b1p |
b21 | b22 | ⋯ | b2p |
⋮ | ⋮ | ⋱ | ⋮ |
bn1 | bn2 | ⋯ | bnp |
,
the matrix product C is defined as the m × p matrix
C =
c11 | c12 | ⋯ | c1p |
c21 | c22 | ⋯ | c2p |
⋮ | ⋮ | ⋱ | ⋮ |
cm1 | cm2 | ⋯ | cmp |
such that
c
ij
=
a
i1b
1j + a
i2b
2j + ⋯ + a
inb
ni
=
a
ikb
kj
for i = 1, ..., m and j = 1, ..., p.
That is, the entry cij of the product is obtained by multiplying term-by-term the entries of the
ith row of A and the jth colum of B, and summing these n products.
In other words, cij is the dot product of the ith row of A and the jth column of B.
Therefore, AB can also be written as
C =
a11b11 + ⋯ + a1nbn1 |
a11b12 + ⋯ + a1nbn2 |
⋯ |
a11b1p + ⋯ + a1nbnp |
a21b11 + ⋯ + a2nbn1 |
a21b12 + ⋯ + a2nbn2 |
⋯ |
a21b1p + ⋯ + a2nbnp |
⋮ |
⋮ |
⋱ |
⋮ |
am1b11 + ⋯ + amnbn1 |
am1b12 + ⋯ + amnbn2 |
⋯ |
am1b1p + ⋯ + amnbnp |
Definition via Code
for (row = 0; row < n; ++row) {
for (col = 0; col < m; ++col) {
C[row][col]
= A[row][0] * B[0][col]
+ A[row][1] * B[1][col]
+ ...
+ A[row][m] * B[n][col]
Generic Rule for a 4 × 4 Matrix
a11 | a12 | a13 | a14 |
a21 | a22 | a23 | a24 |
a31 | a32 | a33 | a34 |
a41 | a42 | a43 | a44 |
b11 | b12 | b13 | b14 |
b21 | b22 | b23 | b24 |
b31 | b32 | b33 | b34 |
b41 | b42 | b43 | b44 |
=
a11b11 |
a12b21 |
a13b31 |
a14b41 |
a21b12 |
a22b22 |
a23b32 |
a24b42 |
a31b13 |
a32b23 |
a33b33 |
a34b43 |
a41b14 |
a42b24 |
a43b34 |
a44b44 |
Links