raytracer

package
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2020 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultMaximumReflections int = 4 // recommended on page 148

TODO ugh can we make this a default argument somehow?

View Source
const EPSILON = 0.00001 // TODO: rename? this is the difference btwn floats less thanw which we'd conisder them the same

Variables

View Source
var Colors = map[string]Color{
	"White":      NewColor(1, 1, 1),
	"Gray":       NewColor(0.5, 0.5, 0.5),
	"Black":      NewColor(0, 0, 0),
	"Brown":      NewColor(1, 0.5, 0),
	"Red":        NewColor(1, 0, 0),
	"Orange":     NewColor(1, 0.5, 0),
	"Yellow":     NewColor(1, 1, 0),
	"Green":      NewColor(0, 1, 0),
	"Cyan":       NewColor(0, 1, 1),
	"Blue":       NewColor(0, 0, 1),
	"Purple":     NewColor(0.5, 0, 0.5),
	"DarkGray":   NewColor(0.5, 0.5, 0.5),
	"DarkBlack":  NewColor(0, 0, 0),
	"DarkRed":    NewColor(1, 0, 0),
	"DarkOrange": NewColor(1, 0.5, 0),
	"DarkYellow": NewColor(1, 1, 0),
	"DarkGreen":  NewColor(0, 1, 0),
	"DarkBlue":   NewColor(0, 0, 1),
	"DarkPurple": NewColor(0.5, 0, 0.5),
}

Functions

func CubeUVBack added in v0.0.4

func CubeUVBack(p Tuple) (float64, float64)

Maps a point on the back face of a cube to its uv values.

func CubeUVFront added in v0.0.4

func CubeUVFront(p Tuple) (float64, float64)

Maps a point on the front face of a cube to its uv values.

func CubeUVLeft added in v0.0.4

func CubeUVLeft(p Tuple) (float64, float64)

Maps a point on the left face of a cube to its uv values.

func CubeUVLower added in v0.0.4

func CubeUVLower(p Tuple) (float64, float64)

func CubeUVRight added in v0.0.4

func CubeUVRight(p Tuple) (float64, float64)

Maps a point on the right face of a cube to its uv values.

func CubeUVUpper added in v0.0.4

func CubeUVUpper(p Tuple) (float64, float64)

Maps a point on the upper face of a cube to its uv values.

func CylindricalMap added in v0.0.4

func CylindricalMap(p Tuple) (float64, float64)

Converts a point to planar coordinates. (u = horizontal, v = vertical) TODO solve problem of top/bottom being rendered based on y component

func FaceFromPoint added in v0.0.4

func FaceFromPoint(p Tuple) string

TODO: is there a better value to return than string? Maybe enum/iota? Returns which face a given point on a unit cube is on.

func IntersectionAllowed added in v0.0.4

func IntersectionAllowed(op string, lhit, inl, inr bool) bool

func PlanarMap added in v0.0.4

func PlanarMap(p Tuple) (float64, float64)

Converts a point to planar coordinates. (u = horizontal, v = vertical)

func SphericalMap added in v0.0.4

func SphericalMap(p Tuple) (float64, float64)

Converts a point to spherical coordinates. (u = horizontal, v = vertical)

Types

type AreaLight added in v0.0.4

type AreaLight struct {
	Corner    Tuple   // corner: position of one corner of the light source
	UVec      Tuple   // direction+length of the u edge
	USteps    float64 // how many points are sampled along u edge. More steps = less banding, but with jittering it becomes noisier.
	VVec      Tuple   // direction+length of the v edge
	VSteps    float64 // how many points are sampled along v edge. More steps = less banding, but with jittering it becomes noisier.
	Intensity Color   // intensity of the light
	Samples   float64
	Jitter    *Sequence
}

func NewAreaLight added in v0.0.4

func NewAreaLight(corner Tuple, full_uvec Tuple, usteps float64, full_vvec Tuple, vsteps float64, intensity Color) *AreaLight

Returns a flat, rectangular light source -- composed of cells -- that casts a soft shadow.

|----------------------------|

^ | | | | | | | |----------------------------| v | | | ^ | | | v |----------------------------| e | | < |cells| > | | c |____________________________| corner uvec ->

TODO: investigate adaptive subdivision, to algorithically determine the resolution (i.e. steps) to use:

https://pdfs.semanticscholar.org/9792/e5563ac82ad33ffd6c9c0772682e96d6ba72.pdf
http://www.cse.chalmers.se/~uffe/xjobb/SoftShadows2.pdf

func NewPointLight added in v0.0.4

func NewPointLight(position Tuple, intensity Color) *AreaLight

Returns a simple point light, composed of 1 cell.

func (*AreaLight) GetIntensity added in v0.0.4

func (al *AreaLight) GetIntensity() Color

func (AreaLight) IntensityAt added in v0.0.4

func (al AreaLight) IntensityAt(p Tuple, w *World) float64

func (*AreaLight) IsEqualTo added in v0.0.4

func (al *AreaLight) IsEqualTo(al2 *AreaLight) bool

func (*AreaLight) PointOnLight added in v0.0.4

func (al *AreaLight) PointOnLight(u, v float64) Tuple

Returns the real point on the area light based on the u/v coordinates. This places the position of the point randomly based on the Jitter sequence to avoid the banding produced by a uniform position.

func (*AreaLight) String added in v0.0.4

func (al *AreaLight) String() string

type BoundingBox added in v0.0.4

type BoundingBox struct {
	MinPoint Tuple
	MaxPoint Tuple
}

BoundingBox represents a bounding box, which can be used to optimize intersection-checking on groups of objects.

func NewBoundingBox added in v0.0.4

func NewBoundingBox(min Tuple, max Tuple) BoundingBox

func NullBoundingBox added in v0.0.4

func NullBoundingBox() BoundingBox

NB: this should just be a BoundingBox with no min/max provided, but Go doesn't support optional arguments.

func (*BoundingBox) AddBoundingBoxes added in v0.0.4

func (b *BoundingBox) AddBoundingBoxes(boundingBoxes ...BoundingBox)

func (*BoundingBox) AddPoints added in v0.0.4

func (b *BoundingBox) AddPoints(points ...Tuple)

Adds points to this BoundingBox and re-calculates the MinPoint and MaxPoint.

func (BoundingBox) ContainsBox added in v0.0.4

func (b BoundingBox) ContainsBox(b2 BoundingBox) bool

func (BoundingBox) ContainsPoint added in v0.0.4

func (b BoundingBox) ContainsPoint(point Tuple) bool

func (BoundingBox) Intersects added in v0.0.4

func (b BoundingBox) Intersects(r *Ray) bool

TODO: we can reuse the Cube LocalIntersect code here if we make this return an Interesctions instead.

func (BoundingBox) IsEqualTo added in v0.0.4

func (b BoundingBox) IsEqualTo(b2 BoundingBox) bool

func (BoundingBox) SplitBounds added in v0.0.4

func (b BoundingBox) SplitBounds() (BoundingBox, BoundingBox)

Divide a bounding box into two sub-boxes.

func (BoundingBox) String added in v0.0.4

func (b BoundingBox) String() string

func (BoundingBox) Transform added in v0.0.4

func (b BoundingBox) Transform(m Matrix) BoundingBox

Transforms a BoundingBox according to a Matrix. To work for scaling, translation and rotation, we need to get all the points from the box, transform each by the matrix, and then find the new min/max.

type Camera added in v0.0.4

type Camera struct {
	HSize            int
	VSize            int
	HalfWidth        float64
	HalfHeight       float64
	FieldOfView      float64
	Transform        Matrix // WARNING: don't set Transform directly, use SetTransform()
	InverseTransform Matrix
}

func NewCamera added in v0.0.4

func NewCamera(h, v int, f float64) *Camera

NewCamera returns a Camera, which renders a canvas 1 unit in front of it.

The h argument is the horizontal size of the canvas. The v argument is the vertical size of the canvas. The f argument is the field-of-view of the camera. (i.e. smaller means zoomed-in)

The Camera also has a Transform attribute, describing the world's orientation relative to the camera.

func (*Camera) PixelSize added in v0.0.4

func (c *Camera) PixelSize() float64

func (*Camera) RayForPixel added in v0.0.4

func (c *Camera) RayForPixel(pixelX, pixelY int) *Ray

TODO memoize PixelSize() for this func? RayForPixel returns a ray, from the camera through the point indicated.

func (*Camera) Render added in v0.0.4

func (c *Camera) Render(w *World, jobs int, printProgress bool) Canvas

Renders the world onto a canvas with the given camera, and returns the canvas.

If printProgress is true, outputs the current number of pixels rendered to canvas.

The number of pixels to render at a time can be controlled with the jobs argument.

func (*Camera) SetTransform added in v0.0.4

func (c *Camera) SetTransform(m Matrix)

func (*Camera) String added in v0.0.4

func (c *Camera) String() string

type Canvas added in v0.0.4

type Canvas struct {
	Width      int
	Height     int
	ColorScale float64
	Pixels     []Color
}

func NewCanvas added in v0.0.4

func NewCanvas(w, h int, defaultColor ...Color) Canvas

func NewCanvasFromPpm added in v0.0.4

func NewCanvasFromPpm(ppm string) (Canvas, error)

func (*Canvas) IsEqualTo added in v0.0.4

func (c *Canvas) IsEqualTo(c2 Canvas) bool

func (*Canvas) PixelAt added in v0.0.4

func (c *Canvas) PixelAt(x, y int) Color

func (*Canvas) SaveGIF added in v0.0.5

func (c *Canvas) SaveGIF(filepath string) error

func (*Canvas) SaveJPEG added in v0.0.5

func (c *Canvas) SaveJPEG(filepath string) error

func (*Canvas) SavePNG added in v0.0.5

func (c *Canvas) SavePNG(filepath string) error

func (*Canvas) SavePpm added in v0.0.5

func (c *Canvas) SavePpm(filepath string) error

func (Canvas) String added in v0.0.4

func (c Canvas) String() string

func (*Canvas) ToImage added in v0.0.5

func (c *Canvas) ToImage() image.Image

Export canvas to an image from Go's std lib.

func (*Canvas) ToPpm added in v0.0.4

func (c *Canvas) ToPpm() string

func (*Canvas) WritePixel added in v0.0.4

func (c *Canvas) WritePixel(x, y int, color Color)

type CheckerPattern added in v0.0.4

type CheckerPattern struct {
	A Color
	B Color
}

func (CheckerPattern) LocalPatternAt added in v0.0.4

func (p CheckerPattern) LocalPatternAt(point Tuple) Color

func (CheckerPattern) LocalUVPatternAt added in v0.0.4

func (p CheckerPattern) LocalUVPatternAt(u, v float64) Color

func (CheckerPattern) String added in v0.0.4

func (p CheckerPattern) String() string

type Color added in v0.0.4

