0% found this document useful (0 votes)
10 views12 pages

HPQ Coding For Gaming

The HPQ project investigates the impact of 3D rendering on the speed of a computer's ALU by developing a custom 3D rendering module. It explores various projection methods, including orthographic and perspective projections, and their mathematical formulations, alongside the role of the ALU in handling complex calculations necessary for rendering. The project also includes a practical implementation using Python and Pygame to visualize 3D objects and their transformations.

Uploaded by

bvatsa339
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views12 pages

HPQ Coding For Gaming

The HPQ project investigates the impact of 3D rendering on the speed of a computer's ALU by developing a custom 3D rendering module. It explores various projection methods, including orthographic and perspective projections, and their mathematical formulations, alongside the role of the ALU in handling complex calculations necessary for rendering. The project also includes a practical implementation using Python and Pygame to visualize 3D objects and their transformations.

Uploaded by

bvatsa339
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 12

HPQ Coding for Gaming

This HPQ project focuses on the complexity and puzzling nature 3D rendering has on gaming more
specifically the analysis of how it affects the Speed of the computers ALU. We are going to achieve this
by making a 3D rendering module ourselves this will help use do custom tests on the ALU giving us a
more deeper understanding of the effects.

First we must understand 3D rendering in its entirety to begin with so that we can dive deeper into the
specifics and details of my methods I have used in my artifact.

A method mathematicians use to look at 3D rendering is:

Orthographic Projection:

This method projects 3D points onto a 2D plane by dropping perpendiculars from each point to the
plane. It's a simple method but doesn't accurately represent depth, as all 3D points along a line
perpendicular to the plane project to the same 2D point.

Perspective Projection:

This method takes into account the distance of 3D points from a viewpoint, which helps convey depth in
the 2D projection. It's the basis for 3D rendering and drawings.

2. Mathematical Formulation:

Orthographic Projection:

The most basic projection involves discarding the z-coordinate, resulting in the transformation (x, y, z) →
(x, y).

Perspective Projection:

This method involves dividing the x and y coordinates by the z-coordinate, effectively mapping 3D points
to 2D points based on their relative distance from the viewpoint. The formula is often represented as (x,
y, z) → (dx/z, dy/z), where d is a distance parameter.

ORTHOGRAPHIC PROJECTION
A simple orthographic projection onto the plane z = 0 can be defined by the following matrix:

For each point v = (vx, vy, vz), the transformed point Pv would be

For each homogeneous vector v = (vx, vy, vz, 1), the transformed vector Pv would be.

In computer graphics, one of the most common matrices used for orthographic projection can
be defined by a 6-tuple, (left, right, bottom, top, near, far), which defines the clipping planes.
These planes form a box with the minimum corner at (left, bottom, -near) and the maximum
corner at (right, top, -far).

The box is translated so that its center is at the origin, then it is scaled to the unit cube which is
defined by having a minimum corner at (−1,−1,−1) and a maximum corner at (1,1,1) which can
be given as a scaling S followed by a translation T of the form the inversion of the projection
matrix P−1, which can be used as the unprojection matrix is defined:

Types of orthographic projection

Classification of orthographic projection and some 3D projections


Three sub-types of orthographic projection are isometric projection, dimetric projection,
and trimetric projection, depending on the exact angle at which the view deviates from the
orthogonal. Typically in axonometric drawing, as in other types of pictorials, one axis of space is
shown to be vertical.

In isometric projection, the most commonly used form of axonometric projection in


engineering drawing, the direction of viewing is such that the three axes of space appear
equally foreshortened, and there is a common angle of 120° between them. As the distortion
caused by foreshortening is uniform, the proportionality between lengths is preserved, and the
axes share a common scale; this eases one's ability to take measurements directly from the
drawing. Another advantage is that 120° angles are easily constructed using only a compass
and straightedge.

In dimetric projection, the direction of viewing is such that two of the three axes of space
appear equally foreshortened, of which the attendant scale and angles of presentation are
determined according to the angle of viewing; the scale of the third direction is determined
separately.

