core

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2017 License: BSD-2-Clause Imports: 11 Imported by: 0

Documentation

Overview

Package core provides core interfaces and main render control paths.

Index

Constants

View Source
const (
	RayTypeCamera uint32 = (1 << iota)
	RayTypeShadow
	RayTypeReflected
	RayTypeRefracted
	RayTypeGlossy
)

Ray type bit flags.

View Source
const (
	VersionMajor   = 0
	VersionMinor   = 3
	VersionPatch   = 0
	VersionRelease = "alpha"
)

Version constants.

View Source
const ShadowRayEpsilon float32 = 0.0001

ShadowRayEpsilon ensures no self-intersecting shadow rays.

Variables

View Source
var (
	ErrNodeAlreadyRegistered = errors.New("Node type already registered.")
	ErrNodeNotRegistered     = errors.New("Node type not registered")
	ErrNotNode               = errors.New("Object is not Node")

	ErrNoSample = errors.New("No sample")

	ErrNoCamera = errors.New("No camera")
)

Common errors.

Functions

func AddNode

func AddNode(node Node)

AddNode adds a node to the core.

func FrameAspect

func FrameAspect() float32

FrameAspect returns the aspect ratio of the current framebuffer.

func FrameBuf

func FrameBuf() []float32

FrameBuf returns the []float32 slice of pixels

func FrameMetrics

func FrameMetrics() (int, int)

FrameMetrics returns the width and height of the current framebuffer.

func Init

func Init(s Scene)

Init initializes the core system with the given Scene.

func PostRender

func PostRender() error

PostRender is called on all nodes once Render has returned.

func PreRender

func PreRender() error

PreRender is called after all nodes are loaded and calls PreRender on all nodes. Nodes may add new nodes so PreRender iterates until no new nodes are created.

func Trace

func Trace(ray *Ray, samp *TraceSample) bool

Trace intersects ray with the scene and evaluates the shader at the first intersection. The result is returned in the samp struct. Returns true if any intersection or false for none.

func TraceProbe

func TraceProbe(ray *Ray, sg *ShaderContext) bool

TraceProbe intersects ray with the scene and sets up the globals sg with the first intersection. rays of type RayTypeShadow will early-out and not necessarily return the first intersection. Returns true if any intersection or false for none.

func VersionString

func VersionString() string

VersionString returns a string representing the current software version.

Types

type BSDF

type BSDF interface {
	// Sample returns a direction given two (quasi)random numbers. NOTE: returned vector in WORLD space.
	Sample(r0, r1 float64) m.Vec3
	// Eval evaluates the BSDF given the incoming direction. Returns value multiplied by cosine
	// of angle between omegaO and the normal. NOTE: omegaO is in WORLD space.
	Eval(omegaO m.Vec3) colour.Spectrum
	// PDF returns the probability density function for the given sample. NOTE: omegaO is in WORLD space.
	PDF(omegaO m.Vec3) float64
}

BSDF represents a BRDF or BTDF that can be sampled. The core API only considers the incoming direction so all other parameters should be stored in the concrete instance of the individual BRDFs. This is used for Multiple Importance Sampling with light sources.

type BSDFSample

type BSDFSample struct {
	D        m.Vec3
	Pdf      float64
	PdfLight float32
	Liu      colour.Spectrum
	Ld       m.Vec3
	Ldist    float32
}

type Camera

type Camera interface {
	// ComputeRay should return a world-space ray within the given pixel.
	ComputeRay(sc *ShaderContext, lensU, lensV float64, ray *Ray)
}

Camera represents a 3D camera.

type Framebuffer

type Framebuffer struct {
	Width, Height int
	Buf           []float32
}

Framebuffer represents a buffer of pixels, RGB or deep.

func (*Framebuffer) Aspect

func (fb *Framebuffer) Aspect() float32

Aspect returns the aspect ratio of this framebuffer.

type Fresnel

type Fresnel interface {
	// Kr returns the fresnel value.  cos_theta is the clamped dot product of
	// view direction and surface normal.
	Kr(cosTheta float32) colour.RGB
}