type Color struct {
	Red   float64
	Green float64
	Blue  float64
}

func NewColor added in v0.0.4

func NewColor(x, y, z float64) Color

func (Color) Add added in v0.0.4

func (c Color) Add(c2 Color) Color

func (Color) Divide added in v0.0.4

func (c Color) Divide(scalar float64) Color

func (Color) IsEqualTo added in v0.0.4

func (c Color) IsEqualTo(c2 Color) bool

func (Color) Multiply added in v0.0.4

func (c Color) Multiply(scalar float64) Color

func (Color) MultiplyColor added in v0.0.4

func (c Color) MultiplyColor(c2 Color) Color

Returns the Hadamard product (or Schur product) of two colors.

func (Color) RGBA added in v0.0.5

func (c Color) RGBA() (uint32, uint32, uint32, uint32)

Fulfills image.Color interface

func (Color) ScaledRGB added in v0.0.5

func (c Color) ScaledRGB(colorScale float64) (uint, uint, uint)

func (Color) String added in v0.0.4

func (c Color) String() string

func (Color) Subtract added in v0.0.4

func (c Color) Subtract(c2 Color) Color

type Computation added in v0.0.4

type Computation struct {
	Time       float64 // the moment (in time units) at which the intersection happened
	Object     *Shape  // the object that was intersected
	Point      Tuple   // the point where intersection happened
	OverPoint  Tuple   // the Point value adjusted slightly to avoid "raytracer acne"
	UnderPoint Tuple   //
	EyeV       Tuple   // the vector from eye to the Point
	NormalV    Tuple   // the normal on the object at the given Point
	ReflectV   Tuple   // the vector of reflection
	Inside     bool    // was the intersection inside the object?
	N1         float64 // refractive index of object being exited at ray-object intersection
	N2         float64 // refractive index of object being entered at ray-object intersection
}

func (*Computation) Schlick added in v0.0.4

func (c *Computation) Schlick() float64

Schlick's equation is an approximation of Fresnel's. Returns the "reflectance", which represents what fraction of the light is reflected at the given hit. TODO rename "SchlickReflectance"? TODO read “Reflections and Refractions in Ray Tracing” paper to understand this.

type Cone added in v0.0.4

type Cone struct {
	Origin  Tuple
	Minimum float64
	Maximum float64
	Closed  bool
}

func (Cone) LocalBounds added in v0.0.4

func (c Cone) LocalBounds() BoundingBox

func (Cone) LocalIntersect added in v0.0.4

func (cone Cone) LocalIntersect(r *Ray, shape *Shape) Intersections

TODO can we remove Shape arg somehow? It's only there because ShapeInterface has no knowledge of its parent, but we need to put its aprent in the Intersection :( We treat a cube like 6 planes, with 2 parallel planes per axis.

func (Cone) LocalNormalAt added in v0.0.4

func (cone Cone) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (Cone) String added in v0.0.4

func (cone Cone) String() string

type Csg added in v0.0.4

type Csg struct {
	Operation string
	Left      *Shape
	Right     *Shape
}

Constructive Solid Geometry: combines shapes using one of three operations

func (*Csg) FilterIntersections added in v0.0.4

func (c *Csg) FilterIntersections(xs Intersections) Intersections

For this to work, your filter_intersections() function needs to loop over each intersection in xs, keeping track of which child the intersection hits and which children it is currently inside, and then passing that information to intersec- tion_allowed(). If the intersection is allowed, it’s added to the list of passing intersections.

func (Csg) LocalBounds added in v0.0.4

func (c Csg) LocalBounds() BoundingBox

func (Csg) LocalIntersect added in v0.0.4

func (c Csg) LocalIntersect(r *Ray, shape *Shape) Intersections

func (Csg) LocalNormalAt added in v0.0.4

func (c Csg) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (Csg) String added in v0.0.4

func (c Csg) String() string

type Cube added in v0.0.4

type Cube struct {
	Origin Tuple
}

func (Cube) LocalBounds added in v0.0.4

func (c Cube) LocalBounds() BoundingBox

func (Cube) LocalIntersect added in v0.0.4

func (c Cube) LocalIntersect(r *Ray, shape *Shape) Intersections

TODO can we remove Shape arg somehow? It's only there because ShapeInterface has no knowledge of its parent, but we need to put its aprent in the Intersection :( We treat a cube like 6 planes, with 2 parallel planes per axis.

func (Cube) LocalNormalAt added in v0.0.4

func (c Cube) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (Cube) String added in v0.0.4

func (c Cube) String() string

type CubeMapPattern added in v0.0.4

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

func (CubeMapPattern) LocalPatternAt added in v0.0.4

func (p CubeMapPattern) LocalPatternAt(point Tuple) Color

func (CubeMapPattern) LocalUVPatternAt added in v0.0.4

func (p CubeMapPattern) LocalUVPatternAt(u, v float64) Color

func (CubeMapPattern) String added in v0.0.4

func (p CubeMapPattern) String() string

type Cylinder added in v0.0.4

type Cylinder struct {
	Origin  Tuple
	Minimum float64
	Maximum float64
	Closed  bool
}

func (Cylinder) LocalBounds added in v0.0.4

func (c Cylinder) LocalBounds() BoundingBox

func (Cylinder) LocalIntersect added in v0.0.4

func (cyl Cylinder) LocalIntersect(r *Ray, shape *Shape) Intersections

TODO can we remove Shape arg somehow? It's only there because ShapeInterface has no knowledge of its parent, but we need to put its aprent in the Intersection :( We treat a cube like 6 planes, with 2 parallel planes per axis.