In trimetric projection, the direction of viewing is such that all of the three axes of space
appear unequally foreshortened. The scale along each of the three axes and the angles among
them are determined separately as dictated by the angle of viewing. Trimetric perspective is
seldom used in technical drawings.

Multiview projection

Symbols used to define whether a multiview projection is either third-angle (right) or first-angle (left)
In multiview projection, up to six pictures of an object are produced, called primary views, with
each projection plane parallel to one of the coordinate axes of the object. The views are
positioned relative to each other according to either of two schemes: first-angle or third-
angle projection. In each, the appearances of views may be thought of as being projected onto
planes that form a six-sided box around the object. Although six different sides can be drawn,
usually three views of a drawing give enough information to make a three-dimensional object.
These views are known as front view (also elevation), top view (also plan) and end
view (also section). When the plane or axis of the object depicted is not parallel to the projection
plane, and where multiple sides of an object are visible in the same image, it is called
an auxiliary view. Thus isometric projection, dimetric projection and trimetric projection would be
considered auxiliary views in multiview projection. A typical characteristic of multiview projection
is that one axis of space is usually displayed as vertical.

import pygame as game_module


import sys as system
from math import *
import numpy as game_NP

game_module.init()

WINDOW_SIZE = 600
GAME_WINDOW = game_module.display.set_mode((WINDOW_SIZE, WINDOW_SIZE))
CLOCK = game_module.time.Clock()
FPS = 30
WHITE = (255, 255, 255)
RED = (255, 0, 0,)
BLACK = (0, 0, 0)
Colours = [(255,127,80), (255,165,0), (255,215,0), (127,255,0), (175,238,238),
(245,245,220)]
SCALE = 2
Rotaion_angle = 0.1
ANGLE_X = ANGLE_Y = ANGLE_Z = 0
PROJECTION_MATRIX = [[1, 0, 0],
[0, 1, 0],
[0, 0, 0]]
CUBE_POINTS = [n for n in range(8)]
CUBE_POINTS[0] = [[-1], [-1], [1]]
CUBE_POINTS[1] = [[1], [-1], [1]]
CUBE_POINTS[2] = [[1], [1], [1]]
CUBE_POINTS[3] = [[-1], [1], [1]]
CUBE_POINTS[4] = [[-1], [-1], [-1]]
CUBE_POINTS[5] = [[1], [-1], [-1]]
CUBE_POINTS[6] = [[1], [1], [-1]]
CUBE_POINTS[7] = [[-1], [1], [-1]]
CONNECTIONS = [
(0, 1), (0, 3), (0, 4),
(1, 2), (1, 5),
(2, 6), (2, 3),
(3, 7),
(4, 5), (4, 7),
(6, 5), (6, 7)
]
FACES = [
(0, 1, 2, 3), # Front
(3, 2, 6, 7), # Top
(1, 2, 6, 5), # right
(0, 3, 7, 4), # Left
(0, 1, 5, 4), # Bottom
(4, 5, 6, 7) # Back
]
POINTS = [0 for i in range(len(CUBE_POINTS))]
CAMERA = {
"x": 0,
"y": 100,
"z": 100, # Put it behind the object initially
"rotation_x": 0.1,
"rotation_y": 0,
"rotation_z": 0,
}
SPEED = 1
def connect_points(i, j, points):
game_module.draw.line(GAME_WINDOW, (255, 255, 255), (points[i][0],
points[i][1]) , (points[j][0], points[j][1]))

def connect_faces(w, x, y, z, points, col):


List = [points[w], points[x], points[y], points[z]]
game_module.draw.polygon(GAME_WINDOW, col, List)

class cuboid_maker:
def __init__(self, cube_points, Height, Width, Length, start_x, start_y,
start_z):
self.cube_points = cube_points
self.width = Width
self.height = Height
self.length = Length
self.start_x = start_x
self.start_y = start_y
self.start_z = start_z
def make_cuboid(self):

