render3d

package
v0.4.4 Latest Latest
Warning

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

Go to latest
Published: Mar 1, 2024 License: BSD-2-Clause Imports: 17 Imported by: 7

Documentation

Overview

Package render3d provides various APIs for creating and rendering visual scenes.

The RayCaster API can be used to render scenes quickly. The RecursiveRayTracer API can be used to render very realistic scenes with accurate lighting.

Index

Constants

View Source
const DefaultEpsilon = 1e-8
View Source
const DefaultFieldOfView = math.Pi / 2

Variables

This section is empty.

Functions

func DestDensity added in v0.1.12

func DestDensity(mat Material, normal, source, dest model3d.Coord3D) float64

DestDensity is like mat.SourceDensity, but for SampleDest rather than SampleSource.

If mat is an AsymMaterial, its SampleDest method is used.

func RGB

func RGB(c Color) (float64, float64, float64)

RGB gets sRGB values for a Color.

func SampleDest added in v0.1.12

func SampleDest(mat Material, gen *rand.Rand, normal, source model3d.Coord3D) model3d.Coord3D

SampleDest is like mat.SampleSource, but it samples a destination direction.

If mat is an AsymMaterial, its SampleDest method is used.

func SaveRandomGrid

func SaveRandomGrid(path string, obj any, rows, cols, imgSize int,
	colorFunc ColorFunc) error

SaveRandomGrid renders a 3D object from a variety of randomized angles and saves the grid of renderings to a file.

The obj argument must be supported by Objectify.

If colorFunc is non-nil, it is used to determine the color for the visible parts of the model.

func SaveRendering

func SaveRendering(path string, obj any, origin model3d.Coord3D, width, height int,
	colorFunc ColorFunc) error

SaveRendering renders a 3D object from the given point and saves the image to a file.

The camera will automatically face the center of the object's bounding box.

The obj argument must be supported by Objectify.

If colorFunc is non-nil, it is used to determine the color for the visible parts of the model.

func SaveRotatingGIF added in v0.3.0

func SaveRotatingGIF(path string, obj any, axis, cameraDir model3d.Coord3D,
	imgSize, frames int, fps float64, colorFunc ColorFunc) error

SaveRotatingGIF saves a grayscale animated GIF panning around a model.

The axis specifies the axis around which the model will rotate. The cameraDir specifies the direction (from the center of the object) from which the camera will be extended until it can see the entire object.

Types

type AreaLight added in v0.1.5

type AreaLight interface {
	Object

	// SampleLight samples a point on the surface of the
	// light with a probability density proportional to
	// the sum of the emission R, G, and B.
	//
	// Returns both the normal to the light, and the
	// emission at the sampled point.
	SampleLight(gen *rand.Rand) (point, normal model3d.Coord3D, emission Color)

	// TotalEmission gets the integral of the emission
	// over the area of the light, where the red, green,
	// and blue components are summed together.
	TotalEmission() float64
}

AreaLight is a surface that emits light.

For regular path tracing, AreaLight is not needed, since lights are just regular objects. For global illumination methods that trace paths from lights to the scene, AreaLights are needed to sample from the light sources.

An AreaLight should not be reflective in any way; its BSDF should be zero everywhere.

func JoinAreaLights added in v0.1.5

func JoinAreaLights(lights ...AreaLight) AreaLight

JoinAreaLights creates a larger AreaLight by combining smaller AreaLights.

type AsymMaterial added in v0.1.5

type AsymMaterial interface {
	Material

	// SampleDest is like SampleSource, but it samples a
	// destination direction.
	SampleDest(gen *rand.Rand, normal, source model3d.Coord3D) model3d.Coord3D

	// DestDensity is like SourceDensity, but for
	// SampleDest rather than SampleSource.
	DestDensity(normal, source, dest model3d.Coord3D) float64
}

AsymMaterial is a specialized Material with a different sampling distribution for destination and source vectors.

This is useful for transparent objects, but should not be used for typical materials.

type BidirPathTracer added in v0.1.5

