← atelier

landing/art/fx_variants.py

One flat illustration (lighthouse at dusk), then the same pixels pushed through eight effect chains (bloom, halftone, pixel, duotone, film, noir, night).

Render it yourself: atelier render fx_variants.py --preview (it imports _common.py for the palette and output folder).

fx_variants.py
# One flat illustration (lighthouse at dusk), then the same pixels pushed through eight effect chains (bloom, halftone, pixel, duotone, film, noir, night).
import numpy as np
from atelier import *
from _common import *

W, H = 1200, 800
c = Canvas(W, H)
c.fill(gradient([(0, "#1b2347"), (0.45, "#5b3a6e"), (0.72, "#e0716a"), (0.85, "#f6b26b")]))
c.layer(blend="screen").fill("white", mask=stars(40, seed=SEED + 1) * top(0.45, soft=0.2))
c.circle(820, 520, 70, fill="#ffe2a8")                                                   # low sun
sea_y = 560
far = fbm(2.5, 4, seed=SEED + 3).ridge_line(0.62, 0.08)
c.layer().fill_below(far, "#4a3060")                                                    # distant headland
sea = c.layer()
sea.rect(0, sea_y, W, H - sea_y, fill=gradient([(0, "#e0716a"), (0.3, "#5b3a6e"), (1, "#141a33")]).within(rect(0, sea_y, W, H - sea_y)))
for k in range(26):                                                                    # sun glitter
    y = sea_y + 6 + k * k * 0.32
    w = 90 - k * 2.4 + (k % 3) * 8
    sea.line(820 - w / 2 + (k % 4) * 6, y, 820 + w / 2 - (k % 5) * 5, y, stroke="#ffd59a", width=2 + k * 0.08, opacity=0.9 - k * 0.03)
tower = polygon([(195, 490), (245, 490), (236, 268), (204, 268)])               # base sinks deep into the rock
c.draw(tower, fill="#f2ebdd")
for y0 in (300, 360, 420):                                                             # red bands
    c.draw(tower & rect(150, y0, 140, 26), fill=VERMILION)
c.draw(tower & rect(220, 260, 60, 220), fill="#000000", opacity=0.22)                  # shaded side
c.rect(198, 248, 44, 22, r=3, fill="#ffe8b0")                                           # lantern
c.polygon([(192, 250), (248, 250), (220, 222)], fill="#2a1f3a")
c.polygon([(188, 436), (252, 436), (258, 480), (182, 480)], fill="#3a2d4c")              # stone plinth: the foot
c.rect(186, 434, 68, 5, fill="#4c3d60")
cliff = svg("M 0 474 L 120 456 L 170 448 L 272 447 L 322 476 L 385 545 L 432 605 L 470 800 L 0 800 Z")
c.draw(cliff, fill=gradient([(0, "#2a1f3a"), (1, "#0f0c18")]).within(cliff))          # drawn last: it holds the tower
beam = c.layer(blend="screen")
beam.polygon([(236, 256), (1200, 120), (1200, 330)], fill=gradient([(0, "#fff1c9"), (1, "#fff1c900")], angle=0))
beam.apply(blur(6))
c.layer()
c.text("ATELIER FX", 60, 90, 30, weight="semibold", fill="#f2ebdd", spacing=0.2)
base = c.flatten()

chains = {
    "original": [],
    "bloom": [exposure(0.2), bloom(0.45, 46, 1.8, tint=GOLD), glow(14, 0.7, "#ffd59a")],
    "halftone": [halftone(9, 22, cmyk=True)],
    "pixel": [pixelate(6, "retro16", dither="bayer", strength=0.5)],
    "duotone": [gradient_map(["#14213d", "#e8553a", "#f6e3c4"])],
    "film": [chromatic_aberration(3), lens_distortion(0.12), grain(0.06, 1.6, seed=SEED), vignette(0.6)],
    "noir": [saturation(0), contrast(0.35), grain(0.05, 1.2, seed=SEED), vignette(0.55)],
    "night": [hue_sat(-30, 0.6, -0.15), curves([(0.0, 0.0), (0.5, 0.36), (1, 0.85)]), color_balance(shadows=(-0.04, 0.0, 0.08))],
}
for name, fx in chains.items():
    v = Canvas(W, H)
    v.place(base)
    if fx:
        v.apply(*fx)
    v.save(out(f"fx-{name}.jpg"), quality=88)