GoTracer
A Go implementation of Ray Tracing in One Weekend by Peter Shirley.
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
- 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
- Prepare
agents.json
file with list of all agents
[
"localhost:9190",
"localhost:9191",
"localhost:9192"
]
- Install and run master
go get github.com/DheerendraRathor/GoTracer/net/master
master --spec=/path/to/spec.json --agents=/path/to/agents.json
- 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