func (Cylinder) LocalNormalAt added in v0.0.4

func (cyl Cylinder) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (Cylinder) String added in v0.0.4

func (cyl Cylinder) String() string

type GradientPattern added in v0.0.4

type GradientPattern struct {
	A Color
	B Color
}

func (GradientPattern) LocalPatternAt added in v0.0.4

func (p GradientPattern) LocalPatternAt(point Tuple) Color

... [a blending function] is a function that takes two values and interpolates the values between them ...

func (GradientPattern) LocalUVPatternAt added in v0.0.4

func (p GradientPattern) LocalUVPatternAt(u, v float64) Color

func (GradientPattern) String added in v0.0.4

func (p GradientPattern) String() string

type Group added in v0.0.4

type Group struct {
	Children    []*Shape
	LeftBounds  BoundingBox
	RightBounds BoundingBox
}

func (Group) LocalBounds added in v0.0.4

func (g Group) LocalBounds() BoundingBox

func (Group) LocalIntersect added in v0.0.4

func (g Group) LocalIntersect(r *Ray, shape *Shape) Intersections

func (Group) LocalNormalAt added in v0.0.4

func (g Group) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (Group) String added in v0.0.4

func (g Group) String() string

type Intersection added in v0.0.4

type Intersection struct {
	Time   float64
	Object *Shape
	U      float64 // identifies where on 2D triangle that an intersection occurred, relative to corners.
	V      float64 // identifies where on 2D triangle that an intersection occurred, relative to corners.
}

func NewIntersection added in v0.0.4

func NewIntersection(t float64, obj *Shape) *Intersection

func NewIntersectionWithUV added in v0.0.4

func NewIntersectionWithUV(t float64, obj *Shape, u, v float64) *Intersection

func (*Intersection) IsEqualTo added in v0.0.4

func (i *Intersection) IsEqualTo(i2 *Intersection) bool

func (*Intersection) PrepareComputations added in v0.0.4

func (i *Intersection) PrepareComputations(r *Ray, xs ...*Intersection) *Computation

r: the ray that hit the intersection xs: "... the collection of all intersections, which can tell you where the hit is relative to the rest of the intersections ...""

func (*Intersection) String added in v0.0.4

func (i *Intersection) String() string

type Intersections added in v0.0.4

type Intersections []*Intersection

func (*Intersections) Hit added in v0.0.4

func (is *Intersections) Hit(checkingForShadows bool) *Intersection

TODO: should we just break out the shadow-checking Hit() into a new method?

func (Intersections) String added in v0.0.4

func (xs Intersections) String() string

type Material added in v0.0.4

type Material struct {
	Label           string
	Color           Color
	Ambient         float64
	Diffuse         float64
	Specular        float64
	Shininess       float64
	Pattern         *Pattern
	Reflective      float64
	Transparency    float64
	RefractiveIndex float64 // Vacuum=1, Water=1.333, Glass=1.52, Diamond=2.42
}

func DefaultMaterial added in v0.0.4

func DefaultMaterial() *Material

Beware: use this instead of Material{}, for Material{} without all the args will throw errors when rendering.

func (*Material) IsEqualTo added in v0.0.4

func (m *Material) IsEqualTo(m2 *Material) bool

func (*Material) Lighting added in v0.0.4

func (m *Material) Lighting(obj *Shape, light *AreaLight, point Tuple, eyeVector, normalVector Tuple, intensity float64) Color

Calculates the lighting for a given point and material, based on Phong reflection. Phone reflection model:

  • Ambient reflection: background lighting; a constant value.
  • Diffuse reflection: reflection from matte surface; depends on angle btwn light and surface.
  • Specular reflection: reflection of the light source; depends on angle btwn the reflection and eye vectors. Intensity is controlled by "shininess".

Inensity: 0.0 = in shadow, 1.0 = not in shadow.

func (*Material) String added in v0.0.4

func (m *Material) String() string

type Matrix added in v0.0.4

type Matrix struct {
	Rows int
	Cols int
	Data []float64
}

func IdentityMatrix added in v0.0.4

func IdentityMatrix() Matrix

func NewMatrix added in v0.0.4

func NewMatrix(rows, cols int, data []float64) Matrix

func NewRotateX added in v0.0.4

func NewRotateX(radians float64) Matrix

func NewRotateY added in v0.0.4

func NewRotateY(radians float64) Matrix

func NewRotateZ added in v0.0.4

func NewRotateZ(radians float64) Matrix

func NewScale added in v0.0.4

func NewScale(x, y, z float64) Matrix

func NewShear added in v0.0.4

func NewShear(xToY, xToZ, yToX, yToZ, zToX, zToY float64) Matrix

aka "skew"

func NewTranslation added in v0.0.4

func NewTranslation(x, y, z float64) Matrix

func NewUScale added in v0.0.4

func NewUScale(n float64) Matrix

func NewViewTransform added in v0.0.4

func NewViewTransform(from, to, up Tuple) Matrix

NewViewTransform returns a transformation matrix that orients the world relative to your eye.

The from argument is the position of the eye. (Point) The to argument is the position the eye's looking at. (Point) The up argument specifies the direction of up. (Vector)

func (Matrix) At added in v0.0.4

func (m Matrix) At(row, col int) float64

func (Matrix) Cofactor added in v0.0.4

func (m Matrix) Cofactor(rowToRemove, colToRemove int) float64

...Cofactors are minors that have (possibly) had their sign changed...

