A Go implementation of Ray Tracing in One Weekend by Peter Shirley.
- 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
Prepare rendering spec as per Tracing Specification
go get github.com/DheerendraRathor/GoTracer
goTracer --spec=/path/to/spec.json
- 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 :)
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.
}
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