tecs.gfx.layers
Depth bands, sorting, coordinate spaces, parallax, and lighting.
A layer occupies one of sixteen depth bands. Entities sort inside their own band and never against another band, so a heads-up display on layer 8 covers a world on layer 1. Extraction turns a layer, a height, and a world position into one depth from zero to one, with zero nearest.
tecs.gfx.layers.configure(1, {sort = "topdown", parallax = 0.4})
tecs.gfx.layers.configure(8, {sort = "z", screenSpace = true, unlit = true, overlay = true})
world:spawn(
tecs.ecs.Transform2D(16, 16, 0, 8, 0, 96, 24),
tecs.gfx.Tint(1, 1, 1, 1),
tecs.gfx.Renderable2D
)The fourth Transform2D argument selects the layer.
The table is process-wide, in the same way component identity is, because one process drives one renderer and a scene's authored depth order cannot differ between two worlds in it.
setExtents names the authored ranges each sort normalizes against. A scene reaching past an extent still draws, resting on the edge, and stops sorting against its neighbors there.
Coordinate spaces#
World coordinates are the default. screenSpace measures a position in target pixels and ignores the camera, which is what a heads-up display wants. virtualCoords measures it in the one authored resolution setVirtualSize names and stretches that resolution to fill the target. ignoreZoom follows the camera's position while keeping the drawn size, and parallax scales how far the camera carries the contents. place resolves all four into one target pixel, and one layer cannot combine screenSpace with virtualCoords.
unlit marks contents that bypass scene lighting, and overlay marks contents that always take the sorted forward lane. Both reach a renderer through entryOf and isOverlay rather than changing anything this module computes.
Module contents
Types
| Type | Kind | Description |
|---|---|---|
Config | type | Defines everything a layer decides about its contents. |
Sort | type | Selects how a layer orders its own contents. |
Functions
| Function | Kind | Description |
|---|---|---|
bandOf | function | Returns the two terms depthIn takes, resolved once for one layer. |
configure | function | Sets what one layer does with its contents. |
depthIn | function | Returns one entity's depth on a band bandOf already resolved. |
depthOf | function | Returns one entity's depth from zero to one, with zero nearest. |
entryOf | function | Returns the four numbers that position and light one layer. |
extents | function | Returns the authored extents every sort normalizes against. |
isOverlay | function | Returns whether a layer always takes the sorted forward lane. |
isScreenSpace | function | Returns whether a layer measures positions in target pixels. |
parallaxOf | function | Returns how much of the camera's movement a layer's contents take. |
place | function | Returns where one authored position lands on the render target. |
resolution | function | Returns the smallest depth difference depthOf produces between two entities one world unit apart, taken over every... |
revision | function | Returns the configuration revision. |
setExtents | function | Replaces the authored extents every sort normalizes against. |
setVirtualSize | function | Replaces the authored resolution every virtual-coordinate layer is measured in. |
sortOf | function | Returns a layer's sort as the identifier depthIn accepts. |
viewCulled | function | Returns whether the camera's view rectangle decides if a layer draws. |
virtualSize | function | Returns the authored resolution every virtual-coordinate layer is measured in. |
Values
| Value | Kind | Description |
|---|---|---|
MAX | variable | The number of bands that divide the depth range. |
MODE_CAMERA | variable | Positions contents in world units, through the camera. |
MODE_SCREEN | variable | Positions contents in target pixels, ignoring the camera. |
MODE_VIRTUAL | variable | Positions contents in the authored virtual resolution, stretched to the target. |
SORT_ISOMETRIC | variable | Sorts by x plus y plus height for a diamond grid. |
SORT_TOPDOWN | variable | Sorts lower screen positions in front and breaks ties with height. |
SORT_Z | variable | Sorts only by height and ignores world position. |
Types#
Configtype#
type Config = {
sort: Sort,
screenSpace: boolean?,
ignoreZoom: boolean?,
virtualCoords: boolean?,
unlit: boolean?,
overlay: boolean?,
parallax: number?
}Defines everything a layer decides about its contents.
A field left out takes its default, so this says what a layer is rather than amending what it was. sort is the one field a caller must set; screenSpace, ignoreZoom, virtualCoords, unlit, and overlay default to false, and parallax defaults to one.
Sorttype#
type Sort = "topdown" | "z" | "isometric"Selects how a layer orders its own contents.
These identifiers reach configuration a developer writes and are a compatibility surface.
Functions#
bandOffunction#
function bandOf(layer: integer): number, integerReturns the two terms depthIn takes, resolved once for one layer.
A caller writing many depths on one layer resolves the band once here rather than once a row.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band to resolve; outside one to |
Returns
| Type | Description |
|---|---|
number | the band's near edge, then the sort identifier |
integer |
configurefunction#
function configure(layer: integer, config: Config): nilSets what one layer does with its contents.
Replaces the layer's configuration rather than amending it, so every omitted field takes its default instead of keeping its previous value.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band to configure, from one to |
config | Config | the complete replacement configuration |
Returns
| Type | Description |
|---|---|
nil |
Raises
when the layer is outside the band range, when the sort is unknown, or when one layer asks for screen pixels and virtual coordinates at once
depthInfunction#
function depthIn(base: number, sort: integer, z: number, x: number, y: number): numberReturns one entity's depth on a band bandOf already resolved.
Arguments
| Name | Type | Description |
|---|---|---|
base | number | the band's near edge, from |
sort | integer | the sort identifier, from |
z | number | the height in the sort, normalized against the height extent |
x | number | the world x, read only by the isometric sort |
y | number | the world y, read by the topdown and isometric sorts, larger being nearer |
Returns
| Type | Description |
|---|---|
number | a depth inside the band, held between 0.001 and 0.999 |
depthOffunction#
function depthOf(layer: integer, z: number, x: number, y: number): numberReturns one entity's depth from zero to one, with zero nearest.
Exact ties carry no tie-breaker of their own. Extraction writes instances in sorted order and the backend draws them in that order, so two entities at one depth resolve the same way every frame: the later one wins.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band, from one to |
z | number | the height in the sort, normalized against the height extent |
x | number | the world x, read only by the isometric sort |
y | number | the world y, read by the topdown and isometric sorts, larger being nearer |
Returns
| Type | Description |
|---|---|
number | the depth inside the layer's own band |
entryOffunction#
function entryOf(layer: integer): number, number, number, numberReturns the four numbers that position and light one layer.
A consumer packs these together when revision changes rather than reading them per frame, which is why they come back together.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band to read; outside one to |
Returns
| Type | Description |
|---|---|
number | the positioning mode, then the camera position's multiplier, then one when the layer ignores zoom, then one when the layer is lit |
number | |
number | |
number |
extentsfunction#
function extents(): number, numberReturns the authored extents every sort normalizes against.
Returns
| Type | Description |
|---|---|
number | the highest height a scene expects to use, then half the expected world extent |
number |
isOverlayfunction#
function isOverlay(layer: integer): booleanReturns whether a layer always takes the sorted forward lane.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band to read; outside one to |
Returns
| Type | Description |
|---|---|
boolean | whether |
isScreenSpacefunction#
function isScreenSpace(layer: integer): booleanReturns whether a layer measures positions in target pixels.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band to read; outside one to |
Returns
| Type | Description |
|---|---|
boolean | whether |
parallaxOffunction#
function parallaxOf(layer: integer): numberReturns how much of the camera's movement a layer's contents take.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band to read; outside one to |
Returns
| Type | Description |
|---|---|
number | the parallax factor, one moving contents with the world and a half drifting them at half speed |
placefunction#
function place(layer: integer, x: number, y: number, cameraX: number, cameraY: number, zoom: number, rotation: number, width: number, height: number): number, numberReturns where one authored position lands on the render target.
The one place the four positioning modes are resolved, so a caller placing geometry and a caller hit-testing it cannot disagree. A camera layer turns and scales the position about the view center, taking parallax before the turn and dropping the zoom afterwards when the layer ignores it. A screen-space layer answers the position unchanged, and a virtual layer scales the authored resolution onto the target.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band whose mode decides what the position means; outside one to |
x | number | the authored horizontal position, in world units, target pixels, or virtual units according to the layer's mode |
y | number | the authored vertical position, running down in every mode |
cameraX | number | the view center's world x, read only by a camera layer |
cameraY | number | the view center's world y, read only by a camera layer |
zoom | number | the camera's zoom, read only by a camera layer that does not ignore it |
rotation | number | the camera's rotation in radians, read only by a camera layer |
width | number | the render target width in pixels |
height | number | the render target height in pixels |
Returns
| Type | Description |
|---|---|
number | the pixels from the target's left edge, then the pixels from its top edge; neither is clamped to the target |
number |
resolutionfunction#
function resolution(): numberReturns the smallest depth difference depthOf produces between two entities one world unit apart, taken over every sort mode.
A depth target must preserve this difference. A format with a larger step keeps the bands, so layer order stays safe, and loses the sort inside them.
Returns
| Type | Description |
|---|---|
number | the depth difference, in the input that moves depth least |
revisionfunction#
function revision(): integerReturns the configuration revision.
Returns
| Type | Description |
|---|---|
integer | a count starting at zero that only rises, so a consumer holding a packed copy can tell whether its copy is still the answer |
setExtentsfunction#
function setExtents(highestZ: number, halfExtent: number): nilReplaces the authored extents every sort normalizes against.
Raising an extent lowers the depth difference one world unit is worth, which is what resolution reports.
Arguments
| Name | Type | Description |
|---|---|---|
highestZ | number | the highest height a scene expects to use |
halfExtent | number | half the expected world extent, used by the position terms |
Returns
| Type | Description |
|---|---|
nil |
Raises
when either extent is not greater than zero
setVirtualSizefunction#
function setVirtualSize(width: number, height: number): nilReplaces the authored resolution every virtual-coordinate layer is measured in.
One resolution serves every such layer, because a game has one authored layout size. place scales it to fill the target, so the layout keeps its internal proportions at any window size and stretches with the window's aspect. It neither letterboxes nor preserves square pixels.
Arguments
| Name | Type | Description |
|---|---|---|
width | number | the authored width in virtual units |
height | number | the authored height in virtual units |
Returns
| Type | Description |
|---|---|
nil |
Raises
when either dimension is not greater than zero
sortOffunction#
function sortOf(layer: integer): integerReturns a layer's sort as the identifier depthIn accepts.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band to read, from one to |
Returns
| Type | Description |
|---|---|
integer | the sort identifier, which is an internal number rather than a |
viewCulledfunction#
function viewCulled(layer: integer): booleanReturns whether the camera's view rectangle decides if a layer draws.
False on a layer the camera does not place where its world bound says. Screen-space and virtual-coordinate contents have no world position for the view to test, and parallax and zoom independence draw them somewhere the bound does not describe. Extraction gives those contents a bound every view contains, so they draw whatever the camera is looking at, and a layer using none of these modes keeps exact culling.
Arguments
| Name | Type | Description |
|---|---|---|
layer | integer | the band to read; outside one to |
Returns
| Type | Description |
|---|---|
boolean | whether extraction should write this layer's real world bound |
virtualSizefunction#
function virtualSize(): number, numberReturns the authored resolution every virtual-coordinate layer is measured in.
Returns
| Type | Description |
|---|---|
number | the authored width, then the authored height, both in virtual units |
number |
Values#
MAXvariable#
const MAX: integerThe number of bands that divide the depth range.
Load-bearing at sixteen. The band formula divides the range by it and a consumer recovers a layer by multiplying a depth by it, so raising it changes every depth a scene has ever recorded.
MODE_CAMERAvariable#
const MODE_CAMERA: numberPositions contents in world units, through the camera.
This value is the first component of what entryOf reports, which a renderer packs into a uniform the vertex stage compares against, so it is a compatibility surface rather than an identifier this tree renumbers.
MODE_SCREENvariable#
const MODE_SCREEN: numberPositions contents in target pixels, ignoring the camera.
MODE_VIRTUALvariable#
const MODE_VIRTUAL: numberPositions contents in the authored virtual resolution, stretched to the target.
SORT_ISOMETRICvariable#
const SORT_ISOMETRIC: integerSorts by x plus y plus height for a diamond grid.
SORT_TOPDOWNvariable#
const SORT_TOPDOWN: integerSorts lower screen positions in front and breaks ties with height.
SORT_Zvariable#
const SORT_Z: integerSorts only by height and ignores world position.