Documentation
¶
Index ¶
- Constants
- func CheckHit(o Object, r *Ray, h *HitRecord)
- func CheckRay(r *Ray)
- func FrontT(t1, t2 float64) float64
- func IndexToCam(w, h int, ix, iy float64) (u, v float64)
- func PixelSize(w, h int) float64
- func Uniform(f ImageFunc, numPass, w, h int, antiAlias bool) Image
- type Camera
- type Ctx
- type HitCoords
- type HitRecord
- type ImageFunc
- type Light
- type Material
- type Medium
- type Object
- type Ray
- type Sampler
- type Scene
- type Stats
- type TransparentMaterial
Examples ¶
Constants ¶
const Tiny = (1. / (1204 * 1024))
Variables ¶
This section is empty.
Functions ¶
func IndexToCam ¶
IndexToCam maps a pixel index {ix, iy} inside an image with given width and height onto a u,v coordinate strictly inside the interval [0,1]. If the image's aspect ratio width:height is not square, then either u or v will not span the entire [0,1] interval.
Half-pixel offsets are applied so that the borders in u,v correspond exactly to pixel borders (not centers). This transformation is sketched below:
+----------------+ (u,v=1,1) | | (x,y=-.5,-.5)+----------------+ | | | | +----------------+ (x,y=w-.5,h-.5) | | (u,v=0,0)+----------------+
Note that the v axis points up, while the y axis points down.
Example ¶
for _, arg := range []struct { w, h int ix, iy float64 }{ {1, 1, -.5, -.5}, {1, 1, 0, 0}, {1, 1, 0.5, 0.5}, {4, 2, -.5, -.5}, {4, 2, 1.5, 0.5}, {4, 2, 3.5, 1.5}, } { x, y := tracer.IndexToCam(arg.w, arg.h, arg.ix, arg.iy) fmt.Printf("[w: %2d, h: %2d]: (% 3.3f, % 3.3f)->(% 3.3f, % 3.3f)\n", arg.w, arg.h, arg.ix, arg.iy, x, y) }
Output: [w: 1, h: 1]: (-0.500, -0.500)->( 0.000, 1.000) [w: 1, h: 1]: ( 0.000, 0.000)->( 0.500, 0.500) [w: 1, h: 1]: ( 0.500, 0.500)->( 1.000, 0.000) [w: 4, h: 2]: (-0.500, -0.500)->( 0.000, 0.750) [w: 4, h: 2]: ( 1.500, 0.500)->( 0.500, 0.500) [w: 4, h: 2]: ( 3.500, 1.500)->( 1.000, 0.250)
Types ¶
type Camera ¶
type Camera interface { // RayFrom constructs a ray starting from position u,v on the image sensor. // u, v are both in the interval [0,1]. // // In case a non-square image is desired, u or v can simply be varied // over a rectangle inside the unit square. // // Ctx should be used to allocate the Ray, // and to generate random lens samples if needed. RayFrom(ctx *Ctx, u, v float64) *Ray }
A Camera maps pixel positions to Rays. Various implementations are in package cameras.
type Ctx ¶
type Ctx struct { CurrentRecursionDepth int // counts recursion depth from 1. AA sequence.Sequence Stats Stats // contains filtered or unexported fields }
Ctx is a "execution context", scoped to the pixel currently being shaded. A Ctx lives though a single pixel shading process, similar to how Go's "context.Context" lives through a single RPC request.
A Ctx carries:
- quasi-random sequences approprately seeded for the pixel
- a storage pool for obtaining and recycling Rays (without allocation)
- statistics about the compute resources used
- the current recursion depth, for aborting recursion
The reason for this is twofold. (1) The random generator, storage pool and statistics are not thread-safe, so each goroutine needs its own instance. This avoids locking, and significantly speeds up execution. (2) Quasi Monte Carlo requires quasi-random numbers that depend on the pixel and recursion depth. Therefore, the context needs access to the recursion depth, and we might as well make the context responsible for limiting recursion depth.
func (*Ctx) GenerateLens ¶
func (*Ctx) IsInitial ¶
IsInitial returns whether this is the context of the initial ray cast by the camera. I.e., returns true when we are at the root of recursion. At the root of recursion, we may apply some expensive Media like fog, or chose to use Quasi Monte Carlo rather than the regular method.
type HitCoords ¶
type HitCoords struct { T float64 // Position along the ray Normal Vec // Normal vector at intersection (needs not have unit length) Local Vec // Local coordinates at intersection, chosen by the Object. E.g. U,V coordinates for objects where this makes sense }
HitCoords record where a Ray intersected an Object.
type HitRecord ¶
type HitRecord struct { T float64 // Position along the ray Normal Vec // Normal vector at intersection (needs not have unit length) Local Vec // Local coordinates at intersection, chosen by the Object. E.g. U,V coordinates for objects where this makes sense Material Material }
A HitRecord records the position and material where a Ray intersected an Object. This allows for lazy evaluation of the Color seen by the Ray, after it has been established that the color is actually going to be used (i.e., the hit point is not occluded by another Object). Without this lazy evaluation, the complexity of recursive ray tracing would become exponential in the recursion depth.
The structure is designed to avoid allocations: It is passed by value, and the Material is only allocated once at initialization time.
type Light ¶
type Light interface { // Object is rendered when a viewing ray sees the light directly. // E.g. for a spherical yellow light source, this object is a // bright yellow sphere. // // Care must be taken that the properties of this object // (size, surface brightness) exactly match the light intensity // obtained by calling Sample(). I.e. The amount of light // that a scene receives from this object via unidirectional path // tracing must be exactly equal to the amout of light // received from Sample() using bidirectional path tracing. Object() Object // Sample returns a position on the light's surface // (used to determine shadows for extended sources), // and the intensity at given target position. Sample(ctx *Ctx, target Vec) (pos Vec, intens Color) }
type Material ¶
type Material interface { // Shade returns the brightness seen by Ray r which intersects // the scene at the given hit coordinates. // // Implementations may call s.LightField recursively, // recursion depth is limited automatically through the context ctx. Shade(ctx *Ctx, s *Scene, r *Ray, h HitCoords) Color }
A Material determines the color of a surface fragment.
type Object ¶
An Object is any thing that can be rendered. E.g., a glass sphere, a white rectangle, ...
type Ray ¶
type Ray struct { Start Vec Dir Vec }
A Ray is a half-line, starting at the Start point (exclusive) and extending in direction Dir.
type Sampler ¶
type Sampler struct { Stats Stats // contains filtered or unexported fields }
A Sampler renders a ray-traced image.
func (*Sampler) Image ¶
func (s *Sampler) Image() Image
Image returns the rendered image currently accumulated by the Sampler. Successive calls to Sample progressively improve this image's quality.
func (*Sampler) SampleWithCancel ¶
TODO: cancellation
type Scene ¶
type Scene struct { RecursionDepth int // contains filtered or unexported fields }
Scene is the ray tracer's central data type. A Scene stores a collection of objects and lights, and provides methods to evaluate the brightness seen by an arbitrary ray (I.e. the light field).
func NewScene ¶
NewScene constructs a scene from objects and light sources. At render time, recursion will be limited to recursionDepth at maximum.
func NewSceneWithMedia ¶
TODO: unify
func (*Scene) ImageFunc ¶
ImageFunc returns an image function that can be sampled to obtain an image of the Scene seen through the given Camera.
The image function expects to be sampled at (u,v) coordinates in the interval [0..1].
Evaluating the image function returns potentially noisy sample, and typically many samples must be averaged to obtain a high-quality image.
The context (*Ctx) is used to generate random numbers deterministically.
TODO: when testing indirect lighting: ImageFunc for non-luminous, lights only
func (*Scene) LightField ¶
LightField returns the light field of all objects in scene.
func (*Scene) LightFieldIndirect ¶
LightFieldIndirect returns the light field the Scene's objects but replaces the light sources by black. This is used by Bi-directional path tracing which adds light sources separately.
func (*Scene) ObjectsAndLights ¶
type Stats ¶
type TransparentMaterial ¶
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package cameras provides various implementations of the camera interface tracer.Camera.
|
Package cameras provides various implementations of the camera interface tracer.Camera. |
Package lights provides implementations of the tracer.Light interface.
|
Package lights provides implementations of the tracer.Light interface. |
Package objects provides concrete implementations of the tracer.Object interface.
|
Package objects provides concrete implementations of the tracer.Object interface. |
Package sequence implements a low-discrepancy sequence for Quasi Monte Carlo integration, and mappings from a uniform sequence to a disk or sphere.
|
Package sequence implements a low-discrepancy sequence for Quasi Monte Carlo integration, and mappings from a uniform sequence to a disk or sphere. |
Package test provides test helpers for BruteRay.
|
Package test provides test helpers for BruteRay. |
Package types provides constants and type aliases that are considered bruteray primitives.
|
Package types provides constants and type aliases that are considered bruteray primitives. |