type BidirPathTracer struct {
	Camera *Camera

	// Light is the (possibly joined) area light that is
	// sampled for light-to-eye paths.
	Light AreaLight

	// MaxDepth is the maximum number of edges in a in
	// either direction.
	MaxDepth int

	// MaxLightDepth, if non-zero, limits the number of
	// light path vertices.
	// Set to 1 to simply sample the area lights.
	MaxLightDepth int

	// MinDepth, if non-zero, is the minimum number of
	// edges in a path before roulette sampling.
	//
	// If unspecified, no roulette sampling is performed
	// except for Cutoff.
	MinDepth int

	// These fields control how many samples are taken per
	// pixel of the image.
	// See RecursiveRayTracer for more details.
	NumSamples           int
	MinSamples           int
	MaxStddev            float64
	OversaturatedStddevs float64
	Convergence          func(mean, stddev Color) bool

	// RouletteDelta is the maximum intensity for roulette
	// sampling to be performed.
	// If zero, all deterministic connections are checked.
	RouletteDelta float64

	// PowerHeuristic, if non-zero, is used for multiple
	// importance sampling of paths.
	// A value of 2 is recommended, and a value of 1 is
	// equivalent to the balance heuristic used by
	// default.
	PowerHeuristic float64

	// See RecursiveRayTracer for more details.
	Cutoff    float64
	Antialias float64
	Epsilon   float64
	LogFunc   func(frac float64, sampleRate float64)
}

BidirPathTracer is a bidirectional path traceb.

Lights in the path tracer should be part of the scene, but should also be provided as an AreaLight.

func (*BidirPathTracer) RayVariance added in v0.1.5

func (b *BidirPathTracer) RayVariance(obj Object, width, height, samples int) float64

RayVariance estimates the variance of the color components in the rendered image for a single sample.

The variance is averaged over every color component in the image.

func (*BidirPathTracer) Render added in v0.1.5

func (b *BidirPathTracer) Render(img *Image, obj Object)

Render renders the object to an image.

func (*BidirPathTracer) RenderVariance added in v0.1.15

func (b *BidirPathTracer) RenderVariance(img *Image, obj Object, numSamples int)

RenderVariance computes the variance per pixel using a fixed number of rays per pixel, and writes the results as pixels in an image.

type Camera

type Camera struct {
	// Origin is the location of the camera, from whence
	// lines if sight originate.
	Origin model3d.Coord3D

	// ScreenX is the (normalized) direction in 3D space
	// that is rendered along the x-axis in images.
	// In other words, it is parallel to the x-axis on the
	// viewing plane.
	ScreenX model3d.Coord3D

	// ScreenY is the (normalized) direction in 3D space
	// that is rendered along the y-axis in images.
	// See ScreenX.
	ScreenY model3d.Coord3D

	// FieldOfView is the angle spanning the viewing plane
	// from the camera's origin.
	//
	// This is measured in radians.
	FieldOfView float64
}

A Camera defines a viewer's position, orientation, and field of view for rendering.

The right-hand rule is used to determine which way the camera is facing, such that if the viewing plane goes from top to bottom and left to right, then the rays of sight go away from the camera's origin. To reverse this, simply use a negative FieldOfView.

func DirectionalCamera added in v0.3.1

func DirectionalCamera(object Object, direction model3d.Coord3D, fov float64) *Camera

DirectionalCamera figures out where to move a camera in the given unit direction to capture the bounding box of an object.

func NewCameraAt

func NewCameraAt(source, dest model3d.Coord3D, fov float64) *Camera

NewCameraAt creates a new Camera that is looking at a point from another point.

If fov is 0, DefaultFieldOfView is used.

The image axes are automatically determined.

func (*Camera) Caster

func (c *Camera) Caster(imageWidth, imageHeight float64) func(x, y float64) model3d.Coord3D

Caster produces a function that converts image coordinates into directions for rays that emenate from the origin.

Arguments to the resulting function are x and y values ranging from [0, imageWidth] and [0, imageHeight].

func (*Camera) Uncaster