self.cube_points = [
[[-self.width + self.start_x], [- self.length + self.start_y],
[self.height + self.start_z]], # 0
[[self.width + self.start_x], [- self.length + self.start_y],
[self.height + self.start_z]], # 1
[[self.width + self.start_x], [ self.length + self.start_y],
[self.height + self.start_z]], # 2
[[-self.width + self.start_x], [ self.length + self.start_y],
[self.height + self.start_z]], # 3
[[-self.width + self.start_x], [- self.length + self.start_y], [-
self.height + self.start_z]], # 4
[[self.width + self.start_x], [- self.length + self.start_y], [-
self.height + self.start_z]], # 5
[[self.width + self.start_x], [ self.length + self.start_y], [-
self.height + self.start_z]], # 6
[[-self.width + self.start_x], [ self.length + self.start_y], [-
self.height + self.start_z]], # 7
]
def perspective_project(x, y, z, fov, viewer_distance):
factor = fov / (viewer_distance + z) if (viewer_distance + z) != 0 else 1
return x * factor, y * factor
cuboid = [cuboid_maker(CUBE_POINTS, 10, 10, 10, 0, 10, 0),
cuboid_maker(CUBE_POINTS, 1, 100, 100, 0, -10, 0)]
for cube in cuboid:
cube.make_cuboid()
OLD_MOUSE_POS = game_module.mouse.get_pos()

while True:
KEYS = game_module.key.get_pressed()
MOUSE_POS = game_module.mouse.get_pos()
for event in game_module.event.get():
if event.type == game_module.QUIT:
game_module.quit()
system.exit()

if KEYS[game_module.K_w]:
CAMERA["z"] += SPEED
if KEYS[game_module.K_s]:
CAMERA["z"] -= SPEED
if KEYS[game_module.K_a]:
CAMERA["x"] -= SPEED
if KEYS[game_module.K_d]:
CAMERA["x"] += SPEED
if KEYS[game_module.K_q]:
CAMERA["y"] -= SPEED
if KEYS[game_module.K_e]:
CAMERA["y"] += SPEED

if KEYS[game_module.K_LEFT]:
CAMERA["rotation_y"] -= Rotaion_angle
if KEYS[game_module.K_RIGHT]:
CAMERA["rotation_y"] += Rotaion_angle
if KEYS[game_module.K_UP]:
CAMERA["rotation_x"] -= Rotaion_angle
if KEYS[game_module.K_DOWN]:
CAMERA["rotation_x"] += Rotaion_angle
if OLD_MOUSE_POS != MOUSE_POS:
if OLD_MOUSE_POS[0] != MOUSE_POS[0]:
if OLD_MOUSE_POS[0] > MOUSE_POS[0]:
CAMERA["rotation_y"] -= Rotaion_angle/3
OLD_MOUSE_POS = MOUSE_POS
else:
CAMERA["rotation_y"] += Rotaion_angle/3
OLD_MOUSE_POS = MOUSE_POS
if OLD_MOUSE_POS[1] != MOUSE_POS[1]:
if OLD_MOUSE_POS[1] > MOUSE_POS[1]:
CAMERA["rotation_x"] += Rotaion_angle/3
OLD_MOUSE_POS = MOUSE_POS
else:
CAMERA["rotation_x"] -= Rotaion_angle/3
OLD_MOUSE_POS = MOUSE_POS
GAME_WINDOW.fill(BLACK)
rotation_x = [[1, 0, 0],
[0, cos(ANGLE_X), -sin(ANGLE_X)],
[0, sin(ANGLE_X), cos(ANGLE_X)]]

rotation_y = [[cos(ANGLE_Y), 0, sin(ANGLE_Y)],


[0, 1, 0],
[-sin(ANGLE_Y), 0, cos(ANGLE_Y)]]

rotation_z = [[cos(ANGLE_Z), -sin(ANGLE_Z), 0],


[sin(ANGLE_Z), cos(ANGLE_Z), 0],
[0, 0, 1]]
ANGLE_X = CAMERA['rotation_x']
ANGLE_Y = CAMERA['rotation_y']
ANGLE_Z = CAMERA['rotation_z']

for cube in range(len(cuboid)):


i = 0
for point in cuboid[cube].cube_points:
px, py, pz = point[0][0], point[1][0], point[2][0]