func (Matrix) Compose added in v0.0.4

func (m Matrix) Compose(transformations ...Matrix) Matrix

func (Matrix) Determinant added in v0.0.4

func (m Matrix) Determinant() float64

.. If the determinant is zero, then the corresponding system of equations has no solution...

func (Matrix) Inverse added in v0.0.4

func (m Matrix) Inverse() Matrix

func (Matrix) IsEqualTo added in v0.0.4

func (m Matrix) IsEqualTo(m2 Matrix) bool

func (Matrix) IsInvertible added in v0.0.4

func (m Matrix) IsInvertible() bool

func (Matrix) Minor added in v0.0.4

func (m Matrix) Minor(rowToRemove, colToRemove int) float64

Returns the determinant of a submatrix.

func (Matrix) Multiply added in v0.0.4

func (m Matrix) Multiply(m2 Matrix) Matrix

func (Matrix) MultiplyByTuple added in v0.0.4

func (m Matrix) MultiplyByTuple(t Tuple) Tuple

func (Matrix) Set added in v0.0.4

func (m Matrix) Set(row, col int, val float64)

func (Matrix) String added in v0.0.4

func (m Matrix) String() string

func (Matrix) Submatrix added in v0.0.4

func (m Matrix) Submatrix(rowToRemove, colToRemove int) Matrix

func (Matrix) Transpose added in v0.0.4

func (m Matrix) Transpose() Matrix

type ObjFile added in v0.0.4

type ObjFile struct {
	IgnoredLineCount int
	Vertices         []Tuple
	Normals          []Tuple
	DefaultGroup     *Shape
	Groups           map[string]*Shape
	CurrentGroupName string
}

func ParseObjFile added in v0.0.4

func ParseObjFile(s string) ObjFile

func (ObjFile) String added in v0.0.4

func (o ObjFile) String() string

func (*ObjFile) ToGroup added in v0.0.4

func (of *ObjFile) ToGroup() *Shape

type Pattern added in v0.0.4

type Pattern struct {
	LocalPattern     PatternInterface
	Transform        Matrix // WARNING: don't set Transform directly, use SetTransform()
	InverseTransform Matrix
}

Pattern is a general pattern (Transform), with the specific type of pattern stored as a PatternInterface in LocalPattern.

func NewCheckerPattern added in v0.0.4

func NewCheckerPattern(a, b Color) *Pattern

func NewCubeMapPattern added in v0.0.4

func NewCubeMapPattern(l, f, r, b, u, d *Pattern) *Pattern

func NewGradientPattern added in v0.0.4

func NewGradientPattern(a, b Color) *Pattern

func NewPattern added in v0.0.4

func NewPattern(pi PatternInterface) *Pattern

func NewRingPattern added in v0.0.4

func NewRingPattern(a, b Color) *Pattern

func NewStripePattern added in v0.0.4

func NewStripePattern(a, b Color) *Pattern

func NewTestPattern added in v0.0.4

func NewTestPattern() *Pattern

func NewTextureMapPattern added in v0.0.4

func NewTextureMapPattern(p *Pattern, f func(Tuple) (float64, float64)) *Pattern

func NewUVAlignCheckPattern added in v0.0.4

func NewUVAlignCheckPattern(main, ul, ur, bl, br Color) *Pattern

func NewUVCheckerPattern added in v0.0.4

func NewUVCheckerPattern(w, h float64, a, b Color) *Pattern

func NewUVImagePattern added in v0.0.4

func NewUVImagePattern(c Canvas) *Pattern

func (*Pattern) IsEqualTo added in v0.0.4

func (p *Pattern) IsEqualTo(p2 *Pattern) bool

func (*Pattern) PatternAtShape added in v0.0.4

func (p *Pattern) PatternAtShape(s *Shape, worldPoint Tuple) Color

func (*Pattern) SetTransform added in v0.0.4

func (p *Pattern) SetTransform(m Matrix)

func (*Pattern) String added in v0.0.4

func (p *Pattern) String() string

func (*Pattern) UVPatternAt added in v0.0.4

func (p *Pattern) UVPatternAt(u, v float64) Color

type PatternInterface added in v0.0.4

type PatternInterface interface {
	LocalPatternAt(Tuple) Color
	LocalUVPatternAt(float64, float64) Color // TODO: only used for uv patterns -- should this just be a different interface?
	// contains filtered or unexported methods
}

type Plane added in v0.0.4

type Plane struct {
}

Plane is implemented on xz axes.

func (Plane) LocalBounds added in v0.0.4

func (p Plane) LocalBounds() BoundingBox

func (Plane) LocalIntersect added in v0.0.4

func (p Plane) LocalIntersect(r *Ray, shape *Shape) Intersections

TODO can we remove Shape arg somehow? It's only there because ShapeInterface has no knowledge of its parent, but we need to put its aprent in the Intersection :(

func (Plane) LocalNormalAt added in v0.0.4

func (p Plane) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

... every single point on the plane has the same normal: vector(0, 1, 0). ...

func (Plane) String added in v0.0.4

func (p Plane) String() string

type Ray added in v0.0.4

type Ray struct {
	Origin    Tuple
	Direction Tuple // aka velocity (i.e. how far it moves per time unit)
}

func NewRay added in v0.0.4

func NewRay(o, d Tuple) *Ray

func (*Ray) IsEqualTo added in v0.0.4

func (r *Ray) IsEqualTo(r2 *Ray) bool

func (*Ray) Position added in v0.0.4

func (r *Ray) Position(time float64) Tuple

func (*Ray) String added in v0.0.4

func (r *Ray) String() string

func (*Ray) Transform added in v0.0.4

func (r *Ray) Transform(t Matrix) *Ray

type RingPattern added in v0.0.4

type RingPattern struct {
	A Color
	B Color
}

func (RingPattern) LocalPatternAt added in v0.0.4

func (p RingPattern) LocalPatternAt(point Tuple) Color

func (RingPattern) LocalUVPatternAt added in v0.0.4

func (p RingPattern) LocalUVPatternAt(u, v float64) Color

func (RingPattern) String added in v0.0.4

func (p RingPattern) String() string

type Sequence added in v0.0.4

type Sequence struct {
	Numbers []float64
	// contains filtered or unexported fields
}

func NewSequence added in v0.0.4

func NewSequence(s ...float64) Sequence

Returns a deterministic number generator. TODO: break out into a SequenceInterface, with DeterministicSequence and RandomSequence?

func (Sequence) IsEqualTo added in v0.0.4

func (s Sequence) IsEqualTo(s2 Sequence) bool

func (*Sequence) Next added in v0.0.4

func (s *Sequence) Next() float64

func (Sequence) String added in v0.0.4

func (s Sequence) String() string

type Shape added in v0.0.4

type Shape struct {
	Label            string
	LocalShape       ShapeInterface // not using anonymous embedded field mostly bc of IsEqualTo()... we have to pass the LocalShape, not the Shape
	Transform        Matrix         // WARNING: don't set Transform directly, use SetTransform()
	InverseTransform Matrix
	Material         *Material
	SavedRay         *Ray // TODO replace this later, it's only for testing purposes with TestShape
	Parent           *Shape
	Shadows          bool
}

Shape is a general shape (Transform+Material), with the specific type of shape stored as a ShapeInterface in LocalShape. LocaleShape-specific functions are prefixed with "local", e.g. localFoo().

func NewCone added in v0.0.4

func NewCone() *Shape

func NewCsg added in v0.0.4

func NewCsg(t string, l, r *Shape) *Shape

func NewCube added in v0.0.4

func NewCube() *Shape

func NewCylinder added in v0.0.4

func NewCylinder() *Shape

func NewGlassSphere added in v0.0.4

func NewGlassSphere() *Shape

func NewGroup added in v0.0.4

func NewGroup() *Shape

func NewPlane added in v0.0.4

func NewPlane() *Shape

func NewShape added in v0.0.4

func NewShape(si ShapeInterface) *Shape

func NewSmoothTriangle added in v0.0.4

func NewSmoothTriangle(p1, p2, p3, n1, n2, n3 Tuple) *Shape

func NewSphere added in v0.0.4

func NewSphere() *Shape

func NewTestShape added in v0.0.4

func NewTestShape() *Shape

func NewTriangle added in v0.0.4

func NewTriangle(p1, p2, p3 Tuple) *Shape

func (*Shape) AddChildren added in v0.0.4

func (s *Shape) AddChildren(shapes ...*Shape)

Adds one or more children to this Group.

func (*Shape) Bounds added in v0.0.4

func (s *Shape) Bounds() BoundingBox

func (*Shape) Divide added in v0.0.4

func (s *Shape) Divide(threshhold int)

If the shape is a Group and has at least +threshhold+ children, divide the children into new subgroups, to create the BVH.

func (*Shape) Includes added in v0.0.4

func (s *Shape) Includes(s2 *Shape) bool

NB: this returns true for "regular shape includes itself"

func (*Shape) Intersect added in v0.0.4

func (s *Shape) Intersect(r *Ray) Intersections

func (*Shape) IsEqualTo added in v0.0.4

func (s *Shape) IsEqualTo(s2 *Shape) bool

func (*Shape) MakeSubGroup added in v0.0.4

func (s *Shape) MakeSubGroup(shapes ...*Shape)

Adds a child that is a Group containing the given Shapes.

func (*Shape) NormalAt added in v0.0.4

func (s *Shape) NormalAt(worldPoint Tuple, i *Intersection) Tuple

func (*Shape) NormalToWorld added in v0.0.4

func (s *Shape) NormalToWorld(normal Tuple) Tuple

Transforms a vector in object space to world space, accounting for the chain of parents in between.

func (*Shape) ParentSpaceBounds added in v0.0.4

func (s *Shape) ParentSpaceBounds() BoundingBox

func (*Shape) PartitionChildren added in v0.0.4

func (s *Shape) PartitionChildren() ([]*Shape, []*Shape)

TODO: can we move this to just Group logic instead of all Shape logic? Divides the children into 2 subgroups, based on which sub-bounding-box they are located in. Any shapes that are located in both remain in this Group.

func (*Shape) SetTransform added in v0.0.4

func (s *Shape) SetTransform(m Matrix)

func (*Shape) String added in v0.0.4

func (s *Shape) String() string

func (*Shape) WorldToObject added in v0.0.4

func (s *Shape) WorldToObject(worldPoint Tuple) Tuple

Transforms a point in world space to object space, accounting for the chain of parents in between.

type ShapeInterface added in v0.0.4

type ShapeInterface interface {
	LocalNormalAt(Tuple, *Intersection) Tuple
	LocalIntersect(*Ray, *Shape) Intersections
	LocalBounds() BoundingBox
	// contains filtered or unexported methods
}

type SmoothTriangle added in v0.0.4

type SmoothTriangle struct {
	P1     Tuple
	P2     Tuple
	P3     Tuple
	N1     Tuple
	N2     Tuple
	N3     Tuple
	E1     Tuple
	E2     Tuple
	Normal Tuple
	// contains filtered or unexported fields
}

SmoothTriangle is like Triangle

func (SmoothTriangle) LocalBounds added in v0.0.4

func (t SmoothTriangle) LocalBounds() BoundingBox

func (SmoothTriangle) LocalIntersect added in v0.0.4

func (t SmoothTriangle) LocalIntersect(r *Ray, shape *Shape) Intersections

Uses the Möller–Trumbore algorithm to find the intersection of the ray and the triangle.

func (SmoothTriangle) LocalNormalAt added in v0.0.4

func (t SmoothTriangle) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (SmoothTriangle) String added in v0.0.4

func (t SmoothTriangle) String() string

type Sphere added in v0.0.4

type Sphere struct {
	Origin Tuple
	Radius float64
}

func (Sphere) LocalBounds added in v0.0.4

func (s Sphere) LocalBounds() BoundingBox

func (Sphere) LocalIntersect added in v0.0.4

func (s Sphere) LocalIntersect(r *Ray, shape *Shape) Intersections

TODO can we remove Shape arg somehow? It's only there because ShapeInterface has no knowledge of its parent, but we need to put its aprent in the Intersection :(

func (Sphere) LocalNormalAt added in v0.0.4

func (s Sphere) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (Sphere) String added in v0.0.4

func (s Sphere) String() string

type StripePattern added in v0.0.4

type StripePattern struct {
	A Color
	B Color
}

func (StripePattern) LocalPatternAt added in v0.0.4

func (s StripePattern) LocalPatternAt(point Tuple) Color

func (StripePattern) LocalUVPatternAt added in v0.0.4

func (sp StripePattern) LocalUVPatternAt(u, v float64) Color

func (StripePattern) String added in v0.0.4

func (s StripePattern) String() string

type TestPattern added in v0.0.4

type TestPattern struct {
}

This is just a dummy "child" of Pattern, for testing purposes.

func (TestPattern) LocalPatternAt added in v0.0.4

func (tp TestPattern) LocalPatternAt(point Tuple) Color

func (TestPattern) LocalUVPatternAt added in v0.0.4

func (tp TestPattern) LocalUVPatternAt(u, v float64) Color

func (TestPattern) String added in v0.0.4

func (p TestPattern) String() string

type TestShape added in v0.0.4

type TestShape struct {
}

This is just a dummy "child" of Shape, for testing purposes.

func (TestShape) LocalBounds added in v0.0.4

func (ts TestShape) LocalBounds() BoundingBox

func (TestShape) LocalIntersect added in v0.0.4

func (ts TestShape) LocalIntersect(r *Ray, shape *Shape) Intersections

func (TestShape) LocalNormalAt added in v0.0.4

func (ts TestShape) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (TestShape) String added in v0.0.4

func (s TestShape) String() string

type TextureMap added in v0.0.4

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

func NewTextureMap added in v0.0.4

func NewTextureMap(p *Pattern, f func(Tuple) (float64, float64)) TextureMap

type TextureMapPattern added in v0.0.4

type TextureMapPattern struct {
	Pattern *Pattern
	UVMap   func(Tuple) (float64, float64)
}

func (TextureMapPattern) LocalPatternAt added in v0.0.4

func (p TextureMapPattern) LocalPatternAt(point Tuple) Color

func (TextureMapPattern) LocalUVPatternAt added in v0.0.4

func (p TextureMapPattern) LocalUVPatternAt(u, v float64) Color

func (TextureMapPattern) String added in v0.0.4

func (p TextureMapPattern) String() string

type Triangle added in v0.0.4

type Triangle struct {
	P1     Tuple
	P2     Tuple
	P3     Tuple
	E1     Tuple
	E2     Tuple
	Normal Tuple
	// contains filtered or unexported fields
}

func (Triangle) LocalBounds added in v0.0.4

func (t Triangle) LocalBounds() BoundingBox

func (Triangle) LocalIntersect added in v0.0.4

func (t Triangle) LocalIntersect(r *Ray, shape *Shape) Intersections

Uses the Möller–Trumbore algorithm to find the intersection of the ray and the triangle.

func (Triangle) LocalNormalAt added in v0.0.4

func (t Triangle) LocalNormalAt(localPoint Tuple, hit *Intersection) Tuple

func (Triangle) String added in v0.0.4

func (t Triangle) String() string

type Tuple

type Tuple struct {
	X float64
	Y float64
	Z float64
	W float64 // 1: point, 0: vector
}

TODO could Tuple be an interface and Point/Vector types that implement it?

func NewPoint added in v0.0.4

func NewPoint(x, y, z float64) Tuple

func NewVector added in v0.0.4

func NewVector(x, y, z float64) Tuple

func (Tuple) Add added in v0.0.4

func (t Tuple) Add(t2 Tuple) Tuple

func (Tuple) Cross added in v0.0.4

func (t Tuple) Cross(t2 Tuple) Tuple

Returns the cross product of two vectors. "... gives you a new vector that is perpendicular to both of the original vectors ..."

func (Tuple) Divide added in v0.0.4

func (t Tuple) Divide(scalar float64) Tuple

func (Tuple) Dot added in v0.0.4

func (t Tuple) Dot(t2 Tuple) float64

Returns the dot product (aka scalar product or inner product) of two vectors. "... the smaller the dot product, the larger the angle between them ..."

func (Tuple) IsEqualTo added in v0.0.4

