Skip to content

plainprince/pathtracer

Repository files navigation

Vulkan Pathtracer

A high-performance pathtracer using Vulkan compute shaders with JSON scene support and GLB import tools.

Quick Start

# Build the project
./build.sh

# Render a scene
./pathtracer demo

# Render with custom settings
./pathtracer demo --width 1920 --height 1080 --samples 200 --bounces 16

Scene System

Rendering Scenes

The pathtracer uses a scene-based workflow:

# Render scene by name (looks in scenes/ directory)
./pathtracer <scene-name> [options]

# Examples:
./pathtracer demo                          # Render scenes/demo.json -> renders/demo.png
./pathtracer my-scene --samples 500       # High quality render
./pathtracer simple --width 800 --height 600

Arguments:

  • scene-name: Name of scene file (without .json extension)
  • --width <int>: Override image width
  • --height <int>: Override image height
  • --samples <int>: Override samples per pixel
  • --bounces <int>: Override maximum ray bounces

Output: Images are saved to renders/<scene-name>.{png,ppm}

Scene Format

Scenes are defined in JSON format in the scenes/ directory. The format includes camera, sky, render settings, materials, and geometry:

{
  "camera": {
    "position": [0, 1, 3],
    "pitch": -10,
    "yaw": 180,
    "fov": 45
  },
  "sky": {
    "color": [0.5, 0.7, 1.0],
    "brightness": 1.0
  },
  "render": {
    "width": 800,
    "height": 600,
    "samples": 200,
    "bounces": 12
  },
  "materials": [
    {
      "name": "red_diffuse",
      "color": [0.9, 0.1, 0.1],
      "emission": [0, 0, 0],
      "roughness": 1.0,
      "metallic": 0.0
    },
    {
      "name": "chrome_metal", 
      "color": [0.98, 0.98, 0.98],
      "emission": [0, 0, 0],
      "roughness": 0.0,
      "metallic": 1.0
    },
    {
      "name": "light_source",
      "color": [1.0, 1.0, 1.0],
      "emission": [25, 20, 5],
      "roughness": 0.0,
      "metallic": 0.0
    }
  ],
  "spheres": [
    {
      "center": [0, 0, -1],
      "radius": 0.5,
      "material": 0,
      "name": "red_sphere"
    }
  ],
  "triangles": [
    {
      "vertices": [
        [-0.5, 0.5, -2],
        [0.5, 0.5, -2], 
        [0, 1, -2]
      ],
      "material": 1,
      "name": "metal_triangle"
    }
  ]
}

Camera Properties

  • position: Camera position in world space
  • pitch: Up/down rotation in degrees (negative = look down)
  • yaw: Left/right rotation in degrees (0=+X, 90=+Z, 180=-X, 270=-Z)
  • fov: Vertical field of view in degrees

Sky Properties

  • color: Sky background color (RGB 0-1)
  • brightness: Sky brightness multiplier

Render Properties

  • width, height: Output image resolution
  • samples: Samples per pixel (higher = less noise)
  • bounces: Maximum ray bounces (higher = more realistic lighting)

Note: Command-line arguments override scene render settings.

Available Scenes

  • demo - Full feature demo (800x600, 200 samples)
  • simple - Fast test scene (400x300, 50 samples)
  • hd-demo - High quality scene (1920x1080, 1000 samples)

GLB Import Tool

Convert GLB files to pathtracer scenes with full geometry and material extraction:

# Convert GLB to scene (run from main directory)
./convert-glb.sh model.glb my-scene

# Examples
./convert-glb.sh assets/car.glb car-scene
./convert-glb.sh downloads/house.glb house-scene

This creates scenes/my-scene.json with:

  • Extracted geometry: All triangles from GLB meshes
  • Extracted materials: PBR materials converted to pathtracer format
  • Optimal camera: Automatically positioned to view the model
  • Smart scaling: Ground plane and lighting sized to model
  • Full metadata: Model bounds, triangle count, material info

What Gets Extracted

  • Meshes: All triangle geometry (indexed and non-indexed)
  • Materials: Base color, metallic, roughness, emission (scaled for pathtracer)
  • Bounds: Automatic model sizing and camera positioning
  • Naming: Preserves mesh and material names from GLB

Dependencies

The converter uses gltf-transform for robust GLB parsing:

  • First run automatically installs dependencies via npm install
  • Supports both .glb (binary) and .gltf (text) formats
  • Handles complex meshes with multiple materials

Material System

Material Properties

  • color: Base albedo color (RGB 0-1)
  • emission: Light emission (RGB, values > 1 for bright lights)
  • roughness: Surface roughness (0=mirror, 1=diffuse)
  • metallic: Metallic behavior (0=dielectric, 1=metal)

Material Examples

// Diffuse materials
{"color": [0.9, 0.1, 0.1], "emission": [0,0,0], "roughness": 1.0, "metallic": 0.0}

// Metals (low roughness, high metallic)
{"color": [0.98, 0.98, 0.98], "emission": [0,0,0], "roughness": 0.05, "metallic": 1.0}

// Lights (emission > 0)
{"color": [1,1,1], "emission": [25, 20, 5], "roughness": 0.0, "metallic": 0.0}

// Rough metals 
{"color": [0.8, 0.6, 0.3], "emission": [0,0,0], "roughness": 0.3, "metallic": 0.9}

Build System

# Build and move executable to root
./build.sh

# Manual build (optional)
mkdir -p build && cd build
cmake ..
make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu)

Requirements

  • Vulkan SDK (1.3+)
  • GLFW 3.3+
  • CMake 3.16+
  • C++17 compiler

macOS: brew install vulkan-sdk glfw cmake
Ubuntu: apt install vulkan-sdk libglfw3-dev cmake build-essential

Performance

Typical render times on Apple Silicon:

  • 400x300, 50 samples: ~25ms
  • 800x600, 200 samples: ~145ms
  • 1920x1080, 1000 samples: ~2-5s

Architecture

pathtracer/
├── pathtracer              # Main executable
├── build.sh                # Build script
├── scenes/                 # Scene definitions (.json)
├── renders/                # Output images (.png/.ppm)  
├── tools/                  # GLB converter utilities
├── src/                    # C++ source code
├── shaders/                # GLSL compute shaders
└── shaders_build/          # Compiled SPIR-V shaders

About

Path tracer written in C++ and Vulkan.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors