Skip to content

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

lua
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.

lua
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:

lua
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)},
})
lux
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.

CurveIntended profile
linearUnmodified interpolation.
smoothstepSoft start and end.
smootherstepFlatter, smoother endpoints.
ease-inQuadratic slow start.
ease-outQuadratic slow finish.
ease-in-outSymmetric quadratic easing.
exponentialNormalized k = 2.6 light falloff; useful for two-stop glows.
gaussianNormalized bell-like falloff.
inverse-squareNormalized 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.

lua
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

lua
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:

FieldPractical RangeMeaning
color / tintalpha 24..70Main worn overlay. Dark tint lowers brightness/contrast; light tint can be used on dark metal.
edgeColor / highlightalpha 40..120Broken edge highlight. Keep it material-colored, not pure white.
fractal0.20..0.70Sparse soft scuff intensity. It should create uneven worn patches, not smoke.
grain0.35..0.90Fine surface roughness and contrast breakup. This is the main "not perfectly smooth" control.
scratches0.12..0.55Sparse short scratch density. Raise slowly; too high becomes random drawn lines.
edge0.25..0.85Broken edge wear intensity inside the shape boundary.
scale24..48Soft scuff scale in pixels. Lower values look busier; higher values look cleaner.
grainScale3.5..7Fine roughness density.
scratchScale20..34Scratch cell spacing. Larger values produce fewer, farther-apart scratches.
scratchWidth0.03..0.07Scratch thickness. Keep narrow for UI.
edgeWidth4..9Edge-wear band width in pixels.
angledegreesScratch direction.
softnessreservedKept in the pattern record for compatibility with older tuning presets.
warp0..0.08Slightly bends the procedural field. Keep low for UI panels.
offset / speednumberSampling offset; speed animates when the caller wants motion.
seednumber or stringStable variation seed.

Tuning notes:

  • For dark inventory/shop cards, start with the default values above and adjust only color.a and edgeColor.a first.
  • grain gives the surface roughness; fractal gives larger uneven scuffs; scratches should remain sparse.
  • Edge wear should be broken and local. If it reads as inner glow or a continuous border, lower edge, edgeColor.a, or edgeWidth.

Transforms

lua
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:

lua
MGFX.RoundedBoxEx(x, y, w, h, {
    radius = 12,
    fill = Color(12, 20, 28, 210),
    transform = tilt,
})

Use a transform stack for multiple calls:

lua
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()
end

Transforms 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.

lua
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

lua
MGFX.GetCapabilities(target)
MGFX.Supports(target, key)

Common targets:

TargetMeaning
MGFX.TARGET.ROUNDED_BOXRounded box, circle, capsule family.
MGFX.TARGET.CHAMFER_BOXChamfer box.
MGFX.TARGET.POLYConvex polygon.
MGFX.TARGET.LINELine primitive.
MGFX.TARGET.IMAGEImage and icon mask path.
MGFX.TARGET.PROGRESS_BARProgress bar.
MGFX.TARGET.SEGMENT_BARSegment bar.
MGFX.TARGET.TEXTText route.

Capabilities describe implemented render slots, not future plans.

Back to API Reference