px -= CAMERA["x"]
py -= CAMERA["y"]
pz -= CAMERA["z"]
rotate_x = game_NP.dot(rotation_x, [[px], [py], [pz]])
rotate_y = game_NP.dot(rotation_y, rotate_x)
rotate_z = game_NP.dot(rotation_z, rotate_y)
resultent_point = game_NP.dot(PROJECTION_MATRIX, rotate_z)
rx = float(resultent_point[0][0])
ry = float(resultent_point[1][0])
rz = float(resultent_point[2][0])
x_proj, y_proj = perspective_project(rx, ry, rz, 500, 50)
x = x_proj * SCALE + WINDOW_SIZE/2
y = y_proj * SCALE + WINDOW_SIZE/2
POINTS[i] = (x, y)
i += 1
game_module.draw.circle(GAME_WINDOW, WHITE, (x, y), 1)
for i, j in CONNECTIONS:
connect_points(i, j, POINTS)
col = 0
for a, b, c, d in FACES:
connect_faces(a, b, c, d, POINTS, Colours[col])
col += 1
CLOCK.tick(FPS)
game_module.display.update()
this is whole of the project which includes the code and my essay underneath.

Understanding 3D Rendering and Its Computational


Demands
What is 3D Rendering?

3D rendering is the process of converting three-dimensional models into two-dimensional


images on a screen. This involves complex calculations to simulate lighting, shading, texture
mapping, and perspective to create a realistic or stylized image. The rendering process is
computationally intensive, requiring significant processing power, especially when aiming for
real-time rendering in gaming applications.

The Role of the ALU in 3D Rendering

The Arithmetic Logic Unit (ALU) is a critical component of the CPU responsible for performing
arithmetic and logical operations. In the context of 3D rendering, the ALU handles numerous
calculations, including:

 Matrix Multiplications: Used for transforming 3D coordinates during scaling, rotation,


and translation.
 Vector Operations: Essential for calculating normals, lighting, and shading.
 Trigonometric Functions: Required for rotations and perspective calculations.

The efficiency of the ALU directly impacts the speed and quality of 3D rendering, especially in
real-time applications like gaming.

Mathematical Foundations of 3D Rendering


Coordinate Systems and Transformations

In 3D graphics, objects are defined in a three-dimensional coordinate system. To render these


objects on a 2D screen, several transformations are applied:
1. Model Transformation: Positions the object in the world space.
2. View Transformation: Adjusts the scene based on the camera's position and orientation.
3. Projection Transformation: Projects the 3D scene onto a 2D plane.

These transformations are achieved using matrix operations, which are computationally handled
by the ALU.

Projection Techniques

Orthographic Projection

Orthographic projection involves projecting 3D objects onto a 2D plane without perspective


distortion. This means that objects retain their size regardless of depth, making it useful for
technical drawings and CAD applications. The transformation matrix for orthographic projection
simplifies to:

csharp
CopyEdit
[1 0 0 0]
[0 1 0 0]
[0 0 0 0]
[0 0 0 1]

This matrix effectively discards the z-coordinate, flattening the 3D scene onto a 2D plane.

Perspective Projection

Perspective projection simulates the way the human eye perceives the world, where objects
appear smaller as they are farther from the viewer. The transformation involves dividing the x
and y coordinates by the z-coordinate, introducing depth perception. The perspective projection
matrix is more complex and includes parameters like the field of view and aspect ratio.

Dissecting the Pygame-Based 3D Renderer


Your artifact utilizes Pygame to simulate a 3D rendering environment. Let's analyze its
components and understand how it mimics 3D rendering processes.

Initialization and Setup


import pygame as game_module
import sys as system
from math import *
import numpy as game_NP

game_module.init()
Here, Pygame is initialized, and essential modules are imported. math provides mathematical
functions, and numpy (aliased as game_NP) is used for efficient numerical computations,
particularly matrix operations.

Window and Display Configuration


WINDOW_SIZE = 600
GAME_WINDOW = game_module.display.set_mode((WINDOW_SIZE, WINDOW_SIZE))
CLOCK = game_module.time.Clock()
FPS = 30

A 600x600 window is created for rendering, and a clock is set to control the frame rate at 30
frames per second.

Defining Colors and Projection Parameters


WHITE = (255, 255, 255)
RED = (255, 0, 0,)
BLACK = (0, 0, 0)
Colours = [(255,127,80), (255,165,0), (255,215,0), (127,255,0), (175,238,238),
(245,245,220)]
SCALE = 2
Rotaion_angle = 0.1
ANGLE_X = ANGLE_Y = ANGLE_Z = 0

Colors are defined for rendering, and initial rotation angles are set. The SCALE factor adjusts the
size of the rendered objects on the screen.

Projection Matrix
PROJECTION_MATRIX = [[1, 0, 0],
[0, 1, 0],
[0, 0, 0]]

This matrix represents an orthographic projection, effectively ignoring the z-coordinate and
projecting the 3D points onto the 2D plane.

Defining the Cube


CUBE_POINTS = [n for n in range(8)]
CUBE_POINTS[0] = [[-1], [-1], [1]]
...
CUBE_POINTS[7] = [[-1], [1], [-1]]

Eight points define the vertices of a cube in 3D space. Each point is a column vector representing
x, y, and z coordinates.

Connections and Faces


CONNECTIONS = [
(0, 1), (0, 3), (0, 4),
...
]
FACES = [
(0, 1, 2, 3), # Front
...
]

CONNECTIONS define the edges between vertices, and FACES define the surfaces of the cube, each
consisting of four vertices.

Camera Configuration
CAMERA = {
"x": 0,
"y": 100,
"z": 100,
"rotation_x": 0.1,
"rotation_y": 0,
"rotation_z": 0,
}

The camera is positioned in 3D space, and its orientation is defined by rotation angles around the
x, y, and z axes.

Creating Cuboids
class cuboid_maker:
def __init__(self, cube_points, Height, Width, Length, start_x, start_y,
start_z):
...
def make_cuboid(self):
...

This class generates cuboids by scaling and translating the base cube points. It allows for
creating multiple cuboids with different dimensions and positions.

Perspective Projection Function


def perspective_project(x, y, z, fov, viewer_distance):
factor = fov / (viewer_distance + z) if (viewer_distance + z) != 0 else 1
return x * factor, y * factor

This function applies a simple perspective projection by scaling the x and y coordinates based on
their distance from the viewer, introducing depth perception.

Main Loop and Event Handling


while True:
KEYS = game_module.key.get_pressed()
MOUSE_POS = game_module.mouse.get_pos()
...

The main loop handles user input for camera movement and rotation. It processes keyboard and
mouse events to adjust the camera's position and orientation.

Rendering Process

GAME_WINDOW.fill(BLACK)
...
for cube in range(len(cuboid)):
...
for point in cuboid[cube].cube_points:
...
rotate_x = game_NP.dot(rotation_x, [[px], [py], [pz]])
...
x_proj, y_proj = perspective_project(rx, ry, rz, 500, 50)
...
game_module.draw.circle(GAME_WINDOW, WHITE, (x, y), 1)
...
for i, j in CONNECTIONS:
connect_points(i, j, POINTS)
...
for a, b, c, d in FACES:
connect_faces(a, b, c, d, POINTS, Colours[col])

Each frame, the screen is cleared, and the cuboids are rendered. Points are transformed using
rotation matrices, projected onto 2D space, and drawn. Edges and faces are then rendered to
complete the visualization.

ALU Performance Analysis


The rendering process involves numerous mathematical operations:

 Matrix Multiplications: For rotating and projecting points.


 Trigonometric Calculations: For determining rotation angles.
 Vector Arithmetic: For translating and scaling objects.

These operations are handled by the ALU, and their efficiency directly affects rendering
performance. By analyzing the frame rate and responsiveness of the application, one can infer
the ALU's performance under different computational loads.
The initial spike shows the load the project at minimum running requirements takes on the computer as
the 3rd graph shows the alu the drasticly increased in calculations due to the heavy load of the threads
increased by the interdimensional calculatins done in a matter of seconds.

You might also like