Fresnel represents a Fresnel model.

type Geom

type Geom interface {
	// Trace returns true if ray hits something. Usually this is the first hit along the ray
	// unless ray.Type &= RayTypeShadow.
	Trace(*Ray, *ShaderContext) bool

	// MotionKeys returns the number of motion keys for this primitive.
	MotionKeys() int

	// Bounds returns the world space bounding volume for the given time.
	Bounds(float32) m.BoundingBox
}

The Geom interface represents all of the basic intersectable shapes.

type Globals

type Globals struct {
	NodeDef       NodeDef `node:",opt"`
	XRes, YRes    int     `node:",opt"`
	UseProgress   bool    `node:",opt"`
	MaxGoRoutines int     `node:",opt"`
	Camera        string  `node:",opt"`
	MaxIter       int     `node:",opt"`
	Output        string  `node:",opt"`
}

Globals is a node representing the global render settings.

func (*Globals) Def

func (g *Globals) Def() NodeDef

Def is a node method.

func (*Globals) Name

func (g *Globals) Name() string

Name is a node method.

func (*Globals) PostRender

func (g *Globals) PostRender() error

PostRender is a node method.

func (*Globals) PreRender

func (g *Globals) PreRender() error

PreRender is a node method.

type Image

type Image struct {
	PixelDelta [2]float32 // Size of pixel
}

// Bit of a hack

type Light

type Light interface {

	// SampleArea samples n points on the surface of the light by area as seen from given ShaderGlobals point.
	// sg.Lsamples should be filled with the samples using append.
	// Returns nil on successful sample.
	SampleArea(sg *ShaderContext, n int) error

	// DiffuseShadeMult returns the diffuse lighting multiplier.
	DiffuseShadeMult() float32

	// NumSamples returns the number of samples that should be taken from this light for the
	// given context.
	NumSamples(sg *ShaderContext) int

	// ValidSample returns true if the BSDF sample will hit light and fills in sample with the unoccluded light
	// value.
	ValidSample(sg *ShaderContext, sample *BSDFSample) bool

	// Geom returns the Geom associated with this light.
	Geom() Geom
}

Light represents a light that can be sampled by the system.

type LightSample

type LightSample struct {
	P     m.Vec3
	Pdf   float32
	Liu   colour.Spectrum
	Ld    m.Vec3
	Ldist float32
}

LightSample is used for direct lighting samples.

type Node

type Node interface {

	// Name returns the name of the node.
	Name() string

	// Def returns where this node was defined.
	Def() NodeDef

	// PreRender is called after loading scene and before render starts.  Nodes should
	// perform all init and may add other nodes in PreRender.
	PreRender() error

	// PostRender is called after render is complete.
	PostRender() error
}

Node represents a node in the core system.

func FindNode

func FindNode(name string) Node

FindNode finds the node with the given name.

type NodeDef

type NodeDef struct {
	Where    string // Filename or name of node for auto-generated nodes.
	Col, Row int    // Column and row in file (if applicable)
}

NodeDef represents where a node is defined.

type PixelFilter

type PixelFilter interface {
	WarpSample(r0, r1 float64) (float64, float64)
}

PixelFilter nodes represent sample warp filters for Filter Importance Sampling.

type Ray

type Ray struct {
	P, D       m.Vec3     // Position and direction
	Dinv       m.Vec3     // 1/direction
	Tclosest   float32    // t value of intersection (here instead of in Result to aid cache)
	S          [3]float32 // Precalculated ray-triangle members
	Kx, Ky, Kz int32      // Precalculated ray-triangle members

	// 64 bytes to here
	Time, Lambda float32 // Time value and wavelength
	X, Y         int32   // Raster position
	Sx, Sy       float32 // Screen space coords [-1,1]x[-1,1]
	Level        uint8
	Type         uint32    // Ray type bits
	I            int       // pixel sample index
	Scramble     [2]uint64 // Pixel scramble values used for light/glossy scrambling

	// Ray differentials
	DdPdx, DdPdy m.Vec3 // Ray differential
	DdDdx, DdDdy m.Vec3 // Ray differential

	NodesT, LeafsT int

	Task *RenderTask
	// contains filtered or unexported fields
}

