gotrace

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2020 License: GPL-3.0 Imports: 14 Imported by: 0

README

gotrace

gotrace is a Golang implementation of Peter Shirley's excellent books on raytracing.

I used it as a way to better understand Go interfaces. Being more familiar with object-oriented languages, I wondered how polymorphism behaviour could be implemented without inheritance. Turns out it is pretty awesome !

render of the second book cover render of the first book cover

Pros

  • Strong concurrency primitives. Using weighted semaphores is a very intuitive way to create a workgroup.
  • Interfaces feels like more natural way to provide polymorphism behaviour at runtime, compared to inheritance.
  • Awesome self-documentation

Cons

  • No operator overloading
corner := lookFrom.Sub(u.Scale(width * focusDist)).Sub(v.Scale(height * focusDist)).Sub(w.Scale(focusDist))

would have been clearer as

corner := lookfrom - u*width*focusDist - v*height*focusDist - w*focusDist
  • No forward declarations

Actor needs to know about Shape, Material and Ray, but Shape also has to know about Ray, so they can't live in different packages without having to add unecessary complexity, because Go doesn't support forward declarations and can't resolve "circular" dependencies.

Credits

Documentation

Overview

Package gotrace is a simple raytracer inspired by Peter Shirley's books.

package main

import "github.com/teobouvard/gotrace"

func main() {
  scene := gotrace.BookScene()
  scene.Render(400, -1, 500, 50)
}

Index

Constants

This section is empty.

Variables

View Source
var (
	BLACK = Vec3{0, 0, 0}
	WHITE = Vec3{1, 1, 1}
	RED   = Vec3{1, 0, 0}
	GREEN = Vec3{0, 1, 0}
	BLUE  = Vec3{0, 0, 1}
)

Colors

Functions

This section is empty.

Types

type Actor

type Actor struct {
	// contains filtered or unexported fields
}

Actor is an object on the scene having a shape and a material

func (Actor) Bound

func (a Actor) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of an actor, which is defined by its shape

func (Actor) Hit

func (a Actor) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit checks if the geometry is hit by the ray, and creates a HitRecord with the actor's material

type Bbox

type Bbox struct {
	Min Vec3
	Max Vec3
}

Bbox is a bounding box of a geometry

func (Bbox) Hit

func (b Bbox) Hit(ray Ray, tMin float64, tMax float64) bool

Hit computes the if the intersection of a ray with a bounding box exists

func (Bbox) Merge

func (b Bbox) Merge(o Bbox) Bbox

Merge returns the union of two bounding boxes

type Box added in v0.2.0

type Box struct {
	// contains filtered or unexported fields
}

Box is a cube

func NewBox added in v0.2.0

func NewBox(p0, p1 Vec3) Box

NewBox constructs a box from its extreme points

func (Box) Bound added in v0.2.0

func (b Box) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of the Box

func (Box) Hit added in v0.2.0

func (b Box) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geometry interface for a Box

type Camera

type Camera struct {
	AspectRatio float64
	// contains filtered or unexported fields
}

A Camera is the eye through which the the scene is observed

func NewCamera

func NewCamera(lookFrom, lookAt, up Vec3, verticalFOV, aspectRatio, aperture, focusDist, tStart, tStop float64) Camera

NewCamera creates a camera

func (Camera) RayTo

func (c Camera) RayTo(s float64, t float64, rnd *rand.Rand) Ray

RayTo casts a Ray from the camera to the given (u, v) coordinates the Ray is cast at a random time during the camera lens' opening

type CheckerTexture

type CheckerTexture struct {
	// contains filtered or unexported fields
}

CheckerTexture is a checkboard-like texture

func (CheckerTexture) Value

func (t CheckerTexture) Value(u, v float64, pos Vec3) Vec3

Value implements the texture interface for a CheckerTexture

type Collection

type Collection []Actor

A Collection is a group of Actors

func (*Collection) Add

func (c *Collection) Add(actors ...Actor)

Add appends new Actors to the collection

func (Collection) Bound

func (c Collection) Bound(tMin float64, tMax float64) (bool, *Bbox)

Bound computes the bounding box of a Collection

func (Collection) Comparator

func (c Collection) Comparator(startTime, endTime float64, axis int) func(i, j int) bool

Comparator returns a comparison function of objects in the collection along the given axis. Used for Index sorting.

func (Collection) Hit

func (c Collection) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit returns the closest intersection of a Ray with a Collection if such an intersection exists, otherwise it returns false with a nil pointer

type ConstantTexture

type ConstantTexture struct {
	// contains filtered or unexported fields
}

ConstantTexture is a uniform texture with a single color

func (ConstantTexture) Value

