phong

package
v0.3.5 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2024 License: BSD-3-Clause Imports: 14 Imported by: 0

README

Phong is a Blinn-Phong rendering system in gpu

Blinn-Phong is a standard lighting model that used to be built into OpenGL, and is widely used in 3D graphics: wikipedia Blinn-Phong, learnopengl.com.

This package provides a "middleware" layer between the basic gpu package and a complete end-user framework like xyz which can focus on how to organize the scenegraph data structures, and then relies on phong to mange the gpu-side rendering efficiently.

Usage

Phong uses the "Set and Reset" paradigm for all resources, which is generally suited to most 3D use-cases. Meshes, Textures and Objects must be Set before they are used in a render pass (and further Set calls with the same unique name id just update existing properties). There is no further Config call or anything: everything is dynamically updated in the Set call. Note that the Phong object must have been created with an active GPU instance and renderer, before calling any Set calls.

If there is any drastic change to the overall scene configuration, Reset removes all of the existing items. Otherwise, any unused items just take up space on the GPU, but do not incur additional runtime costs.

See [examples/phong] for a working example.

    // needs a gpu.GPU, and a gpu.Renderer, e.g., the gpu.Surface
    ph := phong.NewPhong(sf.GPU, sf)
    
    // add lights
    ph.AddDirectional(math32.NewVector3Color(color.White), math32.Vec3(0, 1, 1))
    ...
    
    // add meshes
    ph.SetMesh("sphere", shape.NewSphere(.5, 64))
    ...
    
    // set textures
    ph.SetTexture(fn, phong.NewTexture(imgs[i])) // go image.Image, ideally RGBA
    ...

    // set objects
    ph.SetObject(nm, phong.NewObject(&ob.Matrix, ob.Color, color.Black, 30, 1, 1))
    ...
    
    // set the camera matricies
    ph.SetCamera(view, projection)
    
    ph.Config() // configures everything for current settings -- only call once
    
    // can call ph.ConfigMeshes(), ph.ConfigTextures(), ph.ConfigLights()
    // to update any of those elements if they change

    // render, to a surface:
    rp, err := ph.RenderStart() // uploads updated object data too
    for i, ob := range objects {
        ph.UseObjectIndex(i)
        ph.UseMeshName(ob.Mesh)
        if ob.Texture != "" {
            ph.UseTextureName(ob.Texture)
        } else {
            ph.UseNoTexture()
        }
    }
    ph.RenderEnd(rp)

Features

Supports 4 different types of lights, with a max of 8 instances of each light type:

  • Ambient: light emitted from everywhere -- provides a background of diffuse light bouncing around in all directions.

  • Directional: light directed along a given vector (specified as a position of a light shining toward the origin), with no attenuation. This is like the sun.

  • Point: an omnidirectional light with a position and associated decay factors, which divide the light intensity as a function of linear and quadratic distance. The quadratic factor dominates at longer distances.light radiating out in all directdions from a specific point,

  • Spot: a light with a position and direction and associated decay factors and angles, which divide the light intensity as a function of linear and quadratic distance. The quadratic factor dominates at longer distances.

Meshes are indexed triangles.

There are 3 rendering pipelines:

  • OneColor: a single color for the entire mesh.
  • Texture: color comes from texture image
  • PerVertex: color is provided per vertex by the mesh.

The color model has the following factors:

  • Color = main color of surface arising from one of the 3 sources listed above, used for both ambient and diffuse color in standard Phong model. The alpha component determines transparency. Note that transparent objects require more complex rendering, to sort objects as a function of depth.
  • Emissive = color that surface emits independent of any lighting, i.e., glow, can be used for marking lights with an object.
  • Shiny = specular shininess factor, which determines how focally the surface shines back directional light. This is an exponential factor, where 0 = very broad diffuse reflection, and higher values (typically max of 128) have a smaller more focal specular reflection. Default is 30.
  • Reflect = reflectiveness of the surface in the region where specular reflected light is emitted, where 1 = full shiny white reflection (specular) color and 0 = no shine reflection. The specular color is always set to white, which will reflect the light color accurately.
  • Bright = overall multiplier on final computed color value. Can be used to tune the overall brightness of various surfaces relative to each other for a given set of lighting parameters.

Layout of Vars

Without push constants in WebGPU, we maintain an Objects group with per-object dynamic offset data, that is selected with the UseObject* function on each render step. This means that the phong system must know about all the objects in advance.

Group: -2 Vertex
    Role: Vertex
        Var: 0:	Pos	Float32Vector3	(size: 12)	Values: 8
        Var: 1:	Normal	Float32Vector3	(size: 12)	Values: 8
        Var: 2:	TexCoord	Float32Vector2	(size: 8)	Values: 8
        Var: 3:	VertexColor	Float32Vector4	(size: 16)	Values: 8
    Role: Index
        Var: 0:	Index	Uint32	(size: 4)	Values: 8
Group: 0 Camera
    Role: Uniform
        Var: 0:	Camera	Struct	(size: 128)	Values: 1
Group: 1 Objects
    Role: Uniform
        Var: 0:	Object	Struct	(size: 192)	Values: 1
Group: 2 Lights
    Role: Uniform
        Var: 0:	NLights	Struct	(size: 16)	Values: 1
        Var: 1:	Ambient	Struct[8]	(size: 16)	Values: 1
        Var: 2:	Directional	Struct[8]	(size: 32)	Values: 1
        Var: 3:	Point	Struct[8]	(size: 48)	Values: 1
        Var: 4:	Spot	Struct[8]	(size: 64)	Values: 1
Group: 3 Texture
    Role: SampledTexture
        Var: 0:	TexSampler	TextureRGBA32	(size: 4)	Values: 1

Documentation

Index

Constants

View Source
const MaxLights = 8

MaxLights is upper limit on number of any given type of light

Variables

This section is empty.

Functions

func CameraViewMat

func CameraViewMat(pos, target, up math32.Vector3) *math32.Matrix4

CameraViewMat returns the camera view matrix, based position of camera facing at target position, with given up vector.

Types

type Ambient

type Ambient struct {
	// color of light, which multiplies ambient color of materials.
	Color math32.Vector3
	// contains filtered or unexported fields
}

Ambient provides diffuse uniform lighting. Typically only one of these.

type Camera

type Camera struct {
	// View Camera: transforms world into camera-centered, 3D coordinates.
	View math32.Matrix4

	// Projection Camera: transforms camera coords into 2D render coordinates.
	Projection math32.Matrix4
}

Camera contains the camera view and projection matricies, for uniform uploading.

type Colors

type Colors struct {
	// main color of surface, used for both ambient and diffuse color
	// in standard Phong model. Alpha component determines transparency.
	// Note that transparent objects require more complex rendering.
	Color math32.Vector4

	// ShinyBright has shininess and brightness factors:
	//
	// X = shininess spread factor (30 default), which determines
	// 	how focally the surface shines back directional light, which
	// 	is an exponential factor, where 0 = very broad diffuse reflection,
	// 	and higher values (typically max of 128) have a smaller more
	// 	focal specular reflection.
	//
	// Y = shine reflection factor (1 default), which determines how much
	//		of the incident light is reflected back (0 = no shine).
	//
	// Z = brightness factor (1 default), which is an overall multiplier
	// 	on final computed color value, which can be used to tune the
	//		overall brightness of various surfaces relative to each other
	//		for a given set of lighting parameters.
	ShinyBright math32.Vector4

	// color that surface emits independent of any lighting,
	// i.e., glow. Can be used for marking lights with an object.
	Emissive math32.Vector4

	// texture tiling repeat and offset factors.
	Tiling Tiling
}

Colors are the material colors with padding for direct uploading to shader.

func NewColors

func NewColors(clr, emis color.Color, shiny, reflect, bright float32) *Colors

NewColors returns a new Colors with given values. Texture defaults to using full texture with 0 offset.

func (*Colors) Defaults

func (cl *Colors) Defaults()

func (*Colors) SetColors

func (cl *Colors) SetColors(clr, emis color.Color, shiny, reflect, bright float32) *Colors

SetColors sets the colors from standard Go colors.

func (*Colors) SetTilingOffset

func (cl *Colors) SetTilingOffset(offset math32.Vector2) *Colors

SetTilingOffset sets texture start offsets in each direction

func (*Colors) SetTilingRepeat

func (cl *Colors) SetTilingRepeat(repeat math32.Vector2) *Colors

SetTilingRepeat sets how often to repeat the texture in each direction

func (*Colors) UseFullTexture

func (cl *Colors) UseFullTexture() *Colors

UseFullTexture sets the texture parameters to render the full texture: repeat = 1,1; offset = 0,0

type Directional

type Directional struct {
	// color of light at full intensity.
	Color math32.Vector3

	// position of light vector. Think of it shining down from
	// this position toward the origin, i.e., the negation of
	// this position is the vector.
	Pos math32.Vector3
	// contains filtered or unexported fields
}

Directional is directional light, which is assumed to project light toward the origin based on its position, with no attenuation, like the Sun. For rendering, the position is negated and normalized to get the direction vector (i.e., absolute distance doesn't matter).

type Groups

type Groups int32 //enums:enum

Groups are the VarGroup numbers.

const (
	CameraGroup Groups = iota
	ObjectGroup
	LightGroup
	TextureGroup
)
const GroupsN Groups = 4

GroupsN is the highest valid value for type Groups, plus one.

func GroupsValues

func GroupsValues() []Groups

GroupsValues returns all possible values for the type Groups.

func (Groups) Desc

func (i Groups) Desc() string

Desc returns the description of the Groups value.

func (Groups) Int64

func (i Groups) Int64() int64

Int64 returns the Groups value as an int64.

func (Groups) MarshalText

func (i Groups) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*Groups) SetInt64

func (i *Groups) SetInt64(in int64)

SetInt64 sets the Groups value from an int64.

func (*Groups) SetString

func (i *Groups) SetString(s string) error

SetString sets the Groups value from its string representation, and returns an error if the string is invalid.

func (Groups) String

func (i Groups) String() string

String returns the string representation of this Groups value.

func (*Groups) UnmarshalText

func (i *Groups) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (Groups) Values

func (i Groups) Values() []enums.Enum

Values returns all possible values for the type Groups.

type NLights

type NLights struct {
	Ambient     int32
	Directional int32
	Point       int32
	Spot        int32
}

Number of different lights active.

func (*NLights) Reset

func (nl *NLights) Reset()

type Object

type Object struct {
	Colors

	// Matrix specifies the transformation matrix for this specific Object ("model").
	Matrix math32.Matrix4
	// contains filtered or unexported fields
}

Object is the object-specific data: Colors and transform Matrix. It must be updated on a per-object basis prior to each render pass. It is 8 vec4 in size = 8 * 4 * 4 = 128 bytes.

func NewObject

func NewObject(mtx *math32.Matrix4, clr *Colors) *Object

NewObject returns a new object with given matrix and colors.

type Phong

type Phong struct {
	// The current camera view and projection matricies.
	// This is used for updating the object WorldMatrix.
	Camera Camera

	// number of each type of light
	NLights NLights

	// ambient lights
	Ambient [MaxLights]Ambient

	// directional lights
	Directional [MaxLights]Directional

	// point lights
	Point [MaxLights]Point

	// spot lights
	Spot [MaxLights]Spot

	// a texture was selected for next draw via [UseTexture].
	// if true, overrides other options.
	UseCurTexture bool

	// a per-vertex color was selected for next draw.
	UseVertexColor bool

	// render using wireframe instead of filled polygons.
	// this must be set prior to configuring the Phong rendering system.
	// note: not currently supported in WebGPU.
	Wireframe bool `default:"false"`

	// rendering system
	System *gpu.GraphicsSystem

	// overall lock on Phong operations, use Lock, Unlock on Phong
	sync.Mutex
	// contains filtered or unexported fields
}

Phong implements standard Blinn-Phong rendering pipelines in a gpu GraphicsSystem. Add Lights and call SetMesh, SetTexture, SetObject to config.