Ray is a mostly public structure used by individual intersection routines. These should only ever be created with ShaderContext.NewRay as they need to be in the pool.

func (*Ray) DifferentialTransfer

func (r *Ray) DifferentialTransfer(sc *ShaderContext)

func (*Ray) Init

func (r *Ray) Init(ty uint32, P, D m.Vec3, maxdist float32, level uint8, sc *ShaderContext)

Init sets up the ray. ty should be bitwise combination of RAY_ constants. P is the start point and D is the direction. maxdist is the length of the ray. sg is used to get the Lambda, Time parameters and ray differntial calculations.

func (*Ray) Setup

func (r *Ray) Setup()

Setup should be called after P and D have been set, this will precalculate various values for triangle intersection. This is called by Init but sometimes may need to call it manually.

type RenderStats

type RenderStats struct {
	Duration                 time.Duration
	RayCount, ShadowRayCount uint64
	// contains filtered or unexported fields
}

RenderStats collects stats for the whole render.

func Render

func Render(maxIter int, exit chan bool) (RenderStats, error)

Render is called to start the render process.

func (RenderStats) String

func (s RenderStats) String() string

String returns string representation of stats.

type RenderTask

type RenderTask struct {
	Traversal struct {
		T        [4]float32         // Temporary T values, MUSE be aligned to 16 bytes
		Hits     [4]int32           // Temporary hit values, MUSE be aligned to 16 bytes
		Boxes    [4 * 3 * 2]float32 // Temporary boxes structure, MUST be aligned to 16 bytes
		StackTop int32              // This is the top of the stack for any traversal to start from
		Stack    [90]struct {
			T    float32
			Node int32
		}
	}
	// contains filtered or unexported fields
}

RenderTask represents an image tile. One of these is allocated per goroutine so no worries about thread safety.

func (*RenderTask) NewRay

func (rc *RenderTask) NewRay() *Ray

NewRay allocates a ray from the pool.

func (*RenderTask) NewShaderContext

func (rc *RenderTask) NewShaderContext() *ShaderContext

NewShaderContext allocates a ShaderContext from the pool.

func (*RenderTask) ReleaseRay

func (rc *RenderTask) ReleaseRay(ray *Ray)

ReleaseRay releases ray to pool.

func (*RenderTask) ReleaseShaderContext

func (rc *RenderTask) ReleaseShaderContext(sc *ShaderContext)

ReleaseShaderContext releases context back to pool.

type Scene

type Scene interface {
	// Trace returns true if ray hits something. Usually this is the first hit along the ray
	// unless ray.Type &= RayTypeShadow.
	Trace(*Ray, *ShaderContext) bool

	// LightsPrepare initializes the context with a potential set of lights.
	LightsPrepare(*ShaderContext)

	// AddGeom adds the geom to the scene.
	AddGeom(Geom) error

	// AddLight adds the light to the scene.
	AddLight(Light) error

	// PreRender is called after all other nodes PreRender.
	PreRender() error
}

Scene represents the top level scene.

type Shader

type Shader interface {
	// Eval evaluates the shader and returns values in sh.OutXXX members.
	Eval(sc *ShaderContext)

	// EvalEmission evaluates the shader and returns emission value.
	EvalEmission(sc *ShaderContext, omegaO m.Vec3) colour.RGB
}

Shader represents a surface shader (Note: this will be renamed to Shader or SurfaceShader).

type ShaderContext

