Skip to main content

A high-performance 3D software renderer implemented in Python, optimized with NumPy and Numba JIT compilation.

Project description

Pixerise

A high-performance 3D software renderer implemented in Python, optimized with NumPy and Numba JIT compilation.

Tank Model Rendering Demo

Overview

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.

Features

Core Rendering

  • 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
  • Ray casting for precise 3D object selection

Performance

  • 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

Integration

  • 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)

Scene Management

  • Complete scene graph system
  • Support for model instancing
  • Hierarchical transformations
  • Flexible camera controls
  • Material and lighting properties

Installation

1. Install from PyPI (for end users)

For users who just want to use Pixerise and install it as a dependency:

# Using pip
pip install pixerise

# Using uv
uv add pixerise

2. Install from Source (for development)

To contribute to Pixerise or modify its source code:

1. Install PDM (Python Dependency Manager):

Windows
powershell -ExecutionPolicy ByPass -c "irm https://pdm-project.org/install-pdm.py | py -"
Linux/Mac
curl -sSL https://pdm-project.org/install-pdm.py | python3 -
All (using pip)
pip install pdm

2. Install Pixerise:

Clone the repository and install dependencies:

git clone https://github.com/enricostara/pixerise.git
cd pixerise
pdm install

Quick Start

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()

For detailed API documentation, see src/README.md.

Examples

The examples directory contains several demonstrations:

Ray Casting Selection Demo

  • rendering_wireframe.py: Basic wireframe rendering with interactive camera
  • rendering_flat_shading.py: Flat shading with directional lighting
  • rendering_gouraud_shading.py: Smooth shading using vertex normals
  • rendering_obj_file.py: Loading and rendering 3D models from an OBJ file with interactive controls
    • Left click: Select and highlight objects using ray casting
    • Right click: Toggle group visibility

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)
  • Backspace: Toggle mouse grab mode (to click and highlight objects using ray casting)
  • Esc: Quit the example

Who Should Use Pixerise?

Ideal For:

  • 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

Not Recommended For:

  • Applications requiring real-time GPU acceleration
  • Complex 3D applications needing advanced graphics features

Architecture

graph TD
    subgraph Scene Management
        Scene[Scene Container]
        Model[Model<br/>Reusable Geometry]
        Instance[Instance<br/>Model Occurrences]
        Camera[Camera<br/>Viewpoint]
        Light[DirectionalLight<br/>Scene Lighting]
        
        Scene --> Model
        Scene --> Instance
        Scene --> Camera
        Scene --> Light
        Model --> Instance
    end

    subgraph Core Components
        Canvas[Canvas<br/>2D Drawing Surface]
        ViewPort[ViewPort<br/>View Frustum]
        Renderer[Renderer<br/>Main Pipeline]
        
        Canvas --> Renderer
        ViewPort --> Renderer
    end

    subgraph Renderer Pipeline
        Shading[Shading Modes]
        Culling[Face Culling]
        Lighting[Lighting System]
        Transform[Coordinate<br/>Transforms]
        
        Renderer --> Shading
        Renderer --> Culling
        Renderer --> Lighting
        Renderer --> Transform
    end

    subgraph Optimization
        NumPy[NumPy Arrays<br/>Memory Layout]
        Numba[Numba JIT<br/>@njit + cache]
        
        NumPy --> Renderer
        Numba --> Renderer
    end

    Scene --> Renderer

Development

Running Tests

pdm run pytest

Contributing

We welcome contributions! Here's how you can help:

  1. Open an issue first to discuss your proposed changes
  2. Fork the repository
  3. Create your feature branch (git checkout -b feature/amazing-feature)
  4. Commit your changes (git commit -m 'feat: add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

This way we can ensure your contribution aligns with the project's goals and avoid duplicate efforts.

License

MIT License

Acknowledgments

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pixerise-0.12.2.tar.gz (55.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pixerise-0.12.2-py3-none-any.whl (43.9 kB view details)

Uploaded Python 3

File details

Details for the file pixerise-0.12.2.tar.gz.

File metadata

  • Download URL: pixerise-0.12.2.tar.gz
  • Upload date:
  • Size: 55.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.22.3 CPython/3.12.9 Darwin/24.3.0

File hashes

Hashes for pixerise-0.12.2.tar.gz
Algorithm Hash digest
SHA256 01277c293be1ad6ead00e20898f110f839c636c1efea9044a9532b44ad9dfaf2
MD5 0055d0ee125cdd25dd0fb600188769e2
BLAKE2b-256 33f5c1f0557599cd12e214270e53b71e9262a5d2faf3e16d6aee9a935690585b

See more details on using hashes here.

File details

Details for the file pixerise-0.12.2-py3-none-any.whl.

File metadata

  • Download URL: pixerise-0.12.2-py3-none-any.whl
  • Upload date:
  • Size: 43.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.22.3 CPython/3.12.9 Darwin/24.3.0

File hashes

Hashes for pixerise-0.12.2-py3-none-any.whl
Algorithm Hash digest
SHA256 99e4788c13e5aae4beca6bff5e4036681a358442652286ca6b0e4c319bcad1c3
MD5 a4342cc3474ad2b53e2eaca58c73e4ac
BLAKE2b-256 33b389c9d9c44504b702a2709f3069be1c4aade594510a6442c4f52284dfd5bc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page