func (c *Camera) Uncaster(imageWidth, imageHeight float64) func(model3d.Coord3D) (float64,
	float64)

Uncaster produces a function that converts spatial coordinates to screen coordinates using a perspective projection.

type ColliderObject

type ColliderObject struct {
	Collider model3d.Collider
	Material Material
}

A ColliderObject wraps a model3d.Collider in the Object interface, using a constant material.

func (*ColliderObject) Cast

Cast returns the first ray collision.

func (*ColliderObject) Max

func (c *ColliderObject) Max() model3d.Coord3D

Max gets the maximum of the bounding box.

func (*ColliderObject) Min

func (c *ColliderObject) Min() model3d.Coord3D

Min gets the minimum of the bounding box.

type Color

type Color = model3d.Coord3D

Color is a linear RGB color, where X, Y, and Z store R, G, and B respectively.

Note that these colors are NOT sRGB (the standard), since sRGB values do not represent linear brightness.

Colors should be positive, but they are not bounded on the positive side, since light isn't in the real world.

func ClampColor

func ClampColor(c Color) Color

ClampColor clamps the color into the range [0, 1].

func NewColor

func NewColor(b float64) Color

NewColor creates a Color with a given brightness.

func NewColorRGB

func NewColorRGB(r, g, b float64) Color

NewColorRGB creates a Color from sRGB values.

type ColorFunc

type ColorFunc func(c model3d.Coord3D, rc model3d.RayCollision) Color

ColorFunc determines a color for collisions on a surface. It is used for convenience methods where specifying a material would be too cumbersome.

func TriangleColorFunc

func TriangleColorFunc(f func(t *model3d.Triangle) [3]float64) ColorFunc

TriangleColorFunc creates a ColorFunc from a function that colors triangles. This can be used for compatibility with model3d.EncodeMaterialOBJ.

This only works when rendering meshes or triangles.

type CylinderAreaLight added in v0.2.0

type CylinderAreaLight struct {
	Object
	// contains filtered or unexported fields
}

CylinderAreaLight is a cylinder implementing an area light.

func NewCylinderAreaLight added in v0.2.0

func NewCylinderAreaLight(c *model3d.Cylinder, emission Color) *CylinderAreaLight

NewCylinderAreaLight turns a cylinder collider into an area light.

func (*CylinderAreaLight) SampleLight added in v0.2.0

func (c *CylinderAreaLight) SampleLight(gen *rand.Rand) (point, normal model3d.Coord3D,
	emission Color)

func (*CylinderAreaLight) TotalEmission added in v0.2.0

func (c *CylinderAreaLight) TotalEmission() float64

type FilteredObject added in v0.4.2

type FilteredObject struct {
	Object
	Bounds model3d.Collider
}

A FilteredObject only reports ray collisions if the ray collides with some bounds object.

func (*FilteredObject) Cast added in v0.4.2

type FocusPoint

type FocusPoint interface {
	// SampleFocus samples a source direction for a
	// collision, focusing on some aspect of a scene.
	SampleFocus(gen *rand.Rand, mat Material, point,
		normal, dest model3d.Coord3D) model3d.Coord3D

	// FocusDensity computes the probability density ratio
	// of sampling the source direction from a point,
	// relative to density on a unit sphere.
	FocusDensity(mat Material, point, normal, source,
		dest model3d.Coord3D) float64
}

A FocusPoint is some part of the scene that warrants extra rays (e.g. part of a light).

Focus points perform importance sampling such that the point or object of interest is sampled more.

type HGMaterial

type HGMaterial struct {
	// G is a control parameter in [-1, 1].
	// -1 is backscattering, 1 is forward scattering.
	G float64

	// ScatterColor controls how much light is actually
	// scattered vs. absorbed.
	ScatterColor Color

	IgnoreNormals bool
}

HGMaterial implements the Henyey-Greenstein phase function for ray scattering.

This material cancels out the normal cosine term that is introduced by the rendering equation. To ignore normals and not cancel, set IgnoreNormals.

func (*HGMaterial) Ambient

func (h *HGMaterial) Ambient() Color

