A distributed Go implementation of Ray Tracing in One Weekend by Peter Shirley
Go
Switch branches/tags
Nothing to show
Clone or download

README.md

GoTracer

A Go implementation of Ray Tracing in One Weekend by Peter Shirley.

Five Spheres

Features:

  • Provides a library and executable to trace a bunch of spheres with Matte, Metal and transparent surfaces.
  • Provides a framework to ray trace a bunch or spheres on a distributed systems controlled by master/agent configuration

Usages

Prepare rendering spec as per Tracing Specification

Basic

go get github.com/DheerendraRathor/GoTracer

goTracer --spec=/path/to/spec.json

On distributed Systems

  1. Install and run ray tracing agent on all machines
go get github.com/DheerendraRathor/GoTracer/net/agent

# Provide an addr where agent will listen. Address (including port) must be visible to master
agent --addr=0.0.0.0:1233
  1. Prepare agents.json file with list of all agents
[
  "localhost:9190",
  "localhost:9191",
  "localhost:9192"
]
  1. Install and run master
go get github.com/DheerendraRathor/GoTracer/net/master

master --spec=/path/to/spec.json --agents=/path/to/agents.json
  1. Sit back and relax while image is being rendered :)

As library

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"

	"github.com/DheerendraRathor/GoTracer/models"
	"github.com/DheerendraRathor/GoTracer/tracer"
)

func main() {

	file, e := ioutil.ReadFile("mySpecFile.json")
	if e != nil {
		panic(fmt.Sprintf("File error: %v\n", e))
	}

	var env models.World
	json.Unmarshal(file, &env)

	/*
		This channel is used to track progress of ray tracing. If env.Settings.ShowProgress is set to true.
		On each pixel traced a `false` value is pushed to progress channel. And once all pixel are processed a `true` value is pushed into channel.

		It is responsibility of caller to create sufficiently large buffered channel and read it responsibly if env.Settings.ShowProgress is true.
		Otherwise program might hang.
	*/
	progress := make(chan *models.Pixel, 100)
	closeChan := make(chan bool)
	defer close(progress)

	go goTracer.GoTrace(&env, progress, closeChan)

	go func() {
		for pixel := range progress {
			if pixel == nil {
				// Rendering complete
				return
			}
			// Do processing with pixel here.
			// Want to generate JPEG? GIF? Real time rendering on UI? Show weird looking progress bar? Your call. You've the pixels now
		}
	}()

	// To stop rendering in middle, just pass a value to closeChan.
	// GoTracer does a non-blocking check on closeChan before rendering a pixel. If channel has a value, it will stop rendering and send nil to
	// progress channel.
	// Caveat: Existing goroutines for other pixel will continue to run.

}

Tracing Specification

This program takes a JSON specification of environment to be traced. Currently only spheres are supported.

{
  "Settings": {
    "ShowProgress": true,
    "RenderRoutines": -1,
    "RenderDepth": 10
  },
  "Image": {
    "OutputFile": "./out/renderedImage.png",
    "Width": 400,
    "Height": 200,
    "Samples": 10,
    "Patch": [0, 200, 0, 400]
  },
  "Camera": {
    "LookFrom": [-2, 1, 0.5],
    "LookAt": [0, 0, -1],
    "UpVector": [0, 1, 0],
    "FieldOfView": 45,
    "AspectRatio": 2,
    "Focus": 2.69,
    "Aperture": 0.04
  },
  "Objects": {
    "Spheres": [
      {
        "Center": [0, 0, -1],
        "Radius": 0.5,
        "Surface": {
          "Type": "Lambertian",
          "Albedo": [0.8, 0.1, 0.1],
          "Fuzz": 0.1,
          "RefIndex": 1.3
        }
      }
    ]
  }
}
Field type Details
Settings ShowProgress boolean Show a progress bar while Image is being rendered
RenderRoutines integer Number of goroutines for ray tracing. If value is less than zero then runtime.NumCPU() is taken
RenderDepth integer Number of recursion for a ray after hitting an object
Image OutputFile string Path of file where rendered image should be saved. Rendered image is PNG
Width integer Width of Rendered Image
Height integer Height of Rendered Image
Samples integer Number of samples per pixel
Patch list[int][4] Defines specific patch of image to be rendered. Patch is defined as [x0, y0, x1, y1] and all points (x, y) are considered given that x0 ≤ x < x1 and y0 ≤ y < y1
Camera LookFrom list[float][3] Coordinates of camera lens
LookAt list[float][3] Coordinate of point where camera is pointed.
UpVector list[float][3] Point defining direction of up direction for camera
FieldOfView float Camera field of views in degrees
AspectRatio float Ratio of height and width of camera image plane
Focus float Focal length of camera. This and Aperture are used for creation of depth of field effect
Aperture float Camera aperture diameter
Objects Spheres List[Sphere] List of spheres in world to be rendered
Sphere Center list[float][3] Center of sphere
Radius float Radius of sphere
Surface Material Material description of Sphere
Material Type string Type of Material. Must be from Lambertian, Metal, Dielectric
Albedo list[float][3] Albedo of Material
Fuzz float Fuzziness in reflection for Metal surfaces. Should be in range [0.0, 1)
RefIndex float Refractive index for Dielectric surfaces.

Note: list[x][n] => list of elements of type x with size n