Let's code 3D Engine in Python from Scratch

Let's code 3D Engine in Python from Scratch

Introduction to 3D Graphics with Python

In this video, the basics of creating 3D graphics are covered. The viewer will learn how to create three-dimensional objects, write a simple software engine to load and display real 3D models, move and rotate them in 3D space using the Python language, Pygame library, and Numpy module.

Setting up the Application

  • Install necessary modules: Pygame and Numpy.
  • Write a template for the application as a class that defines standard objects for Pi games such as window resolution surface for drawing.
  • Write two methods in the class: one for rendering and painting the surface in desired color; another for main program loop where we call method for drawing future objects.

Understanding 3D Graphics

  • Objects in space are defined by points called object vertices which have corresponding coordinates. Vertices are connected along given faces.
  • Any object has its own local coordinate system. Movement and rotation mean moving local system of object to position needed in world system coordinates.
  • Main actions with 3D objects are moving, rotating, scaling (stretching), and shifting. Almost any change in vertex is carried out by multiplying vertices of object by matrix designed for specific action.

Creating Objects

  • Create a new file and add matrices to it in number of functions that will form necessary matrix depending on input parameters.
  • Create a class that interacts with main program. Add one more method for creating objects.
  • Our first object will be a 3D cube. Set numbering of vertices so we can correctly build faces of cube. Determine coordinates of these vertices in numpy array.

Understanding Camera and Projection Matrices

In this section, the speaker explains how to project a three-dimensional image onto a flat screen using view frustum with the near and far clipping planes of space. They also discuss camera parameters, camera coordinate system, and projection matrix.

Camera Coordinate System

  • The camera coordinate system is characterized by the position of the camera in the world system and its orientation.
  • To get into the camera coordinate system, we need to move the world so that the camera position coincides with the origin of the world coordinate system and then rotate the camera so that both orientations coincide.
  • We can transfer vertices of an object to camera space using translation and rotation matrices from previous steps.

Projection Matrix

  • To move from camera space to clip space, we need to form a projection matrix or clip matrix based on mathematics arising from consideration of plane onto which image must be projected.
  • A simple class in projection file will have attributes taken from an instance of a camera class for formation of projection matrix.
  • Vertices are transferred to clip space using multiplication with projection matrix. After multiplication, it becomes necessary to normalize values of vertices by dividing value of coordinates by fourth coordinate.

Displaying Object on Screen

  • Coordinates are normalized in clipping space before being displayed on screen.
  • We iterate over all faces of object and decide whether or not to draw face based on those cut off vertices that have taken zero value after multiplication with display matrix.

Creating a 3D Cube and Adding Movement

In this section, the speaker explains how to create a 3D cube using a general drawing method. They also explain how to add movement to the cube by importing a camera and projection, setting their positions, and defining keys for moving along all three axes of the world coordinate system.

Creating a 3D Cube

  • To create a 3D cube, draw the object through a more general drawing method.
  • Import a camera and projection in the main file.
  • Create an instance of the camera class and set it to some position.
  • Make an instance of the projection class and suggest moving our object a little and rotating it for example by 30 degrees around the y-axis.
  • Call the function of drawing it from the object.

Adding Movement to the Cube

  • Define keys for moving along all three axes of the world coordinate system.
  • Multiply required orientation vector by speed of movement to shift camera position.
  • Add ability to rotate camera by writing rotation functions of orientation vectors multiplied by previously calculated rotation matrix for desired axis.
  • Assign keys to call these functions when pressing left, right, up or down keys.

Clipping Space & Object Movement

In this section, we learn about vertex clipping when objects become larger than screen size. The speaker suggests increasing clipping space so that we can get closer to objects. They also explain how to make objects move around their own axis.

Vertex Clipping & Increasing Clipping Space

  • When an object becomes larger than screen size, vertices are cut off beyond visible area.
  • Increase clipping space two times larger so that we can get closer to objects.

Making Objects Move Around Their Own Axis

  • Write function for object movement (e.g., around y-axis).
  • Call function from general drawing method.

Adding Objects to the Scene

In this section, we learn how to add objects to the scene and create a more interesting scene in the form of coordinate axes. The speaker suggests adding some attributes in the form of a font, defining a color for faces, adding a trigger to allow movement, displaying vertices in an inscription for the object, and redefining coordinates of vertices and faces.

Adding Objects to the Scene

  • Make local coordinate system as if center of cube was at beginning of this system.
  • Add world coordinate system with ban on movement and increase it by two and a half times.
  • Call drawing methods for new objects.

Creating More Interesting Scene

  • Add attributes such as font and color for faces.
  • Add trigger to allow movement.
  • Display vertices in an inscription for object.
  • Redefine coordinates of vertices and faces.

Creating a 3D Software Engine for Displaying 3D Models in OBJ Format

In this section, the speaker explains how to create a 3D software engine for displaying 3D models in OBJ format.

Converting Vertices and Faces into Homogeneous Coordinates

  • Use the simplest methods of working with strings to add one to the coordinates of the vertices to convert them into homogeneous coordinates.
  • For faces, take into account that the numbering of the face starts from one so subtract one from its number.
  • Pass the lists of faces and vertices to create and return an instance of the object class.

Creating Two-Dimensional Numpy Arrays

  • Create full-fledged two-dimensional numpy arrays from these lists.
  • Reduce the size of the vertex in the polygon line.

Speeding Up Numpy Function Using Just-In-Time Compiler

  • The numpy any function is a bottleneck in this project.
  • Use just-in-time compiler (JIT) to speed up this function by converting python code to fast machine code using convenient decorators.
  • Use ng decorator with fast calculation options to speed up numpy function.
  • Make a replacement where necessary.

Turning Off Rendering of Vertices

  • Suggest turning off rendering of vertices since with a large number of them, objects are poorly visible.

Results

-: The number of frames increased by more than three times.

-: A 3D software engine for displaying 3D models in OBJ format was created.

Conclusion: The speaker explains how to create a 3D software engine for displaying 3D models in OBJ format by converting vertices and faces into homogeneous coordinates, creating two-dimensional numpy arrays, speeding up the numpy function using just-in-time compiler, and turning off rendering of vertices.