func (*HGMaterial) BSDF

func (h *HGMaterial) BSDF(normal, source, dest model3d.Coord3D) Color

func (*HGMaterial) Emission

func (h *HGMaterial) Emission() Color

func (*HGMaterial) SampleSource

func (h *HGMaterial) SampleSource(gen *rand.Rand, normal, dest model3d.Coord3D) model3d.Coord3D

func (*HGMaterial) SourceDensity

func (h *HGMaterial) SourceDensity(normal, source, dest model3d.Coord3D) float64

type Image

type Image struct {
	Data   []Color
	Width  int
	Height int
}

func NewImage

func NewImage(width, height int) *Image

NewImage creates an image at a certain size.

func (*Image) At added in v0.4.0

func (i *Image) At(x, y int) Color

At gets the color at the coordinate.

func (*Image) CopyFrom

func (i *Image) CopyFrom(i1 *Image, x, y int)

CopyFrom copies the image img into this image at the given coordinates x, y in i.

This can be used to copy a smaller image i1 into a larger image i.

func (*Image) Downsample added in v0.3.4

func (i *Image) Downsample(factor int) *Image

Downsample returns a new image by downsampling i by an integer scale factor. The factor must evenly divide the width and height.

New colors are computed by averaging squares of colors in linear RGB space.

func (*Image) FillRange

func (i *Image) FillRange()

FillRange scales the color values so that the largest color component is exactly 1.

func (*Image) Gray

func (i *Image) Gray() *image.Gray

Gray creates a standard library Gray image from i.

Values outside the range of [0, 1] are clamped.

func (*Image) RGBA

func (i *Image) RGBA() *image.RGBA

RGBA creates a standard library RGBA image from i.

Values outside the range of [0, 1] are clamped.

func (*Image) Save

func (i *Image) Save(path string) error

Save saves the image to a file.

It uses the extension to determine the type. Use either .png, .jpg, or .jpeg.

func (*Image) Scale added in v0.1.2

func (i *Image) Scale(s float64)

Scale scales all colors by a constant.

func (*Image) Set added in v0.4.0

func (i *Image) Set(x, y int, c Color)

Set stores a color at the coordinate.

func (*Image) SetAll added in v0.4.2

func (i *Image) SetAll(c Color)

SetAll sets all of the pixels to a constant color.

type JoinedMaterial

type JoinedMaterial struct {
	Materials []Material

	// Probs contains probabilities for importance
	// sampling each material.
	// The probabilities should sum to 1.
	Probs []float64
}

A JoinedMaterial adds the BSDFs of multiple materials.

It also importance samples from each BSDF according to pre-determined probabilities.

func (*JoinedMaterial) Ambient

func (j *JoinedMaterial) Ambient() Color

func (*JoinedMaterial) BSDF

func (j *JoinedMaterial) BSDF(normal, source, dest model3d.Coord3D) Color

func (*JoinedMaterial) DestDensity added in v0.1.12

func (j *JoinedMaterial) DestDensity(normal, source, dest model3d.Coord3D) float64

func (*JoinedMaterial) Emission

func (j *JoinedMaterial) Emission() Color

func (*JoinedMaterial) SampleDest added in v0.1.12

func (j *JoinedMaterial) SampleDest(gen *rand.Rand, normal,
	dest model3d.Coord3D) model3d.Coord3D

func (*JoinedMaterial) SampleSource

func (j *JoinedMaterial) SampleSource(gen *rand.Rand, normal,
	dest model3d.Coord3D) model3d.Coord3D

func (*JoinedMaterial) SourceDensity

func (j *JoinedMaterial) SourceDensity(normal, source, dest model3d.Coord3D) float64

type JoinedObject

type JoinedObject []Object

A JoinedObject combines multiple Objects.

func (JoinedObject) Cast

Cast casts the ray onto the objects and chooses the closest ray collision.

func (JoinedObject) Max

func (j JoinedObject) Max() model3d.Coord3D

Max gets the maximum of the bounding box.

func (JoinedObject) Min

func (j JoinedObject) Min() model3d.Coord3D

Min gets the minimum of the bounding box.

type LambertMaterial

type LambertMaterial struct {
	DiffuseColor  Color
	AmbientColor  Color
	EmissionColor Color
}

LambertMaterial is a completely matte material.

func (*LambertMaterial) Ambient

func (l *LambertMaterial) Ambient() Color

func (*LambertMaterial) BSDF

func (l *LambertMaterial) BSDF(normal, source, dest model3d.Coord3D) Color

func (*LambertMaterial) Emission

func (l *LambertMaterial) Emission() Color

func (*LambertMaterial) SampleSource

func (l *LambertMaterial) SampleSource(gen *rand.Rand, normal,
	dest model3d.Coord3D) model3d.Coord3D

func (*LambertMaterial) SourceDensity

func (l *LambertMaterial) SourceDensity(normal, source, dest model3d.Coord3D) float64

type Material

type Material interface {
	// BSDF gets the amount of light that bounces off the
	// surface into a given direction.
	// It differs slightly from the usual meaning of BRDF,
	// since it may include refractions into the surface.
	// Thus, the BSDF is a function on the entire sphere,
	// not just a hemisphere.
	//
	// Both arguments should be unit vectors.
	//
	// The source argument specifies the direction that
	// light is coming in and hitting the surface.
	//
	// The dest argument specifies the direction in which
	// the light is to reflect or refract, and where we
	// would like to know the intensity.
	//
	// Returns a multiplicative mask for incoming light.
	//
	// The outgoing flux should be less than or equal to
	// the incoming flux.
	// Thus, the outgoing Color should be, on expectation
	// over random unit dest vectors weighted by the
	// cosine of the outgoing angle, less than 1 in all
	// components.
	BSDF(normal, source, dest model3d.Coord3D) Color

	// SampleSource samples a random source vector for a
	// given dest vector, possibly with a non-uniform
	// distribution.
	//
	// The main purpose of SampleSource is to compute a
	// the mean outgoing light using importance sampling.
	//
	// The densities returned by SourceDensity correspond
	// to this sampling distribution.
	//
	// The gen argument is used for sampling.
	// This is more efficient than using a shared RNG for
	// multithreaded rendering.
	SampleSource(gen *rand.Rand, normal, dest model3d.Coord3D) model3d.Coord3D

	// SourceDensity computes the density ratio of
	// arbitrary source directions under the distribution
	// used by SampleSource(). These ratios measure the
	// density divided by the density on a unit sphere.
	// Thus, they measure density per steradian.
	SourceDensity(normal, source, dest model3d.Coord3D) float64

	// Emission is the amount of light directly given off
	// by the surface.
	Emission() Color

	// Ambient is the baseline color to use for all
	// collisions with this surface for rendering.
	// It ensures that every surface is rendered at least
	// some amount.
	Ambient() Color
}

A Material determines how light bounces off a locally flat surface.

type MeshAreaLight added in v0.1.5

type MeshAreaLight struct {
	Object
	// contains filtered or unexported fields
}

MeshAreaLight is an AreaLight for the surface of a mesh.

func NewMeshAreaLight added in v0.1.5

func NewMeshAreaLight(mesh *model3d.Mesh, emission Color) *MeshAreaLight

NewMeshAreaLight creates an efficient area light from the triangle mesh.

func (*MeshAreaLight) SampleLight added in v0.1.5

func (m *MeshAreaLight) SampleLight(gen *rand.Rand) (point, normal model3d.Coord3D,
	emission Color)

func (*MeshAreaLight) TotalEmission added in v0.2.0

func (m *MeshAreaLight) TotalEmission() float64

type Object

type Object interface {
	model3d.Bounder

	// Cast finds the first collision with ray r.
	//
	// It returns not only the ray collision, but also the
	// material on the surface of the object at the point.
	//
	// The final return value indicates if there was a
	// collision or not.
	Cast(r *model3d.Ray) (model3d.RayCollision, Material, bool)
}

An Object is a renderable 3D object.

func BVHToObject added in v0.4.2

func BVHToObject(objs *model3d.BVH[Object]) Object

BVHToObject creates a single object from a BVH by wrapping each node in a (bounding-box filtered) joined object.

func MatrixMultiply

func MatrixMultiply(obj Object, m *model3d.Matrix3) Object

MatrixMultiply left-multiplies coordinates in an object by a matrix m. It can be used for rotations, scaling, etc.

func Objectify

func Objectify(obj any, colorFunc ColorFunc) Object

Objectify turns a mesh, collider, or Object into a new Object with a specified coloration.

Accepted object types are:

  • render3d.Object
  • *model3d.Mesh
  • model3d.Collider

The colorFunc is used to color the object's material. If colorFunc is used, a default yellow color is used, unless the object already has an associated material.

func Rotate added in v0.2.23

func Rotate(obj Object, axis model3d.Coord3D, angle float64) Object

Rotate creates a new Object by rotating an Object by a given angle (in radians) around a given (unit) axis.

func Scale added in v0.2.23

func Scale(obj Object, scale float64) Object

Scale creates a new Object by scaling an Object by the given factor along all axes.

func Translate

func Translate(obj Object, offset model3d.Coord3D) Object

Translate moves the object by an additive offset.

type ParticipatingMedium

type ParticipatingMedium struct {
	Collider model3d.Collider
	Material Material

	// Lambda controls how likely a collision is.
	// Larger lambda means lower probability.
	// Mean distance is 1 / lambda.
	Lambda float64
}

ParticipatingMedium is a volume in which a ray has a probability of hitting a particle, in which the collision probability increases with distance.

It is recommended that you use an HGMaterial with this object type.

Normals reported for collisions are random and have no bearing on how rays are scattered, since the medium simulates complex particles which either reflect or refract light. Hence, materials which use normals should not be employed.

func (*ParticipatingMedium) Cast

Cast returns the first probabilistic ray collision.

func (*ParticipatingMedium) Max

Max gets the maximum of the bounding box.

func (*ParticipatingMedium) Min

Min gets the minimum of the bounding box.

type PhongFocusPoint

type PhongFocusPoint struct {
	Target model3d.Coord3D

	// Alpha is the amount of focus to put on the target
	// direction.
	Alpha float64

	// MaterialFilter, if non-nil, is called to see if a
	// given material needs to be focused on a light.
	MaterialFilter func(m Material) bool
}

A PhongFocusPoint uses a distribution proportional to cos(theta)^alpha, just like phong shading.

func (*PhongFocusPoint) FocusDensity

func (p *PhongFocusPoint) FocusDensity(mat Material, point, normal, source,
	dest model3d.Coord3D) float64

FocusDensity gives the probability density ratio for the given direction.

func (*PhongFocusPoint) SampleFocus

func (p *PhongFocusPoint) SampleFocus(gen *rand.Rand, mat Material, point, normal,
	dest model3d.Coord3D) model3d.Coord3D

SampleFocus samples a point that is more concentrated in the direction of Target.

type PhongMaterial

type PhongMaterial struct {
	// Alpha controls the specular light, where 0 means
	// unconcentrated, and higher values mean more
	// concentrated.
	Alpha float64

	SpecularColor Color
	DiffuseColor  Color
	EmissionColor Color
	AmbientColor  Color

	// NoFluxCorrection can be set to true to disable
	// the max-Phong denominator.
	NoFluxCorrection bool
}

PhongMaterial implements the Phong reflection model.

https://en.wikipedia.org/wiki/Phong_reflection_model.

func (*PhongMaterial) Ambient

func (p *PhongMaterial) Ambient() Color

func (*PhongMaterial) BSDF

func (p *PhongMaterial) BSDF(normal, source, dest model3d.Coord3D) Color

func (*PhongMaterial) Emission

func (p *PhongMaterial) Emission() Color

func (*PhongMaterial) SampleSource

func (p *PhongMaterial) SampleSource(gen *rand.Rand, normal, dest model3d.Coord3D) model3d.Coord3D

SampleSource uses importance sampling to sample in proportion to the reflection weight of a direction.

If there is a diffuse lighting term, it is mixed in for some fraction of the samples.

func (*PhongMaterial) SourceDensity

func (p *PhongMaterial) SourceDensity(normal, source, dest model3d.Coord3D) float64

SourceDensity gets the density of the SampleSource distribution.

type PointLight

type PointLight struct {
	Origin model3d.Coord3D
	Color  Color

	// If true, the ray tracer should use an inverse
	// square relation to dim this light as it gets
	// farther from an object.
	QuadDropoff bool
}

A PointLight is a light eminating from a point and going in all directions equally.

func (*PointLight) ColorAtDistance

func (p *PointLight) ColorAtDistance(distance float64) Color

ColorAtDistance gets the Color produced by this light at some distance.

func (*PointLight) ShadeCollision

func (p *PointLight) ShadeCollision(normal, pointToLight model3d.Coord3D) Color

ShadeCollision determines a scaled color for a surface light collision.

type RayCaster

type RayCaster struct {
	Camera *Camera
	Lights []*PointLight
}

A RayCaster renders objects using simple one-step ray tracing with no recursion.

func (*RayCaster) Render

func (r *RayCaster) Render(img *Image, obj Object)

Render renders the object to an image.

type RecursiveRayTracer

type RecursiveRayTracer struct {
	Camera *Camera
	Lights []*PointLight

	// FocusPoints are functions which cause rays to
	// bounce more in certain directions, with the aim of
	// reducing variance with no bias.
	FocusPoints []FocusPoint

	// FocusPointProbs stores, for each FocusPoint, the
	// probability that this focus point is used to sample
	// a ray (rather than the BRDF).
	FocusPointProbs []float64

	// MaxDepth is the maximum number of recursions.
	// Setting to 0 is almost equivalent to RayCast, but
	// the ray tracer still checks for shadows.
	MaxDepth int

	// NumSamples is the number of rays to sample.
	NumSamples int

	// MinSamples and MaxStddev control early stopping for
	// pixel sampling. If they are both non-zero, then
	// MinSamples rays are sampled, and then more rays are
	// sampled until the pixel standard deviation goes
	// below MaxStddev, or NumSamples samples are taken.
	//
	// Additionally, see Convergence for to customize this
	// stopping criterion.
	MinSamples int
	MaxStddev  float64

	// OversaturatedStddevs controls how few samples are
	// taken at bright parts of the scene.
	//
	// If specified, a pixel may stop being sampled after
	// MinSamples samples if the brightness of that pixel
	// is more than OversaturatedStddevs standard
	// deviations above the maximum brightness (1.0).
	//
	// This can override MaxStddev, since bright parts of
	// the image may have high standard deviations despite
	// having uninteresting specific values.
	OversaturatedStddevs float64

	// Convergence implements a custom convergence
	// criterion.
	//
	// If specified, MaxStddev and OversaturatedStddevs
	// are not used.
	//
	// Convergence is called with the current mean and
	// variance of a pixel, and a return value of true
	// indicates that the ray has converged.
	Convergence func(mean, stddev Color) bool

	// Cutoff is the maximum brightness for which
	// recursion is performed. If small but non-zero, the
	// number of rays traced can be reduced.
	Cutoff float64

	// Antialias, if non-zero, specifies a fraction of a
	// pixel to perturb every ray's origin.
	// Thus, 1 is maximum, and 0 means no change.
	Antialias float64

	// Epsilon is a small distance used to move away from
	// surfaces before bouncing new rays.
	// If nil, DefaultEpsilon is used.
	Epsilon float64

	// LogFunc, if specified, is called periodically with
	// progress information.
	//
	// The frac argument specifies the fraction of pixels
	// which have been colored.
	//
	// The sampleRate argument specifies the mean number
	// of rays traced per pixel.
	LogFunc func(frac float64, sampleRate float64)
}

A RecursiveRayTracer renders objects using recursive tracing with random sampling.

func (*RecursiveRayTracer) RayVariance