func (t ConstantTexture) Value(u, v float64, pos Vec3) Vec3

Value implements the texture interface for a ConstantTexture

type Dielectric

type Dielectric struct {
	// contains filtered or unexported fields
}

Dielectric is a glass-like material

func (Dielectric) Emit added in v0.2.0

func (d Dielectric) Emit(u, v float64, pos Vec3) Vec3

Emit defines how a lambertian emits light (it doesn't)

func (Dielectric) Scatter

func (d Dielectric) Scatter(ray Ray, hit HitRecord) (bool, Vec3, Ray)

Scatter defines the behaviour of rays when they hit Metal material

type DiffuseLight added in v0.2.0

type DiffuseLight struct {
	// contains filtered or unexported fields
}

DiffuseLight is a light-emitting material

func (DiffuseLight) Emit added in v0.2.0

func (l DiffuseLight) Emit(u, v float64, pos Vec3) Vec3

Emit implements the emit interface for a DiffuseLight material

func (DiffuseLight) Scatter added in v0.2.0

func (l DiffuseLight) Scatter(ray Ray, hit HitRecord) (bool, Vec3, Ray)

Scatter implements the scatter interface for a DiffuseLight material

type FlipFace added in v0.2.0

type FlipFace struct {
	// contains filtered or unexported fields
}

FlipFace is a geometry wrapper for flipping the front face of the wrapped geometry

func (FlipFace) Bound added in v0.2.0

func (f FlipFace) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of a the initial geometry

func (FlipFace) Hit added in v0.2.0

func (f FlipFace) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit returns the hit of the inital geometry, but with the opposed record normal

type Fog added in v0.2.0

type Fog struct {
	// contains filtered or unexported fields
}

Fog is a volumetric medium

func (Fog) Bound added in v0.2.0

func (f Fog) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of the volumetric medium Bounding box is delegated to the boundary geometry containing the fog

func (Fog) Hit added in v0.2.0

func (f Fog) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geometry interface for volumetric medium

type Geometry

type Geometry interface {
	Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)
	Bound(startTime float64, endTime float64) (bool, *Bbox)
}

Geometry interface

Hit

@in

ray : a light ray
tMin : closer objects are not considered
tMax : further objects are not considered

@out

bool : if the ray hit the geometry
HitRecord : information about the hit, or nil

Bound

@in

startTime : the starting time for bounding
endTime : the ending time for bounding

@out

bool : if the geometry can be bounded (false for infinite planes)
Bbox : bounding box (aabb) of the geometry, if applicable

func NewRotateY added in v0.2.0

func NewRotateY(shape Geometry, angle float64) Geometry

NewRotateY constructs a rotated object around the Y axis

type HitRecord

type HitRecord struct {
	Distance float64
	Position Vec3
	Normal   Vec3
	Material Material
	U, V     float64
}

HitRecord defines the intersection of a Ray and an Actor

type Image added in v0.2.0

type Image struct {
	// contains filtered or unexported fields
}

Image is a texture mapped to an image file

func NewImage added in v0.2.0

func NewImage(file string, xoffset, yoffset float64) Image

NewImage creates an image texture from the path to the image, and an offset on the x axis The offset is given as a percentage of the width

func (Image) Value added in v0.2.0

func (t Image) Value(u, v float64, pos Vec3) Vec3

Value implements the texture interface for an Image texture

type Index

type Index struct {
	// contains filtered or unexported fields
}

Index is a binary tree forming a bounding volume hierarchy of objects satisfying the geometry interface

func NewIndex

func NewIndex(world Collection, start, end int, startTime, endTime float64) *Index

NewIndex builds a bounding volume hierarchy

func (*Index) Bound

func (idx *Index) Bound(tMin float64, tMax float64) (bool, *Bbox)

Bound returns the bounding box of the Index

func (*Index) Hit

func (idx *Index) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the hit interface for the Index

type Isotropic added in v0.2.0

type Isotropic struct {
	// contains filtered or unexported fields
}

Isotropic is a material scattering in random direction

func (Isotropic) Emit added in v0.2.0

func (i Isotropic) Emit(u float64, v float64, pos Vec3) Vec3

Emit defines how an isotropic material doesn't emit light

func (Isotropic) Scatter added in v0.2.0

func (i Isotropic) Scatter(ray Ray, hit HitRecord) (bool, Vec3, Ray)

Scatter of isotropic material scatters a new ray in a random direction at the hit

type Lambertian

type Lambertian struct {
	// contains filtered or unexported fields
}

Lambertian is a diffuse material

func (Lambertian) Emit added in v0.2.0

func (l Lambertian) Emit(u, v float64, pos Vec3) Vec3

Emit defines how a Lambertian emits light (it doesn't)

func (Lambertian) Scatter

func (l Lambertian) Scatter(ray Ray, hit HitRecord) (bool, Vec3, Ray)

Scatter defines how a lambertian material scatters a Ray

type Marble added in v0.2.0

type Marble struct {
	// contains filtered or unexported fields
}

Marble is a marble-like texture

func (Marble) Value added in v0.2.0

func (t Marble) Value(u, v float64, pos Vec3) Vec3

Value implements the texture interface for a Marble texture

type Material

type Material interface {
	Scatter(ray Ray, hit HitRecord) (bool, Vec3, Ray)
	Emit(u, v float64, pos Vec3) Vec3
}

Material define the way actors interact with a ray

Scatter

@in

ray : an incident ray
hit : the record for the hit of the ray with a geometry

@out

bool : true if the material scatters the ray
Vec3 : the attenuation of the scattered ray
Ray : the scattered ray

type Metal

type Metal struct {
	// contains filtered or unexported fields
}

Metal is a reflective material

func NewMetal

func NewMetal(albedo Vec3, fuzz float64) Metal

NewMetal returns a metal material from its albedo

func (Metal) Emit added in v0.2.0

func (m Metal) Emit(u, v float64, pos Vec3) Vec3

Emit defines how a Metal emits light (it doesn't)

func (Metal) Scatter

func (m Metal) Scatter(ray Ray, record HitRecord) (bool, Vec3, Ray)

Scatter defines the behaviour of rays when they hit Metal material

type MovingSphere

type MovingSphere struct {
	CenterStart Vec3
	CenterStop  Vec3
	Radius      float64
	// contains filtered or unexported fields
}

MovingSphere geometry

func (MovingSphere) Bound

func (s MovingSphere) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of the MovingSphere

func (MovingSphere) Hit

func (s MovingSphere) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geomtry interface for checking the intersection of a Ray and a MovingSphere

type Noise added in v0.2.0

type Noise struct {
	// contains filtered or unexported fields
}

Noise is an opensimplex noise

func (Noise) Value added in v0.2.0

func (t Noise) Value(u, v float64, pos Vec3) Vec3

Value implements the texture interface for a Noise Texture

type Ray

type Ray struct {
	Origin     Vec3
	Direction  Vec3
	Time       float64
	RandSource *rand.Rand
}

Ray is a light ray

func (Ray) At

func (r Ray) At(t float64) Vec3

At is the point of the ray having travelled t

type RectXY added in v0.2.0

type RectXY struct {
	// contains filtered or unexported fields
}

RectXY is a rectangular shape in the XY plane (z=k), bounded by x0, x1, y0 and y1

func (RectXY) Bound added in v0.2.0

func (r RectXY) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of a RectXY

func (RectXY) Hit added in v0.2.0

func (r RectXY) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geometry interface for RectXY

type RectXZ added in v0.2.0

type RectXZ struct {
	// contains filtered or unexported fields
}

RectXZ is a rectangular shape in the XZ plane (y=k), bounded by x0, x1, z0 and z1

func (RectXZ) Bound added in v0.2.0

func (r RectXZ) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of a RectXZ

func (RectXZ) Hit added in v0.2.0

func (r RectXZ) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geometry interface for RectXY

type RectYZ added in v0.2.0

type RectYZ struct {
	// contains filtered or unexported fields
}

RectYZ is a rectangular shape in the YZ plane (x=k), bounded by y0, y1, z0 and z1

func (RectYZ) Bound added in v0.2.0

func (r RectYZ) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of a RectXZ

func (RectYZ) Hit added in v0.2.0

func (r RectYZ) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geometry interface for RectYZ

type RotateY added in v0.2.0

type RotateY struct {
	// contains filtered or unexported fields
}

RotateY is a wrapper around a geometry, which is rotated around the Y axis

func (RotateY) Bound added in v0.2.0

func (r RotateY) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of a rotated geometry

func (RotateY) Hit added in v0.2.0

func (r RotateY) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geometry interface for a Rotated object (around Y axis)

type Scene

type Scene struct {
	// contains filtered or unexported fields
}

Scene is the whole scene to be rendered

func BookScene

func BookScene() *Scene

BookScene creates the scene on the cover of the first book

func CornellBox added in v0.2.0

func CornellBox() *Scene

CornellBox is a the classic cornell box scene

func EarthScene added in v0.2.0

func EarthScene() *Scene

EarthScene is a scene demonstrating image textures

func FinalScene added in v0.2.0

func FinalScene() *Scene

FinalScene is the last scene of Ray Tracing: The Next Week

func FoggyCornellBox added in v0.2.0

func FoggyCornellBox() *Scene

FoggyCornellBox is a the cornell box scene with fog objects

func LightMarbleScene added in v0.2.0

func LightMarbleScene() *Scene

LightMarbleScene is a scene with a black and white marble with lights

func MarbleScene added in v0.2.0

func MarbleScene() *Scene

MarbleScene is a scene with a black and white marble

func MovingSpheres

func MovingSpheres() *Scene

MovingSpheres creates the scene on the cover of the first book, with bouncing balls

func NewScene added in v0.2.0

func NewScene(camera Camera, world Collection, background Vec3) *Scene

NewScene creates a scene that can be rendered. It contains all actors in the world collection, and is viewed from the camera.

func (*Scene) Render

func (s *Scene) Render(width, height, pixelSamples, maxScatter int) *image.RGBA

Render renders the scene with the given parameters

type Sphere

type Sphere struct {
	Center Vec3
	Radius float64
}

Sphere geometry

func (Sphere) Bound

func (s Sphere) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of the Sphere

func (Sphere) Hit

func (s Sphere) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geomtry interface for checking the intersection of a Ray and a Sphere

type Texture

type Texture interface {
	Value(u, v float64, pos Vec3) Vec3
}

Texture interface

Value

@in

u, v : coordinates of the point

@out

Vec3 : color at the given coordinates

type Translate added in v0.2.0

type Translate struct {
	// contains filtered or unexported fields
}

Translate is a wrapper around a geometry, which is offset by a translation vector

func (Translate) Bound added in v0.2.0

func (t Translate) Bound(startTime float64, endTime float64) (bool, *Bbox)

Bound returns the bounding box of a translated geometry

func (Translate) Hit added in v0.2.0

func (t Translate) Hit(ray Ray, tMin float64, tMax float64) (bool, *HitRecord)

Hit implements the geometry interface for a Translated object It does so by offsetting the ray rather than the wrapped object

type Vec3

type Vec3 struct {
	X, Y, Z float64
}

Vec3 defines a 3-dimensional vector

func MaxCoord added in v0.2.0

func MaxCoord(u Vec3, v Vec3) Vec3

MaxCoord returns a new vector corresponding to the element-wise maximum of the two vectors

func MinCoord added in v0.2.0

func MinCoord(u Vec3, v Vec3) Vec3

MinCoord returns a new vector corresponding to the element-wise minimum of the two vectors

func RandDisk

func RandDisk(rnd *rand.Rand) Vec3

RandDisk returns a random vector in the unit disk

func RandSphere

func RandSphere(rnd *rand.Rand) Vec3

RandSphere returns vector drawn from a lambertian distribution inside the unit sphere

func RandVec

func RandVec(rnd *rand.Rand) Vec3

RandVec returns a random vector with coordinates in [0, 1)

func RandVecInterval

func RandVecInterval(low float64, high float64, rnd *rand.Rand) Vec3

RandVecInterval returns a random vector with coordinates in [low, high)

func (Vec3) Add

func (u Vec3) Add(v Vec3) Vec3

Add returns u + v

func (Vec3) AsArray

func (u Vec3) AsArray() [3]float64

AsArray returns the coordinates of the vector as an array of size 3

func (Vec3) Cross

func (u Vec3) Cross(v Vec3) Vec3

Cross returns the cross product between u and v

func (Vec3) Div

func (u Vec3) Div(t float64) Vec3

Div returns the scaling of v by 1/t

func (Vec3) Dot

func (u Vec3) Dot(v Vec3) float64

Dot returns the dot (inner) product between u and v

func (Vec3) GetColor

func (u Vec3) GetColor(samples int) color.RGBA

GetColor retruns the RGBA color of the vector

func (Vec3) Mul

func (u Vec3) Mul(v Vec3) Vec3

Mul returns the *termwise* product betweenu and v

func (Vec3) Neg

func (u Vec3) Neg() Vec3

Neg returns -v

func (Vec3) Norm

func (u Vec3) Norm() float64

Norm returns the euclidean norm of u

func (Vec3) Reflect

func (u Vec3) Reflect(n Vec3) Vec3

Reflect computes the reflection of v if it hits a surface of normal n

func (Vec3) Refract

func (u Vec3) Refract(n Vec3, nRatio float64) (bool, Vec3)

Refract returns the refraction of u at an interface

func (Vec3) Scale

func (u Vec3) Scale(t float64) Vec3

Scale returns v scaled by t

func (Vec3) SquareNorm

func (u Vec3) SquareNorm() float64

SquareNorm returns the square of the euclidean norm of u

func (Vec3) Sub

func (u Vec3) Sub(v Vec3) Vec3

Sub returns u-v

func (Vec3) Unit

func (u Vec3) Unit() Vec3

Unit returns a unit vector from u

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL