Material
How a surface looks: its texture, a colour multiplier, and how shiny it is. Shininess and specular strength live HERE rather than on the lights, which is where I first put them and was wrong: they describe the SURFACE. A polished ball and a matte floor lit by the same lamp need different values, and a property that cannot differ between objects in one scene is not a property of the object. ## The tint Multiplied into the final colour, so one texture can dress many objects. A tint of exactly black counts as "untinted" rather than as black -- see the note in the shader: GL leaves an unset uniform at zero, and without that rule a forgotten tint turns everything black, while an object tinted to pure black is indistinguishable from one that is not drawn. ## Not owned A Material does not own its texture. Several materials sharing one texture is the normal case, so freeing the material does not free the texture -- the same rule Scene follows for the mesh and shader it is handed.
Example
metal := Material->New(texture);
metal->SetSpecular(96.0, 0.9);
stone := Material->New(texture);
stone->SetTint(0.7, 0.68, 0.62); # same texture, different colour
box->SetMaterial(metal);Operations
- New
- ClearEmissive
- Colored
- GetNormalMap
- GetOpacity
- HasEmissive
- HasNormalMap
- HasTexture
- IsOpaque
- SetEmissive
- SetOpacity
- SetSpecular
- SetTexture
Colored # function
A material with a tint and no texture, for flat-coloured objects drawn through a textured shader.
function : Colored(r:Float, g:Float, b:Float) ~ MaterialParameters
| Name | Type | Description |
|---|---|---|
| r | Float | red, 0..1 |
| g | Float | green, 0..1 |
| b | Float | blue, 0..1 |
Return
| Type | Description |
|---|---|
| Material | the material |
GetNormalMap #
method : public : GetNormalMap() ~ Texture2DReturn
| Type | Description |
|---|---|
| Texture2D | the normal map, or Nil |
GetOpacity #
method : public : GetOpacity() ~ FloatReturn
| Type | Description |
|---|---|
| Float | the opacity, 1.0 for solid |
HasEmissive #
method : public : HasEmissive() ~ BoolReturn
| Type | Description |
|---|---|
| Bool | true when this material emits any light of its own |
HasNormalMap #
method : public : HasNormalMap() ~ BoolReturn
| Type | Description |
|---|---|
| Bool | true when ApplyTo will bind a normal map |
HasTexture #
Whether this material carries a texture of its own. A material without one does NOT bind anything, so whatever a previous draw left on the unit is what gets sampled. Scene uses this to fall back to the box's own texture rather than let the result depend on draw order.
method : public : HasTexture() ~ BoolReturn
| Type | Description |
|---|---|
| Bool | true when ApplyTo will bind a texture |
IsOpaque #
method : public : IsOpaque() ~ BoolReturn
| Type | Description |
|---|---|
| Bool | true when this material needs no sorting |
New # constructor
An untinted, matte material.
New(texture:Texture2D)Parameters
| Name | Type | Description |
|---|---|---|
| texture | Texture2D | the texture to draw with; may be Nil |
SetEmissive #
Light this surface gives off on its own. Added AFTER the lighting rather than multiplied into it, which is the whole point: SetTint scales what the lights deliver, so a tinted surface can never be brighter than the light falling on it. That is why a relic in an unlit corner is invisible however you tint it, and why a creature standing between the player and their own lamp came out darker than the wall behind it. Emissive is also the right tool when the base texture is the wrong hue. Tinting a GOLD texture blue gives green, because tint multiplies; an emissive term does not care what the texture underneath is. This does not light anything else -- there is no bloom and no light bleed. It makes the surface itself bright.
method : public : SetEmissive(r:Float, g:Float, b:Float) ~ NilParameters
| Name | Type | Description |
|---|---|---|
| r | Float | red, 0..1 and beyond if you want it to bloom out |
| g | Float | green |
| b | Float | blue |
SetOpacity #
How opaque this material is. 1.0 is solid and is the default. Anything less needs blending on and the object drawn after the solid ones -- Scene does both once it knows where the camera is; a program drawing by hand does it with GL->BeginTransparency and GL->EndTransparency. This MULTIPLIES the texture's own alpha rather than replacing it, so a cut-out texture stays cut out at 0.5 opacity instead of turning into a uniformly half-visible rectangle.
method : public : SetOpacity(opacity:Float) ~ NilParameters
| Name | Type | Description |
|---|---|---|
| opacity | Float | 0.0 invisible to 1.0 solid |
SetSpecular #
How tight the highlight is and how strong. Strength defaults to zero, so a material is matte until asked -- a diffuse surface is the right default and an unexpected highlight reads as a bug.
method : public : SetSpecular(shininess:Float, strength:Float) ~ NilParameters
| Name | Type | Description |
|---|---|---|
| shininess | Float | the exponent; 8 is a broad sheen, 128 a tight glint |
| strength | Float | 0 matte, around 0.5 plastic, 1.0 something wet |