func (r *RecursiveRayTracer) RayVariance(obj Object, width, height, samples int) float64

RayVariance estimates the variance of the color components in the rendered image for a single ray path. It is intended to be used to quickly judge how well importance sampling is working.

The variance is averaged over every color component in the image. Antialiasing is not used.

func (*RecursiveRayTracer) Render

func (r *RecursiveRayTracer) Render(img *Image, obj Object)

Render renders the object to an image.

func (*RecursiveRayTracer) RenderVariance added in v0.1.15

func (r *RecursiveRayTracer) RenderVariance(img *Image, obj Object, numSamples int)

RenderVariance computes the variance per pixel using a fixed number of rays per pixel, and writes the results as pixels in an image.

type RefractMaterial

type RefractMaterial struct {
	// IndexOfRefraction is the index of refraction of
	// this material. Values greater than one simulate
	// materials like water or glass, where light travels
	// more slowly than in space.
	IndexOfRefraction float64

	// RefractColor is the mask used for refracted flux.
	RefractColor Color

	// SpecularColor, if specified, indicates that Fresnel
	// reflection should be used with the given color.
	// Typically, if specified, the color of 1's should be
	// used for a white reflection.
	SpecularColor Color
}

RefractMaterial is an approximate refraction material based on a delta function.

Unlike other BSDFs, the BSDF of RefractMaterial is asymmetric, since energy is concentrated and spread out due to refraction.

func (*RefractMaterial) Ambient

func (r *RefractMaterial) Ambient() Color

func (*RefractMaterial) BSDF

func (r *RefractMaterial) BSDF(normal, source, dest model3d.Coord3D) Color

func (*RefractMaterial) DestDensity added in v0.1.5

func (r *RefractMaterial) DestDensity(normal, source, dest model3d.Coord3D) float64

func (*RefractMaterial) Emission

func (r *RefractMaterial) Emission() Color

func (*RefractMaterial) SampleDest added in v0.1.5

func (r *RefractMaterial) SampleDest(gen *rand.Rand, normal,
	source model3d.Coord3D) model3d.Coord3D

func (*RefractMaterial) SampleSource

func (r *RefractMaterial) SampleSource(gen *rand.Rand, normal,
	dest model3d.Coord3D) model3d.Coord3D

func (*RefractMaterial) SourceDensity

func (r *RefractMaterial) SourceDensity(normal, source, dest model3d.Coord3D) float64

type SphereAreaLight added in v0.1.5

type SphereAreaLight struct {
	Object
	// contains filtered or unexported fields
}

SphereAreaLight is a perfect sphere implementing an area light.

func NewSphereAreaLight added in v0.1.5

func NewSphereAreaLight(s *model3d.Sphere, emission Color) *SphereAreaLight

NewSphereAreaLight turns a sphere collider into an area light.

func (*SphereAreaLight) SampleLight added in v0.1.5

func (s *SphereAreaLight) SampleLight(gen *rand.Rand) (point, normal model3d.Coord3D,
	emission Color)

func (*SphereAreaLight) TotalEmission added in v0.2.0

func (s *SphereAreaLight) TotalEmission() float64

type SphereFocusPoint

type SphereFocusPoint struct {
	// Center and Radius controls the position and size of
	// the sphere to sample.
	Center model3d.Coord3D
	Radius float64

	// MaterialFilter, if non-nil, is called to see if a
	// given material needs to be focused on a light.
	MaterialFilter func(m Material) bool
}

SphereFocusPoint uses a distribution that samples rays which hit a specific sphere.

func (*SphereFocusPoint) FocusDensity

func (s *SphereFocusPoint) FocusDensity(mat Material, point, normal, source,
	dest model3d.Coord3D) float64

FocusDensity gives the probability density ratio for the given direction.

func (*SphereFocusPoint) SampleFocus

func (s *SphereFocusPoint) SampleFocus(gen *rand.Rand, mat Material, point, normal,
	dest model3d.Coord3D) model3d.Coord3D

SampleFocus samples a point that is more concentrated in the direction of Target.

Jump to

Keyboard shortcuts

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