Skip to content

Anisotropic filtering, 4x by default - #343

Open
startupfoundry wants to merge 2 commits into
OpenCommunityEdition:mainfrom
startupfoundry:anisotropic-filtering
Open

startupfoundry wants to merge 2 commits into
OpenCommunityEdition:mainfrom
startupfoundry:anisotropic-filtering

Conversation

@startupfoundry

@startupfoundry startupfoundry commented Oct 13, 2026 •

Copy link
Copy Markdown

The game never asks for anisotropic filtering: every sampler it sets is linear or point with an anisotropy of 1. So floors, walls and terrain seen at a slant blur into their small mip levels a short way ahead: the cryo bay's grates on a10, the sand on b30.

Screenshots (the same frozen frame, stock above and 4x below, zoomed 4x nearest-neighbour so each game pixel is a 4x4 block):

a10's cryo bay, the vent strip beside the floor grate. Stock smears the slats into streaks; with filtering they stay separate:
a10 vents, stock above, 4x below, zoomed 4x

The grate under the crewman. The lit slots break into dots in stock and stay whole:
a10 grate, stock above, 4x below, zoomed 4x

b30's beach. The sand's detail map is kept instead of blurring out:
b30 sand, stock above, 4x below, zoomed 4x

The whole a10 view, for where these are:
a10 cryo bay, stock and 4x

Change: display.anisotropic_filtering (HALO_ANISOTROPIC_FILTERING; 0, 2, 4, 8 or 16, default 4), with a TEXTURE FILTERING row on Video Setup's Graphics screen.

  • What it touches: the map's mipmapped, linearly filtered textures are sampled anisotropically: base, detail, bump and environment maps. The level is capped at the GPU's maximum, which is logged.
  • What it leaves alone:
    • Textures the game renders itself, such as the water's ripple map and the shadow maps. At 16x the ripple map turned b30's far ocean into heavy noise, so render targets keep the game's own filtering.
    • Point-sampled textures, textures without mip levels (the lightmaps have none), and the high-res HUD.
  • Changing it applies at once: the level is part of the sampler cache's key and is read again when a setting changes, so the menu's OK takes effect without a restart.
  • On GLES (Android and the web): it applies only where GL_EXT_texture_filter_anisotropic exists; otherwise nothing changes.
  • Rendering only: nothing machines in a network game agree on is touched.

Default: 4 departs from the Xbox's look, against the rule that such changes default to stock. 4x gets most of 16x's sharpness at less cost on phones and in browsers, and it costs about 0.08 ms a frame on a10 at 1080p on desktop. Happy to make it 0 if the project prefers.

How this differs from #341, which also adds anisotropic filtering, bundled with 5.1 surround sound:

  • It keeps render targets out. Add 5.1 surround sound #341 filters every mipmapped linear texture, which takes in the water's ripple map; at high levels that is where we saw the far ocean turn to noise.
  • It is a setting you can change while playing, with a menu row. Add 5.1 surround sound #341 reads the setting once at start, so a change needs a restart, and it has no menu row.
  • It is one feature in one pull request, so it can be reviewed and merged apart from audio.

Test:

  • a10's cryo bay floor and b30's beach, off, 4x and 16x on the same frozen frame: grates and sand stay sharp, and the water is unchanged.
  • tools/harness passes, as does tools/test_web_build.py's test that the menus match their generator.
  • The Graphics screen was opened with debug.menu_open and shows the row.
  • Not built for Android or the web here (no toolchains on this machine); the GLES path was checked by reading it.

The Xbox game never asks for anisotropic filtering: every sampler is linear
or point with an anisotropy of 1, so floors, walls and terrain seen at a
grazing angle blur into their small mip levels. display.anisotropic_filtering
(HALO_ANISOTROPIC_FILTERING) samples the map's mipmapped, linearly filtered
textures (base, detail, bump and environment maps) along the angle, at most
2, 4, 8 or 16 times and at most the GPU's limit; 0 filters as the Xbox did.
Textures the game renders itself are left alone: at 16x the water's ripple
map turned the far ocean into noise. Lightmaps have no mip levels and are
unchanged.

Checked: a10's cryo bay floor and b30's beach, off, 4x and 16x on the same
frozen frame (grates and sand stay sharp, the water is unchanged); about
+0.08 ms a frame on a10 at 1080p; tools/harness passes. Android and the web
apply it only where GL_EXT_texture_filter_anisotropic exists; not built here.
Video Setup's Graphics screen gets a TEXTURE FILTERING row, which sets
display.anisotropic_filtering. Its values are 0 (off, as on the Xbox),
2, 4, 8 and 16. Its XML is written by tools/port_settings.py's
settings_files(), as tools/ce_menus.py writes it; no other screen
changes.

Checked: tools/test_web_build.py's test that the menus match their
generator; the screen opened with debug.menu_open shows the row with the
setting's value, above the help.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant