GodotUO

Classic Ultima Online on Godot 4 .NET


Project maintained by DatMoshu Hosted on GitHub Pages — Theme by mattgraham

Screen Effects

GUO can give the world a different look: cel shading, ink outlines, black and white, sepia, noir, colour grades, a vignette, a glow around lights, an EGA or handheld palette, CRT scanlines, and colour-blind help. Effects apply to the world only, at the art’s own pixels, before the window is scaled up. Gumps, the paperdoll and the rest of the interface are never touched.

Classic, the default, is exactly ClassicUO’s picture: no effect runs, and the world is drawn the same way it always was. The decision record is ADR-0023.

Choosing a look

The chosen look is remembered on this device.

The same things by typed command (a client command, like ClassicUO’s own):

-postfx list          the looks and the shaders there are
-postfx load Noir     switch to a look
-postfx off           back to Classic
-postfx save My Look  save the current look under a name
-postfx split 0.5     compare with Classic (again to turn it off)
-postfx cost          how long the effects took on the GPU last frame
-postfx               open or close the menu

The looks that come with GUO

Cel, Ink Outline, Posterize, Black & White, Sepia, Noir, Warm Grade, Teal & Orange, Faded Film, Moonlight, Vignette, Glow, EGA, Handheld, CRT, Colour Help (protanopia, deuteranopia, tritanopia), and two that react to the game:

There is also a Silhouettes look in the built-in set.

On a desktop GPU each look costs well under a millisecond a frame. The measured costs are in ADR-0023.

GUO also has an optional pack, JarJar’s screen effects: 32 more looks by MeesaJarJar (fog, rain, snow, night vision, thermal, depth of field, damage, poison and more). Install it from Options > Video > Store (Asset Store, Content Packs). Installing it does not switch a look on; pick one in Screen effects, and choose Classic to turn every effect off.

Your own looks

Looks are plain text. Put them in the postfx folder of the client’s home (beside settings.json); they appear in the menu, and a file changed while you play is picked up within a second.

{
  "name": "Stormy",
  "description": "Cold and dim when it rains.",
  "passes": [
    { "shader": "grade",    "params": { "temperature": -0.3, "saturation": 0.8 } },
    { "shader": "vignette", "params": { "radius": 0.85, "strength": 0.3 } }
  ],
  "bindings": [
    { "pass": 0, "param": "exposure", "from": "weather", "scale": -0.15, "offset": 0.0 }
  ]
}

Your own shaders

A pass is a Godot canvas_item shader that reads the pass before it and writes its result:

shader_type canvas_item;
render_mode blend_disabled;

uniform sampler2D source : hint_screen_texture, filter_nearest;
uniform float amount : hint_range(0.0, 1.0, 0.01) = 0.5;   // becomes a slider
uniform int style : hint_enum("Soft", "Hard") = 0;          // becomes a dropdown
uniform vec4 tint : source_color = vec4(1.0);               // becomes a colour picker

void fragment() {
	vec4 c = texture(source, SCREEN_UV);
	COLOR = vec4(mix(c.rgb, c.rgb * tint.rgb, amount), c.a);  // keep the alpha
}

Declare uniform sampler2D light_tex : filter_nearest; to read the client’s light buffer (where torches, lamps and spells light the world). Keep sampling nearest: UO’s art is pixel art, and filtering it blurs it.

Sharing looks

The Asset Store has a postfx kind: a pack of presets, their shaders and any images they use. Installed packs appear in the menu beside the built-in looks, and your own same-named look wins. See ADR-0019 (Amendment 3).