Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Randomness

A shader has no RND that’s different every time: the same pixel has to come out the same every frame, or the screen would boil. What it has instead is RND(x, y): a number from 0 to 1 that looks random, made from x and y. The same x and y always give the same number, and numbers next to each other give numbers that have nothing to do with each other.

SCREEN 320, 240
SHADER "snow"
    WHEN DRAWING
        pixel = FLOOR(UV * SCREEN_SIZE)
        n = RND(pixel.x, pixel.y)
        SET COLOR = RGB(n, n, n)
    END WHEN
END SHADER

SET LAYER 0 !! shader("snow")
PAUSE

An old television between stations, holding perfectly still: a random grey for each of the game’s pixels. FLOOR(UV * SCREEN_SIZE) is which pixel this is, counted in the game’s pixels, so every bit of the window that shows that pixel gets the same number. RND(x) with one number works too, for a random number along a line.

Making it move

Put TIME in, and it’s different every moment. FLOOR it first and it changes in steps, which is the noise of a broken television rather than a blur:

SCREEN 320, 240
SHADER "static"
    USE NUMBER rate DEFAULT 12
    WHEN DRAWING
        frame = FLOOR(TIME * rate)
        pixel = FLOOR(UV * SCREEN_SIZE)
        n = RND(pixel.x + frame * 7.0, pixel.y + frame * 13.0)
        SET COLOR = RGB(n, n, n)
    END WHEN
END SHADER

SET LAYER 0 !! shader("static")
PAUSE

Twelve new screens of noise a second.

Random blocks

Give RND the same numbers for a whole patch of pixels and the whole patch gets the same random number. FLOOR(UV * 10.0) is the same for every pixel in a tenth of the layer each way, so this picks a random color for each block:

SCREEN 320, 240
SHADER "blocks"
    WHEN DRAWING
        cell = FLOOR(UV * 10.0)
        r = RND(cell.x, cell.y)
        g = RND(cell.x + 50.0, cell.y)
        b = RND(cell.x, cell.y + 50.0)
        SET COLOR = RGB(r, g, b)
    END WHEN
END SHADER

SET LAYER 0 !! shader("blocks")
PAUSE

Adding 50 to one of the numbers gives an unrelated random number for the same block, so its red, green and blue don’t all come out the same.

Dissolving

Random numbers make good dissolves. Each pixel gets its own random number, and goes when the dissolve’s progress passes it:

SCREEN 320, 240
SHADER "dissolve"
    USE NUMBER gone DEFAULT 0.5
    WHEN DRAWING
        c = IMAGE
        n = RND(FLOOR(UV.x * 64.0), FLOOR(UV.y * 64.0))
        keep = STEP(gone, n)
        SET COLOR = RGBA(c.r, c.g, c.b, c.a * keep)
    END WHEN
END SHADER

LOADIMG "hero.png", "hero"
ENABLE SPRITE 0
SET SPRITE 0 !! image("hero") x(140) y(100) scale((3, 3))
    !! shader("dissolve") shader_params({gone: 0.5})
SHOW SPRITE 0
PAUSE

Half the hero’s pixels are gone. Turn gone from 0 up to 1 and the hero crumbles away.

Crash-tan’s Tip: RND is made of a SIN of a big number, which is as random as a shader can cheaply get. It’s for looks, not for dice: give it numbers in the thousands and it gets less random, because the graphics chip’s numbers have only so many digits. Keep what you give it small.