MGL

MGL
Login

Mathematics for Graphics in Lua, or Mathematics for OpenGL, is a math library for graphics purposes. It is effectively designed for 2D/3D rendering (but may also be used for physics).

It aims to be simple and optimized, mostly for LuaJIT.

It tries to follow GLSL, but it will diverge when relevant. One benefit is the decrease in mental load when working with Lua (CPU) and GLSL (GPU), as it is the case with LÖVE.

Table of Content

Install

See src/, rockspecs/ or luarocks.

Quick downloads: trunk

API

local mgl = require "mgl"

Generalities

Conventions

Noteworthy Differences With GLSL

Vector

vecM is a column vector of size M, i.e. with M rows.

A vector is a table sequence of the components.

The following vector types are available: vec2, vec3, vec4.

Constructors

Scalar

mgl.vecM (s: number) -> vecM

Construct from a scalar. All components are set to the value s.

Table

mgl.vecM (t: table) -> vecM

Construct a vector from a raw table of the same length. The table content is copied.

Sequence

mgl.vecM (...) -> vecM

Construct from a sequence of scalars and vectors matching the number of components.

Examples:

mgl.vec3(mgl.vec2(1, 2), 3)
mgl.vec4(mgl.vec2(0), mgl.vec2(1))
mgl.vec4(mgl.vec4(1))

Truncate

mgl.vecM (v: vecM+) -> vecM

Construct a vector from one with more components.

Accessors

Table Access

As a table sequence, each component can be accessed with its index. E.g. v[1], v[2], v[3].

Swizzling

See GLSL.

Defined masks are xyzw and rgba.

Examples:

local v2 = mgl.vec2(1)
local v4 = mgl.vec4(v2.xxyy)
local v4_mirror = v4.wzyx

local c1 = mgl.vec4(1, 0, 0, 0.5)
local c2 = mgl.vec4(0, 1, 0, 1)
local c3 = mgl.vec4(c1.rgb, c2.a)

Operators

Arithmetic Operators

Defined operators are: add +, sub -, unm -, mul *, div /, mod %, pow ^.

They all work component-wise. Binary operators work with another vector of the same size or with a scalar.

Examples:

1 / mgl.vec2(2) -- (1/2, 1/2)
2 ^ mgl.vec3(1, 2, 3) -- (2, 4, 8)
mgl.vec3(1, 2, 3) % 2 -- (1, 0, 1)

Other Operators

The eq relational operator and tostring are defined.

Functions

length

mgl.length (x: vecM) -> number

Calculate the length of a vector.

normalize

mgl.normalize (x: vecM) -> vecM

Calculate the unit vector in the same direction as the original vector.

distance

mgl.distance (x: vecM, y: vecM) -> number

Calculate the distance between two points.

dot

mgl.dot (x: vecM, y: vecM) -> number

Calculate the dot product of two vectors.

cross

mgl.cross (x: vec3, y: vec3) -> vec3

Calculate the cross product of two vectors.

reflect

mgl.reflect (i: vecM, n: vecM) -> vecM

Calculate the reflection direction for an incident vector.

For a given incident vector i and surface normal n, reflect returns the reflection direction calculated as i - 2.0 * dot(n, i) * n.
n should be normalized in order to achieve the desired result. — glsl

refract

mgl.refract (i: vecM, n: vecM, eta: number) -> vecM

Calculate the refraction direction for an incident vector.

The input parameters i and n should be normalized in order to achieve the desired result. — glsl

Matrix

matNxM is a matrix of N columns and M rows.

A matrix is a table sequence of all the values in column-major order.

The following matrix types are available:

In addition, matN is an alias for the square matrix matNxN (i.e. mat2, mat3 and mat4).

Constructors

Scalar

mgl.matNxM (s: number) -> matNxM

Construct from a scalar. The diagonal of the matrix is set to s, the rest is 0. If s == 1, it builds the identity matrix.

Copy

mgl.matNxM (m: matrix) -> matNxM

Construct a matrix from any other matrix, of any size. Existing values are copied, the rest is filled with the identity matrix.

Table

mgl.matNxM (t: table) -> matNxM

Construct a matrix from a raw table with the right amount of values in column-major order. The table content is copied.

Sequence

mgl.matNxM (...) -> matNxM

Construct from a sequence of scalars and vectors matching the number of values in the matrix.

