A high-performance 3D software renderer implemented in Python, optimized with NumPy and Numba JIT compilation.
Pixerise is a Python 3D rendering engine that focuses on CPU-based rendering, making it ideal for educational purposes, embedded systems, and applications where GPU acceleration is not available or desired.
- Multiple shading modes (Wireframe, Flat, Gouraud)
- View frustum culling with bounding spheres
- Backface culling for performance optimization
- Directional lighting with ambient and diffuse components
- Efficient batch processing of vertices and normals
- NumPy-accelerated array operations for fast geometry processing
- JIT-compiled core rendering functions using Numba
- Optimized batch transformations of vertices and normals
- Efficient memory layout with contiguous arrays
- Early culling of invisible geometry
- Agnostic rendering buffer system compatible with any display library
- No direct dependencies on specific media or rendering libraries
- Clean separation between rendering and display logic
- Example integrations with popular libraries (e.g., Pygame)
- Complete scene graph system
- Support for model instancing
- Hierarchical transformations
- Flexible camera controls
- Material and lighting properties
PDM is required to manage project dependencies. Here's how to install it on different platforms:
Using pip:
pip install pdm
Or using winget:
winget install pdm
Using Homebrew:
brew install pdm
Or using pip:
pip install pdm
Using pip:
pip install pdm
Or on Ubuntu/Debian:
curl -sSL https://pdm.fming.dev/install-pdm.py | python3 -
Clone the repository and install dependencies:
git clone https://github.com/enricostara/pixerise.git
cd pixerise
pdm install
import pygame
from pixerise import Canvas, ViewPort, Renderer
from scene import Scene
# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Pixerise Quick Start")
# Initialize rendering components
canvas = Canvas((800, 600))
viewport = ViewPort((1.6, 1.2), 1, canvas)
renderer = Renderer(canvas, viewport)
# Define scene structure
scene_dict = {
'camera': {
'transform': {
'translation': [0, 0, -3],
'rotation': [0, 0, 0]
}
},
"models": {
"triangle": {
"vertices": [
[0, 1, 0], # top vertex
[-0.866, -0.5, 0], # bottom left vertex
[0.866, -0.5, 0] # bottom right vertex
],
"triangles": [[0,1,2]]
}
},
"instances": [
{
"model": "triangle",
"name": "a_triangle",
"color": [0, 255, 0],
'transform': {
'translation': [0, 0, 0],
'rotation': [0, 0, 0],
'scale': [1, 1, 1]
}
}
]
}
# Create scene from dictionary
scene = Scene.from_dict(scene_dict)
# Main loop
running = True
clock = pygame.time.Clock()
while running:
clock.tick(60) # Limit to 60 FPS
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
# Update triangle rotation
scene.get_instance("a_triangle").rotation -= [0, 0, .01]
# Render the scene
renderer.render(scene)
# Display the rendered image
surf = pygame.surfarray.make_surface(canvas.color_buffer)
screen.blit(surf, (0, 0))
pygame.display.update()
pygame.quit()
The examples
directory contains several demonstrations:
rendering_wireframe.py
: Basic wireframe rendering with interactive camerarendering_flat_shading.py
: Flat shading with directional lightingrendering_gouraud_shading.py
: Smooth shading using vertex normalsrendering_obj_file.py
: Loading and rendering 3D models from an OBJ file with interactive controls
Run the tank example using:
pdm run python examples/rendering_obj_file.py
Each example demonstrates different features of the engine and includes interactive controls:
- WASD: Move camera position
- Mouse: Look around
- Mouse wheel: Move forward/backward
- Q/E: Move up/down
- Space: Toggle between shading modes (where available)
- Esc: Exit
- Educational projects learning 3D graphics fundamentals
- Embedded systems without GPU access
- Cross-platform applications requiring consistent rendering
- Custom 3D visualization tools
- Projects requiring full control over the rendering pipeline
- Applications requiring real-time GPU acceleration
- Complex 3D applications needing advanced graphics features
pdm run pytest
We welcome contributions! Here's how you can help:
- Open an issue first to discuss your proposed changes
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'feat: add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This way we can ensure your contribution aligns with the project's goals and avoid duplicate efforts.
Special thanks to:
- Gabriel Gambetta and his amazing book Computer Graphics from Scratch, which inspired many of the rendering techniques used in this project
- Windsurf, the excellent agentic IDE that made this project feasible in a few months by working after dinner
- The NumPy and Numba teams for their awesome libraries
Future enhancements may include:
- More shading models
- Texturing support
- Scene serialization
- Additional example scenes