Skip to content
Garrett Fairburn edited this page Aug 31, 2019 · 1 revision

Why did you make this?

I never really knew a lot about 3D rendering, and that bothered me. As a result, I started studying the process. After close to a year of planning and development, this is what I have to show for it.

Why aren't you using any external libraries?

The main reason I started developing this engine was to help me learn and understand the process of 3D rendering. I thought I'd learn the best if I force myself to make it from scratch.

How does it work?

I'll explain how it works by describing the phases of its rendering pipeline. Do realize that I use the term "rendering pipeline" very loosely because the engine doesn't conform to any pipeline standards. I've broken the pipeline down into three stages and two sync steps between the stages. Each stage does as much parallelizable work as it can at that moment in the pipeline. Each sync step handles necessary, non-parallelizable work between stages such as data decoupling.

  • STAGE 1 Transform vertices from model space to clip space. Transform sprites from model space to NDC space. Perform frustum culling on sprites.

  • SYNC 1 Share vertex data with polygon data. Drop culled sprites from pipeline.

  • STAGE 2 Perform backface and frustum culling on polygons. Transform polygons from clip space to NDC space.

  • SYNC 2 Restructure polygon data. Share polygon and sprite data with fragment data.

  • STAGE 3 Rasterize fragments.

Why does it run so poorly?

Partially because Python, as a programming language, isn't designed for this type of processing, but mostly because I'm inexperienced at graphics programming. I've likely made plenty of mistakes throughout the engine that slow it down.

Are there any ways to improve performance?

Yes, there are multiple ways!

  • The best option would be to use the PyPy3 python implementation instead of CPython3. If you do take that route, be sure not to compile extensions, and don't use any rendering workers (i.e. use num_workers=0 in the constructor for rendascii.interface.Engine).

  • Alternatively, if you want to stick with CPython3, use as many rendering workers as you have physical cores in your CPU. I have yet to test the engine's multiprocessing capabilities on a CPU with virtual cores, but I suspect only physical cores will speed up rendering. Furthermore, be certain that you do compile the accelerator extensions.

Does it support texture mapping?

No, unfortunately. I would love to add texture mapping to the engine, but I don't fully understand the process quite yet. Once I do learn how texture mapping works, I plan to add it in!