3D Effects & Graphics
Five levels of optional 3D effects, from the classic look to an HDR picture at the window's own resolution, plus frame rate, texture size and window settings.
By default Galaxy Eggbert draws the classic look: the original's tiles and sprites on lit 3D cubes and models.
The Setup screen's graphics options add effects on top of that. They change only how the world is drawn,
never how it plays. This page describes the state as of 2026-11-10; for how the drawing is organised
(SceneFrame, WorldRenderer, the passes) see Rendering.
The Setup's graphics options
| Setup button | Choices | Saved as | Takes effect |
|---|---|---|---|
| 3D effects | Off, Low, Medium, High, Ultra (each press steps to the next) | effectsLevel=0 .. 4 | The next frame |
| Frame rate | 60, 120, 144, 240 fps | frameRate= | At once |
| Textures | Auto, 1x, 2x | textureScale=0, 1, 2 | The next start |
| 3D terrain | On, off (the tiles' relief near the camera) | terrainRelief= | At once (the terrain is rebuilt) |
| Fullscreen / Window (main menu), F11 | Fullscreen or a window | fullscreen= | At once |
All of them live in savedata.txt and are shared by the three players. The 3D effects are off by
default; a file from the first effects build with effects3d=1 is read as High.
fullscreen=0
terrainRelief=0
effectsLevel=3
frameRate=144
textureScale=0
What each level adds
Each level keeps everything of the levels below it.
| Level | Adds |
|---|---|
| Off (0) | Nothing: the classic look, byte for byte the picture of the build without effects. |
| Low (1) | Distance fog in the colour of the world's background picture (from 20 blocks, whole at 140); soft round shadows under Blupi and the pickups, enemies and vehicles; explosions, splashes and sparks as particles cut from their own sprite frames; Blupi's moments as particles: dust when he lands or runs, a splash into water, bubbles under it, stars as he teleports, embers off the lava. Particles are stepped by the game's ticks (EffectParticles). |
| Medium (2) | Ambient occlusion baked into the terrain's corners; the water and lava shaders (SurfaceShaders: the water below; the lava's slow pulse and crawling hot spots); FXAA edge smoothing. |
| High (3) | Real sun shadows (SceneShaders): two cascades of 1024 texels, 44 blocks round the camera's target every frame and 160 blocks ahead every third frame, soft 16-sample filtering, thrown by the terrain, cubes, every model and every sprite onto everything (they replace Low's round shadows). Point lights, up to 8, from explosions, the lightning, the nearest lava and the electrodes. The models' Ray Dream procedural materials (wood, marble, spots, bump) from avatars3d/objects/*/materials.txt. A glow on what shines, with a light colour grade (PostProcess). |
| Ultra (4) | A different picture pipeline, listed below. Desktop only in practice. |
Ultra
The levels below Ultra draw on the game's 800x480 logical surface, scaled up to the window. Ultra draws the world at the window's own pixels (the HUD stays on the logical surface) and adds:
- HDR finish (
UltraFinish): a half-float scene, auto exposure, HDR bloom, ACES tone mapping and a colour grade per world built from its sky. - Physically based light, with the sky's light taken from the world's background picture and the Ray Dream surface values of every object model.
- Screen-space effects: ambient occlusion (SSAO), contact shadows, and reflections on the water and on metal and polished floors (read from the terrain atlas's surface map).
- Voxel global illumination (
TerrainGi.hpp): light bounced from around, baked into the terrain when it is built: a room is lit by its walls, grass tints the wall beside it, an overhang is darker underneath. The reliefs read it per chunk, and sprites and particles per cell, so in a cave they are as dark as its floor. - Lit sprites and particles; fire, sparks and stars shine above white into the bloom.
- Volumetric fog with god rays through the shadow map.
- Lens: temporal anti-aliasing, depth of field, camera motion blur, film grain.
- Finer detail: the terrain atlas upscaled with normal and surface maps, and the models smoothed by PN-triangle subdivision.
Ultra's first frame builds the finer atlas and its maps; the game logs it and pauses for one to two seconds on the desktop (the work is spread over up to eight threads). Loading a world at Ultra also takes a little longer than at High, about half a second for mission 105 (the illumination bake and the programs).
The water
At Off and Low the water is its animated 2D tile on the outer faces of the water cells. From Medium up it is no
longer the tile: its colour and clearness come from the tiles, its surface is a height field of waves in world
space (three swells and two scales of chop that run on across the cells, calmer far off;
WaterWaves.hpp), with Fresnel clearness, a sun glint and a pale sheen at a glancing view. Seen from
inside it is darker. At Ultra the sky is reflected by Fresnel, the screen-space reflections ripple with the
waves, and from under the surface the sky shows only within Snell's window. Independently of the effects, a
camera under water gets a blue haze and less warm colour, fading out at the waterline.
Where the shaders cannot run
The shaders, the shadow map and the glow need GLSL source compiled at runtime (desktop GLSL 3.30 or GLSL ES 3.00) and render targets. Where they do not compile, they leave themselves out: the stock effects draw the world (no ambient occlusion either), and the fog, the round shadows and the particles remain. Where Ultra's own programs do not compile, Ultra's world is lit as High's.
Frame rate
The game always steps 60 times a second, as the original did. Above 60 fps the loop runs that often and the
frames between two steps are interpolated: the camera and its shake, Blupi, every moving object (projectiles
included) and the particles. An object that moves more than two blocks in one step (a respawn, a teleport) is
drawn where it lands, not in between. Above 60 the
screen's vertical sync is turned off. Captures, golden frames, autoplay, demo verification and resume replays
always step one tick per frame, so they are unaffected. The fps cheat shows the frames drawn per
second.
Textures: Auto, 1x, 2x
2x loads Content/icons2x/ and Content/backgrounds2x/ in place of the normal sheets
(TextureScale.hpp). A 2x sheet is used only if it is exactly twice the size of its 1x sheet,
otherwise the 1x one is kept, and all texture coordinates are computed from the logical 1x size. Auto picks 2x
on the desktop when Ultra is on and the display is at least 1000 pixels tall, since only Ultra draws the world at
the window's pixels. The web and Android always use 1x; the APK leaves the 2x folders out.
Fullscreen and window
The main menu's upper-left button switches between fullscreen and a window and always names the other mode;
F11 does the same. The first run is windowed; the choice is remembered as fullscreen=0/1.
Environment overrides
For tests and comparisons; see also Configuration.
| Variable | Effect |
|---|---|
GALAXY_EFFECTS | 0-4 or off, low, medium, high, ultra: overrides the Setup's level. |
GALAXY_TEXTURES | 1x, 2x or auto: overrides the Setup's Textures. |
GALAXY_TERRAIN_RELIEF | 0 or 1: overrides the Setup's 3D terrain. |
GALAXY_EFFECTS_DEBUG | shadow or occlusion: the terrain drawn as that factor alone (grey); at Ultra also gi (the light from around) and sprites (the sprites' light). |
GALAXY_ULTRA_DEBUG | 1-9: one part of Ultra's finish shown alone or left out (no grade, no bloom, fixed exposure, the scene before tone mapping, the exposure, the screen occlusion, the contact shadows, the reflections' weight, the fog's light). |
GALAXY_RELIEF_GI | 0: the reliefs drawn without Ultra's global illumination, to compare. |
GALAXY_PERF | 1: prints the mean draw time and model counts every 120 frames. |
GALAXY_INTERP_TRACE | A file name: writes one line per frame drawn in Play, showing the interpolation (step, fraction, camera, what moved). |
Presentation only
No effect changes the simulation. With the effects on, the golden behaviour trace and the autoplay traces are
equal to those without them; with them off, every frame is byte-equal to the build before they existed. Medium
and High have golden frames of their own beside the classic ones: tests/golden/ (classic),
tests/golden/effects-medium/ and tests/golden/effects-high/, checked by
tools/verify_golden_frames.sh. The effects' GPU-free decisions are covered by the CTest cases
VerifySceneEffects, VerifyUltra and VerifyEffectParticles; see
Testing.
Measured with GALAXY_PERF in mission 105 under a CPU rasteriser (relative numbers only): Off 23 ms
a frame, Low 24, Medium 25, High 68.
Platform status (as of 2026-11-10)
| Build | Status |
|---|---|
Linux desktop, OPENGL33 | Verified Off to High under Xvfb: 11 missions at each level, the editor, the Setup live. Ultra verified on the desktop as it was built (2026-11-09). |
Web, WEBGL2 | Verified to High High set in the main menu's Setup and played in headless Chrome, every shader compiled. Ultra's shaders were also seen to compile there on 2026-11-09 (its atlas maps take about 4 s, on one thread), but Ultra has not been played on the web, and the status document still lists it as not run there. Textures are always 1x. |
Android, OPENGLES3 | Not verified The effects have not been run on Android. Textures are always 1x. |
Windows, SDLGPU | Not verified No fresh build or live 3D run yet; see Platform Support. |
Source map
Source (src/GalaxyEggbert/Game/) | Role |
|---|---|
SceneFrame.hpp (SceneEffects), SceneEffectsLogic.hpp | The level's flags per frame; shadow placement, light choice, occlusion (no GPU). |
EffectParticles.hpp/.cpp | Low's particles. |
SurfaceShaders.hpp/.cpp, WaterWaves.hpp | Water and lava shaders, the wave height field. |
SceneShaders.hpp/.cpp | Terrain and model shaders, the shadow cascades, point lights, Ultra's lit programs. |
PostProcess.hpp/.cpp | Glow, grade and FXAA for Medium and High. |
UltraFinish.hpp/.cpp, UltraLogic.hpp, UltraAssets.hpp | Ultra's HDR finish, geometry pass, fog and lens; the sky light and grade tables. |
TerrainGi.hpp, TerrainMaps.hpp, ModelSubdivision.hpp | Ultra's global illumination bake, the finer atlas and its maps, model smoothing. |
TextureScale.hpp/.cpp | Choosing and loading 1x or 2x sheets. |
The level is chosen in GalaxyEggbertGame::AppendSceneEffects()
(src/GalaxyEggbertCNA/GalaxyEggbertGameScene.cpp) and drawn by
WorldRenderer.