type ShaderContext struct {
	X, Y                int32     // raster positions
	Sx, Sy              float32   // screen space [-1,1]x[-1,1]
	RayType             uint16    // Ray type
	Level               uint8     // Recursive level of sample (0 for first hit)
	I, Sample, NSamples int       // pixel sample index, sample index, total samples
	Scramble            [2]uint64 // Per pixel scramble values for lights and glossy
	Weight              float32   // Sample weight
	Lambda              float32   // Wavelength
	Time                float32
	Ro, Rd              m.Vec3         // Ray origin and direction
	Rl                  float64        // Ray length (|Ro-P|)
	ElemID              uint32         // Element ID (triangle, curve etc.)
	Geom                Geom           // Geom pointer
	Psc                 *ShaderContext // Parent (last shaded)
	Shader              Shader

	Transform, InvTransform m.Matrix4

	Po, P, Poffset m.Vec3 // Shading point in object/world space

	N, Nf, Ng, Ngf, Ns m.Vec3  // Shading normal, face-forward shading normal, geometric normal, face-forward geom normal, smoothed normal (N without bump)
	DdPdu, DdPdv       m.Vec3  // Derivative vectors
	Bu, Bv             float32 // Barycentric U&V
	U, V               float32 // Surface params

	// Ray differentials
	DdPdx, DdPdy   m.Vec3 // Ray differential
	DdDdx, DdDdy   m.Vec3 // Ray differential
	DdNdx, DdNdy   m.Vec3 // Normal derivatives
	Dduvdx, Dduvdy m.Vec2 // texture/surface param derivs

	Lights   []Light // Array of active lights in this shading context
	Lidx     int     // Index of current light
	Lsamples []LightSample
	Lp       Light // Light pointer (current light)

	Area float32

	Image *Image // Image constant values stored here

	OutRGB      colour.RGB
	OutSpectrum colour.Spectrum
	// contains filtered or unexported fields
}

ShaderContext encapsulates all of the data needed for evaluating shaders. These should only ever be created with NewShaderContext.

func (*ShaderContext) ApplyTransform

func (sc *ShaderContext) ApplyTransform()

ApplyTransform applies Transfomrm to appropriate fields to go from object space into world space.

func (*ShaderContext) EvaluateLightSamples

func (sc *ShaderContext) EvaluateLightSamples(bsdf BSDF) colour.RGB

EvaluateLightSamples will evaluate direct lighting for the current light using MIS and return total contribution. This can be weighted by albedo (colour). Will do MIS for diffuse too but just discard any that miss light. Can do BRDF first up to NSamples/2 then any left over samples will be given to light sampling.

func (*ShaderContext) LightsPrepare

func (sc *ShaderContext) LightsPrepare()

LightsPrepare initialises the lighting loop.

func (*ShaderContext) NewRay

func (sc *ShaderContext) NewRay() *Ray

NewRay returns a new ray from the pool.

func (*ShaderContext) NewShaderContext

func (sc *ShaderContext) NewShaderContext() *ShaderContext

NewShaderContext returns a new context from the pool. Should not create these manually.

func (*ShaderContext) NextLight

func (sc *ShaderContext) NextLight() bool

NextLight sets up the ShaderContext for the next relevant light and returns true. If there are no further lights will return false.

func (*ShaderContext) OffsetP

func (sc *ShaderContext) OffsetP(dir int) m.Vec3

OffsetP returns the intersection point pushed out from surface by about 1 ulp. Pass -ve value to push point 'into' surface (for transmission).

func (*ShaderContext) ReleaseRay

func (sc *ShaderContext) ReleaseRay(ray *Ray)

ReleaseRay returns ray to pool

func (*ShaderContext) ReleaseShaderContext

func (sc *ShaderContext) ReleaseShaderContext(sc2 *ShaderContext)

ReleaseShaderContext returns a context to the pool.

type TraceSample

type TraceSample struct {
	Colour  colour.RGB
	Opacity colour.RGB
	Alpha   float32
	Point   m.Vec3
	Z       float64
	ElemID  uint32
	Geom    Geom
}

TraceSample is returned by Trace.

Directories

Path Synopsis
Package param implements parameter types for nodes.
Package param implements parameter types for nodes.

Jump to

Keyboard shortcuts

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