Rendering starts with RenderStart, followed by Use* calls to specify the render parameters for each item, followed by the Render() method that calls the proper pipeline's render methods.

func NewPhong

func NewPhong(gp *gpu.GPU, rd gpu.Renderer) *Phong

NewPhong returns a new Phong system that is ready to be configured by calls to SetMesh, SetTexture, SetObject, in addition to adding lights. Renderer can either be a Surface or a RenderTexture.

func (*Phong) AddAmbient

func (ph *Phong) AddAmbient(color math32.Vector3)

AddAmbient adds Ambient light at given position

func (*Phong) AddDirectional

func (ph *Phong) AddDirectional(color, pos math32.Vector3)

AddDirectional adds directional light

func (*Phong) AddPoint

func (ph *Phong) AddPoint(color, pos math32.Vector3, linDecay, quadDecay float32)

AddPoint adds point light. Defaults: linDecay=.1, quadDecay=.01

func (*Phong) AddSpot

func (ph *Phong) AddSpot(color, pos, dir math32.Vector3, angDecay, cutAngle, linDecay, quadDecay float32)

AddSpot adds spot light Defaults: angDecay=15, cutAngle=45 (max 90), linDecay=.01, quadDecay=0.001

func (*Phong) ConfigLights

func (ph *Phong) ConfigLights() *Phong

ConfigLights can be called after initial Config whenver the Lights data has changed, to sync changes up to the GPU.

func (*Phong) Release

func (ph *Phong) Release()

Release should be called to release all the GPU resources.

func (*Phong) Render

func (ph *Phong) Render(rp *wgpu.RenderPassEncoder)

Render does one step of rendering given current Use* settings, which can be updated in between subsequent Render calls.

func (*Phong) RenderEnd

func (ph *Phong) RenderEnd(rp *wgpu.RenderPassEncoder)

func (*Phong) RenderOneColor

func (ph *Phong) RenderOneColor(rp *wgpu.RenderPassEncoder)

RenderOneColor renders current settings to onecolor pipeline.

func (*Phong) RenderStart

func (ph *Phong) RenderStart() (*wgpu.RenderPassEncoder, error)

RenderStart starts the render pass, returning the RenderPassEncoder used for encoding the rendering commands for this pass. This also ensures that all updated object data from SetObject* calls is transferred to the GPU.

func (*Phong) RenderTexture

func (ph *Phong) RenderTexture(rp *wgpu.RenderPassEncoder)

RenderTexture renders current settings to texture pipeline

func (*Phong) RenderVertexColor

func (ph *Phong) RenderVertexColor(rp *wgpu.RenderPassEncoder)

RenderVertexColor renders current settings to vertexcolor pipeline

func (*Phong) ResetAll

func (ph *Phong) ResetAll()

ResetAll resets all the dynamic resources: Objects, Meshes, Textures and Lights.

func (*Phong) ResetLights

func (ph *Phong) ResetLights()

ResetLights resets number of lights to 0 -- for reconfig

func (*Phong) ResetMeshes

func (ph *Phong) ResetMeshes()

ResetMeshes resets the meshes for reconfiguring.

func (*Phong) ResetObjects

func (ph *Phong) ResetObjects()

ResetObjects resets the objects for reconfiguring

func (*Phong) ResetTextures

func (ph *Phong) ResetTextures()

ResetTextures resets all textures

func (*Phong) SetAmbient

func (ph *Phong) SetAmbient(idx int, color math32.Vector3)

SetAmbient sets Ambient light at index to given position

func (*Phong) SetCamera

func (ph *Phong) SetCamera(view, projection *math32.Matrix4)

SetCamera the camera view and projection matrixes, and updates uniform data, so they are ready to use.

func (*Phong) SetDirectional

func (ph *Phong) SetDirectional(idx int, color, pos math32.Vector3)

SetDirectional sets directional light at given index

func (*Phong) SetMesh

func (ph *Phong) SetMesh(name string, mesh shape.Mesh)