func (t Tuple) IsEqualTo(t2 Tuple) bool

func (Tuple) Magnitude added in v0.0.4

func (t Tuple) Magnitude() float64

Returns the magnitude of a vector.

func (Tuple) Multiply added in v0.0.4

func (t Tuple) Multiply(scalar float64) Tuple

func (Tuple) Negate added in v0.0.4

func (t Tuple) Negate() Tuple

func (Tuple) Normalized added in v0.0.4

func (t Tuple) Normalized() Tuple

Returns a normalized vector.

func (Tuple) Reflect added in v0.0.4

func (t Tuple) Reflect(normal Tuple) Tuple

Return the reflection of this vector, off a given normal.

func (Tuple) String added in v0.0.4

func (t Tuple) String() string

func (Tuple) Subtract added in v0.0.4

func (t Tuple) Subtract(t2 Tuple) Tuple

func (Tuple) Type

func (t Tuple) Type() string

type UVAlignCheckPattern added in v0.0.4

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

This is a pattern for testing purposes.

func (UVAlignCheckPattern) LocalPatternAt added in v0.0.4

func (acp UVAlignCheckPattern) LocalPatternAt(point Tuple) Color

func (UVAlignCheckPattern) LocalUVPatternAt added in v0.0.4

func (acp UVAlignCheckPattern) LocalUVPatternAt(u, v float64) Color

func (UVAlignCheckPattern) String added in v0.0.4

func (acp UVAlignCheckPattern) String() string

type UVCheckerPattern added in v0.0.4

type UVCheckerPattern struct {
	Width  float64
	Height float64
	A      Color
	B      Color
}

func (UVCheckerPattern) LocalPatternAt added in v0.0.4

func (p UVCheckerPattern) LocalPatternAt(point Tuple) Color

func (UVCheckerPattern) LocalUVPatternAt added in v0.0.4

func (p UVCheckerPattern) LocalUVPatternAt(u, v float64) Color

func (UVCheckerPattern) String added in v0.0.4

func (p UVCheckerPattern) String() string

type UVImagePattern added in v0.0.4

type UVImagePattern struct {
	Canvas Canvas
}

This is a pattern for testing purposes.

func (UVImagePattern) LocalPatternAt added in v0.0.4

func (ip UVImagePattern) LocalPatternAt(point Tuple) Color

func (UVImagePattern) LocalUVPatternAt added in v0.0.4

func (ip UVImagePattern) LocalUVPatternAt(u, v float64) Color

func (UVImagePattern) String added in v0.0.4

func (ip UVImagePattern) String() string

type World added in v0.0.4

type World struct {
	Objects []*Shape
	Lights  []*AreaLight
}

func DefaultWorld added in v0.0.4

func DefaultWorld() *World

DefaultWorld returns a new world with some default settings:

  • 1 unit sphere with color
  • 1 smaller sphere inside ^
  • a single white light

func NewWorld added in v0.0.4

func NewWorld() *World

NewWorld instantiates a new World object.

func (*World) ColorAt added in v0.0.4

func (w *World) ColorAt(r *Ray, remainingReflections int) Color

ColorAt gets a ray's intersection in the world and returns that intersection's color.

func (*World) Contains added in v0.0.4

func (w *World) Contains(obj *Shape) bool

Contains returns true if the world contains obj.

func (*World) Intersect added in v0.0.4

func (w *World) Intersect(r *Ray) Intersections

func (*World) IsShadowed added in v0.0.4

func (w *World) IsShadowed(p Tuple, lightPosition Tuple) bool

func (*World) ReflectedColor added in v0.0.4

func (w *World) ReflectedColor(c *Computation, remainingReflections int) Color

func (*World) RefractedColor added in v0.0.4

func (w *World) RefractedColor(c *Computation, remaining int) Color

func (*World) ShadeHit added in v0.0.4

func (w *World) ShadeHit(c *Computation, remainingReflections int) Color

ShadeHit returns the color for the given computation's intersection.

func (*World) String added in v0.0.4

func (w *World) String() string

type YamlInstruction added in v0.0.4

type YamlInstruction struct {
	// Type of instruction
	Define string
	Add    string

	// Extra fields
	Extend      string
	Width       int
	Height      int
	FieldOfView float64 `yaml:"field-of-view"`
	From        [3]float64
	To          [3]float64
	Up          [3]float64
	At          [3]float64
	Intensity   [3]float64
	Transform   yaml.Node
	Material    yaml.Node
	Value       yaml.Node
}

type YamlMaterial added in v0.0.4

type YamlMaterial struct {
	Color           [3]*float64
	Diffuse         *float64
	Ambient         *float64
	Specular        *float64
	Reflective      *float64
	Shininess       *float64
	RefractiveIndex *float64 `yaml:"refractive-index"`
	Transparency    *float64
}

NB: using pointers instead of values because values that are missing from the YAML struct would be initialized as their zero values (e.g. 0.0), but we don't want to use 0.0 if they're actually just missing.

type YamlSceneFile added in v0.0.4

type YamlSceneFile struct {
	Camera             *Camera
	World              *World
	MaterialDefs       map[string]Material
	TransformationDefs map[string]Matrix
}

func NewYamlSceneFile added in v0.0.4

func NewYamlSceneFile() YamlSceneFile

This returns a World as parsed from YAML, based on the format in the book.

func ParseYamlSceneFile added in v0.0.4

func ParseYamlSceneFile(filename string) (YamlSceneFile, error)

Jump to

Keyboard shortcuts

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