Because matrix values are stored in column-major order, it is possible to do:

local m = mgl.mat4(
    mgl.vec4(1), -- first column
    mgl.vec4(2), -- second column
    mgl.vec4(3), -- third column
    mgl.vec4(4)) -- fourth column

See GLSL.

Accessors

Table Access

As a table sequence, each value can be accessed with its index. E.g. m[1], m[2], m[3]....

Scalar Access

matNxM:a (i: number, j: number) -> number

Method to get one value from the matrix. If the coordinates are outside the matrix, it returns nil.

matNxM:a (i: number, j: number, v: number)

Method to set one value of the matrix. If the coordinates are outside the matrix, it throws an error.

Vector Access

matNxM:v (j: number) -> vecM

Method to get one vector from the matrix. If the index is invalid, it returns nil.

matNxM:v (j: number, v: vecM)

Method to set one vector of the matrix. If the index is invalid, it throws an error.

Operators

Arithmetic Operators

Defined operators are: add +, sub -, unm -, mul *, div /, mod %, pow ^.

Except for multiplication, they all work component-wise. Binary operators work with another matrix of the same size or with a scalar.

For multiplication, it performs the matrix product1. The number of columns in the first matrix must be equal to the number of rows in the second matrix. In addition, a vector is considered a matrix with a single column.

Other Operators

The eq relational operator and tostring are defined.

Functions

transpose

mgl.transpose (m: matNxM) -> matMxN

Calculate the transpose of a matrix.

determinant

mgl.determinant (m: matN) -> number

Calculate the determinant of a matrix.

inverse

mgl.inverse (m: matN) -> matN

Calculate the inverse of a matrix.

Transform Functions

translation

mgl.translation (v: vec2) -> mat3

Build a 2D homogeneous translation matrix from a vector.

mgl.translation (v: vec3) -> mat4

Build a 3D homogeneous translation matrix from a vector.

rotation

mgl.rotation (theta: number) -> mat3

Build a 2D homogeneous rotation matrix from an angle in radians.

mgl.rotation (axis: vec3, theta: number) -> mat4

Build a 3D homogeneous rotation matrix from a unit vector and an angle in radians.

scale

mgl.scale (v: vec2) -> mat3

Build a 2D homogeneous scale matrix from a vector.

mgl.scale (v: vec3) -> mat4

Build a 3D homogeneous scale matrix from a vector.

Projection Functions

orthographic

mgl.orthographic (left, right, bottom, top, near, far) -> mat4

Build an orthographic projection matrix compatible with OpenGL. All parameters are numbers.

perspective

mgl.perspective (hfov, aspect, near, far) -> mat4

Build a perspective projection matrix compatible with OpenGL. All parameters are numbers.

Scalar / Component-wise Functions

These functions operate on every component independently.

In the documentation of these functions, the type T can be a scalar, a vector or a matrix.

If there is no explanation for a function, it can be found in the GLSL specification at the function of the same name.

Single Argument

mgl.<func> (a: T) -> T

Apply a maths function to each component of a.

Available functions:

Note: deg and rad are aliases for degrees and radians.

Two Arguments

mgl.<func> (a: T, b: T or number) -> T

Apply a maths function to each component of a, using b. Argument b can be of the same type as a or a scalar.

Available functions:

Other Functions

clamp

mgl.clamp (x: T, a: T or number, b: T or number) -> T

Constrain a value to lie between two further values.

The returned value is computed as min(max(x, a), b).

mix

mgl.mix (x: T, y: T, a: T or number) -> T

Linearly interpolate between two values.

The returned value is computed as x * (1 − a) + y * a. The multiplication is component-wise using cmul.

Performances

Benchmarks

Notes:

Time to transform 2500 entities at 60 FPS for 10s (600 ticks):

name time ms / tick frame % code
GLM GCC -O2 0.306 ±0.004 0.510 3 % benchmarks/compare/glm/transform.cpp
MGL LuaJIT (JIT on) 0.382 ±0.009 0.637 4 % benchmarks/transform.lua
MGL LuaJIT (JIT off) 7.723 ±0.184 12.872 77 % benchmarks/transform.lua
MGL Lua 5.4 15.425 ±0.168 25.708 154 % benchmarks/transform.lua

Observations:


  1. ^ https://en.wikipedia.org/wiki/Matrix_multiplication