Paint, Patterns, Transforms, and Capabilities
Paint helpers create records consumed by shape, image, widget, and text style fields.
Plain GLua calls the PascalCase methods on its local API owner (named MGFX in the signatures below). Lux calls the same helpers as lowerCamelCase methods on mgfx.api.
Paint Functions
MGFX.Solid(color)
MGFX.LinearGradient(x1, y1, x2, y2, colorA, colorB, curve)
MGFX.LinearGradientStops(x1, y1, x2, y2, stops, curve)
MGFX.RadialGradient(cx, cy, radius, colorA, colorB, curve)
MGFX.EllipticalRadialGradient(cx, cy, radiusX, radiusY, colorA, colorB, curve)
MGFX.ConicGradient(cx, cy, rotationDeg, stops, curve)
MGFX.ShapeAngularGradient(stops, rotationDeg)
MGFX.RingRadialGradient(stops)
MGFX.RingAngularGradient(stops, rotationDeg)
MGFX.SectorRadialGradient(stops)
MGFX.SectorAngularGradient(stops, rotationDeg)RadialGradient keeps a true circle in pixel space and measures radius against the primitive's shorter side. EllipticalRadialGradient uses independent local-axis radii: radiusX = 0.5 reaches half the primitive width, and radiusY = 1 reaches one full primitive height. Centers may sit outside the primitive, so cy <= 0 is useful for a top-origin spotlight. Both APIs reuse the same radial shader, LUT, material, and draw pass.
local topGlow = MGFX.EllipticalRadialGradient(0.5, -0.15, 0.72, 1.35, {
{0.00, Color(132, 255, 148, 224)},
{1.00, Color(18, 48, 30, 0)},
}, nil, "exponential")Stops can use compact or named forms:
local fill = MGFX.LinearGradientStops(0, 0, 1, 0, {
{0.00, Color(80, 170, 255)},
{pos = 0.55, color = Color(90, 220, 180)},
{offset = 1.00, color = Color(255, 210, 90)},
})import * as mgfx from "@lux/mgfx"
local draw = mgfx.api
local fill = draw.linearGradientStops(0, 0, 1, 0, {
{0.00, Color(80, 170, 255)},
{pos = 0.55, color = Color(90, 220, 180)},
{offset = 1.00, color = Color(255, 210, 90)},
})Gradient Curves
Every gradient constructor accepts an optional final curve argument. The default is "linear". Curves remap the normalized gradient coordinate in the existing pixel shader before it samples the stops LUT, so they add no draw pass and do not create curve-specific LUT textures.
| Curve | Intended profile |
|---|---|
linear | Unmodified interpolation. |
smoothstep | Soft start and end. |
smootherstep | Flatter, smoother endpoints. |
ease-in | Quadratic slow start. |
ease-out | Quadratic slow finish. |
ease-in-out | Symmetric quadratic easing. |
exponential | Normalized k = 2.6 light falloff; useful for two-stop glows. |
gaussian | Normalized bell-like falloff. |
inverse-square | Normalized inverse-square-inspired attenuation. |
The presets are fixed and intentionally have no strength parameter. Use stops when a design needs art-directed changes beyond a preset profile.
All presets use the same packed 16-bit RGBA stops LUT. Stable screen-space IGN dithering is applied in the existing gradient pixel shader to disperse the final 8-bit framebuffer quantization; neither feature adds a draw pass.
local light = MGFX.EllipticalRadialGradient(0.5, 0.04, 0.55, 1.2, {
{0, Color(80, 220, 120, 73)},
{1, Color(80, 220, 120, 0)},
}, nil, "exponential")Patterns
MGFX.StripePattern({
color = Color(255, 255, 255, 18),
spacing = 10,
width = 2,
angle = 135,
})
MGFX.SmokePattern({
color = Color(80, 170, 255, 24),
scale = 140,
density = 0.45,
softness = 0.32,
seed = "panel",
})
MGFX.WornPattern({
color = Color(0, 0, 0, 44),
edgeColor = Color(218, 208, 184, 78),
fractal = 0.44,
grain = 0.64,
scratches = 0.30,
edge = 0.54,
scale = 32,
grainScale = 5.6,
scratchScale = 26,
scratchWidth = 0.045,
edgeWidth = 7,
angle = -14,
warp = 0.035,
seed = "shop-card",
})Patterns should be passed as style.pattern, fillPattern, or trackPattern. Do not emulate stripes, smoke, or worn surface texture with many primitive calls.
WornPattern is a shader-native surface pass. It combines subtle dulling, fine roughness, directional hairline scratches, sparse soft scuffs, and broken edge wear without using render targets or data textures. It uses matrix parameter pages (c11 and c15) and intentionally avoids $c0..$c3 float uploads.
Recommended WornPattern ranges:
| Field | Practical Range | Meaning |
|---|---|---|
color / tint | alpha 24..70 | Main worn overlay. Dark tint lowers brightness/contrast; light tint can be used on dark metal. |
edgeColor / highlight | alpha 40..120 | Broken edge highlight. Keep it material-colored, not pure white. |
fractal | 0.20..0.70 | Sparse soft scuff intensity. It should create uneven worn patches, not smoke. |
grain | 0.35..0.90 | Fine surface roughness and contrast breakup. This is the main "not perfectly smooth" control. |
scratches | 0.12..0.55 | Sparse short scratch density. Raise slowly; too high becomes random drawn lines. |
edge | 0.25..0.85 | Broken edge wear intensity inside the shape boundary. |
scale | 24..48 | Soft scuff scale in pixels. Lower values look busier; higher values look cleaner. |
grainScale | 3.5..7 | Fine roughness density. |
scratchScale | 20..34 | Scratch cell spacing. Larger values produce fewer, farther-apart scratches. |
scratchWidth | 0.03..0.07 | Scratch thickness. Keep narrow for UI. |
edgeWidth | 4..9 | Edge-wear band width in pixels. |
angle | degrees | Scratch direction. |
softness | reserved | Kept in the pattern record for compatibility with older tuning presets. |
warp | 0..0.08 | Slightly bends the procedural field. Keep low for UI panels. |
offset / speed | number | Sampling offset; speed animates when the caller wants motion. |
seed | number or string | Stable variation seed. |
Tuning notes:
- For dark inventory/shop cards, start with the default values above and adjust only
color.aandedgeColor.afirst. graingives the surface roughness;fractalgives larger uneven scuffs;scratchesshould remain sparse.- Edge wear should be broken and local. If it reads as inner glow or a continuous border, lower
edge,edgeColor.a, oredgeWidth.
Transforms
local transform = MGFX.Transform({
origin = "50% 50%",
rotate = 6,
scale = 1.02,
translate = {x = 0, y = -2},
})
local tilt = MGFX.PointerTilt(mx, my, {
perspective = 900,
maxRotateX = 4,
maxRotateY = 6,
})Use style.transform for a single draw call:
MGFX.RoundedBoxEx(x, y, w, h, {
radius = 12,
fill = Color(12, 20, 28, 210),
transform = tilt,
})Use a transform stack for multiple calls:
if MGFX.PushTransform(transform, x, y, w, h) then
MGFX.RoundedBoxEx(x, y, w, h, panelStyle)
MGFX.RingEx(cx, cy, 42, 6, ringStyle)
MGFX.PopTransform()
endTransforms are visual only. They do not change layout, hit testing, or input coordinates.
Projected Quads
ProjectedQuad is an expert helper for perspective-like visual quads. Prefer Transform or PointerTilt unless you need explicit corner positions.
local q = MGFX.ProjectedQuad({
tl = {x = x + 8, y = y},
tr = {x = x + w - 3, y = y + 5},
br = {x = x + w, y = y + h},
bl = {x = x, y = y + h - 7},
steps = 12,
})Capability Queries
MGFX.GetCapabilities(target)
MGFX.Supports(target, key)Common targets:
| Target | Meaning |
|---|---|
MGFX.TARGET.ROUNDED_BOX | Rounded box, circle, capsule family. |
MGFX.TARGET.CHAMFER_BOX | Chamfer box. |
MGFX.TARGET.POLY | Convex polygon. |
MGFX.TARGET.LINE | Line primitive. |
MGFX.TARGET.IMAGE | Image and icon mask path. |
MGFX.TARGET.PROGRESS_BAR | Progress bar. |
MGFX.TARGET.SEGMENT_BAR | Segment bar. |
MGFX.TARGET.TEXT | Text route. |
Capabilities describe implemented render slots, not future plans.