SetMesh sets a Mesh using the shape.Mesh interface for the source of the mesh data, and sets the values directly. If Mesh already exists, then data is updated. It is ready for [UseMesh] after this point.

func (*Phong) SetObject

func (ph *Phong) SetObject(name string, ob *Object)

SetObject sets Object data with given unique name identifier. If object already exists, then data is updated if different.

func (*Phong) SetPoint

func (ph *Phong) SetPoint(idx int, color, pos math32.Vector3, linDecay, quadDecay float32)

SetPoint sets point light at given index. Defaults: linDecay=.1, quadDecay=.01

func (*Phong) SetSpot

func (ph *Phong) SetSpot(idx int, color, pos, dir math32.Vector3, angDecay, cutAngle, linDecay, quadDecay float32)

SetSpot sets spot light at given index Defaults: angDecay=15, cutAngle=45 (max 90), linDecay=.01, quadDecay=0.001

func (*Phong) SetTexture

func (ph *Phong) SetTexture(name string, tx *Texture)

SetTexture sets given Texture to be available for [UseTexture] call during render. If it already exists, it is updated, otherwise added.

func (*Phong) UseMesh

func (ph *Phong) UseMesh(name string) error

UseMesh selects mesh by name for current render step. Mesh must have been added / updated via SetMesh method. If mesh has per-vertex colors, these are selected for rendering, and texture is turned off. UseTexture* after this to override.

func (*Phong) UseNoTexture

func (ph *Phong) UseNoTexture()

UseNoTexture turns off texture rendering

func (*Phong) UseObject

func (ph *Phong) UseObject(name string) error

UseObject selects object by name for current render step. Object must have already been added / updated via [SetObject]. If object has per-vertex colors, these are selected for rendering, and texture is turned off. UseTexture* after this to override.

func (*Phong) UseObjectIndex

func (ph *Phong) UseObjectIndex(idx int) error

UseObjectIndex selects object by index for current render step. If object has per-vertex colors, these are selected for rendering, and texture is turned off. UseTexture* after this to override.

func (*Phong) UseTexture

func (ph *Phong) UseTexture(name string) error

UseTexture selects texture by name for current render step.

type Point

type Point struct {
	// color of light a full intensity.
	Color math32.Vector3

	// position of light in world coordinates.
	Pos math32.Vector3

	// X = Linear distance decay factor (default .01).
	// Y = Quadratic distance quadratic decay factor
	// (default .001, dominates at longer distances)
	Decay math32.Vector3
	// contains filtered or unexported fields
}

Point is an omnidirectional light with a position and associated decay factors, which divide the light intensity as a function of linear and quadratic distance. The quadratic factor dominates at longer distances.

type Spot

type Spot struct {
	// color of light a full intensity.
	Color math32.Vector3

	// position of light in world coordinates.
	Pos math32.Vector3

	// direction of light vector.
	Dir math32.Vector3

	// X = Angular decay, in degrees (15 default)
	// Y = CutAngle is cutoff angle in degrees beyond which no light (45 default).
	// Z = LinDecay distance linear decay (.01 default)
	// W = QuadDecay distance Distance quadratic decay factor (0.001 default),
	//     which dominates at longer distances
	Decay math32.Vector4
	// contains filtered or unexported fields
}

Spotlight is a light with a position and direction and associated decay factors and angles, which divide the light intensity as a function of linear and quadratic distance. The quadratic factor dominates at longer distances.

type Texture

type Texture struct {
	Image *image.RGBA
}

Texture has texture image and other params. Stored as image.RGBA for GPU compatibility.

func NewTexture

func NewTexture(img image.Image) *Texture

func (*Texture) Set

func (tx *Texture) Set(img image.Image) *Texture

Set sets texture from Go image.

type Tiling

type Tiling struct {

	// how often to repeat the texture in each direction
	Repeat math32.Vector2

	// offset for when to start the texure in each direction
	Offset math32.Vector2
}

Tiling are the texture tiling parameters

func (*Tiling) Defaults

func (tl *Tiling) Defaults()

Defaults sets default tiling params if not yet initialized

Jump to

Keyboard shortcuts

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