In-game shader toggling and cycling within favorite presets (per RetroArch / Core / Content-Dir)
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 20/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- c
- Domain
- computer-graphics, frontend
Research direction
Start by reviewing the input_shader_toggle, input_shader_prev, and input_shader_next behavior, along with the interactions described for video_shader_remember_last_dir and retroarch.glslp. Use issue #4857 and the documented workaround as context. Done should provide predictable favorite-preset cycling, independent shader toggling, and persisted per-scope resume position without duplicate cycle entries.
Written by the indexing model from the issue text.
Description
User Goal
- While in-game via hotkeys I want to…
a) ✅ cycle through my favorite shaders,
b) ✅ in my desired order,
c) ✅ and toggle shading OFF at any time,
d) ✅ and ON at any time,
e) ❌ resuming where I was in the cycle order. - ✅ Those favorites I can define: globally or per core or per content-dir, e.g.:
- For NES and PS1 games I want to cycle through some particular 5 favorite shaders:
- 3 CRT shaders + 2 VHS shaders, ordered from most subtle to strongest visual effect
- For GB and GBC games I want to cycle through some particular other 3 favorite shaders:
- 3 handheld shaders, sorted from smallest to largest grid
- For NES and PS1 games I want to cycle through some particular 5 favorite shaders:
Legend: ✅ achieved ❌ unachieved in my workaround
Collaboration
- As a UX designer I offer to speak to interested developers about this complex matter holistically in an A/V chat.
- Nevertheless I try to compile it here en detail to be approachable independent of persons and timezones.
Status Quo
- For the average user and with the default setup on some platforms (e.g. Android's shader directory by default in inaccessible sandbox ❗️) this is almost impossible.
- The features Toggle Shader
input_shader_toggle+ Prev/Next Shaderinput_shader_previnput_shader_next+ Remember last shader directoryvideo_shader_remember_last_dirall work quite limited, even flawed.- In interplay with the default central shader directory structure and RetroArch's standard override mechanism, you get even many more unforeseen and undesired side effects.
- See section Flaws of shader toggling and cycling at the end for in depth explanations
- Luckily after intensive trial and error and source code study (aided by ChatGPT) I understood their interplay somehow and found a workaround, which fulfills almost all the goals.
- In interplay with the default central shader directory structure and RetroArch's standard override mechanism, you get even many more unforeseen and undesired side effects.
- I share the workaround here for others to benefit from it, and likely will also integrate it as a guide in the official user documentation.
- After getting some expert feedback here first, hopefully.
Workaround: Core specific overrides each point to specific directory with favorite shader presets
retroarch.cfg (main config)
video_shader_enable = "false"
video_shader_dir = "/data/user/0/com.retroarch.aarch64/shaders"
video_shader_preset_save_reference_enable = "true"
video_shader_remember_last_dir = "true"
Explanations
video_shader_enable = "false"because in general we don't want shaders, just per particular cores.video_shader_dirin the mainretroarch.cfgpoints to the central shader directory (no shader-presets on root, on root are only sub-directories, in them then: shader-presets + shaders + assets like textures)- ❗️ On Android the central shader directory lies within application sandbox directory!
- Thus inaccessible in file browser and Terminal!
- Another reason why shader management is such a bad UX on Android.
- You can't tweak anything there
- Once you created a shader preset file there (by actions in the UI) you can not even delete it anymore. You have to delete the whole app-data if you want to get rid of it. Big conceptual/architectural flaw IMHO.
video_shader_preset_save_reference_enable = "true"- Uses a simple preset with the #reference directive to keep the setup small, efficient and modular
- Essentially this is just a minimal text file with a relative link to
- another shader preset file, which itself can link
- to yet another shader preset file (and so on) or a real shader file
- Important is that at the end of that link chain must be a real shader file (algorithm + full parameters + references to assets)
- another shader preset file, which itself can link
- Essentially this is just a minimal text file with a relative link to
- Uses a simple preset with the #reference directive to keep the setup small, efficient and modular
video_shader_remember_last_dir = "true"- For exploring in general this may be helpful, because then the in game hotkeys
prev/next shaderare relative to that directory. - For core specific configurations of
video_shader_dir(see below) we'll intentionally setvideo_shader_remember_last_dirtofalse.
- For exploring in general this may be helpful, because then the in game hotkeys
Mappings from core config file(s) to particular shader favorite directory
Types of mapping from core to favorite-shader-preset-dir
1:1(one to one) — One core points to its specific shader preset directory.N:1(many to one) — Multiple cores (with shared visual output characteristics) point to a particular shader preset directory.
CRT gaming platforms point to my favorite CRT shader presets directory (N:1)
CRT core configuration files (overrides)
CRT era consoles handled by core-A.cfg + core-B.cfg all have the following attributes in them (among potential further customizations) :
video_shader_dir = "/path/to/shader-favorites/crt"
video_shader_remember_last_dir = "false"
Explanation
video_shader_dirfor that core points exactly to the directory holding my favorite shaders for that core (1:1) or potentially also further cores having similar output characteristics hence making use of the same same favorite shaders (1:N).video_shader_remember_last_dirset tofalseguarantees that preset file cycling via hotkeys Prev shaderinput_shader_prevand Next shaderinput_shader_nextalways remains within the definedvideo_shader_dir.
CRT shader favorite directory
/path/to/shader-favorites/crt contains my favorite presets for CRT era video games:
000.glslp
crt-nes-mini.glslp
sl-res-independent-scanlines.glslp
sl-scanlines-sine-abs.glslp
zfast-crt.glslp
zz-fakelottes.glslp
Explanations
000.glslpis an "empty shader" ( containing only the line "shaders=0") so a way to toggle off the shader when cycling through the series.- When cycling through my shaders after having reached the last shader preset and reaching the start again (
000.glslp) this turns the shader off. - Without requiring the other hotkey "Toggle Shader"
input_shader_togglewhich has its own usability shortcomings to better avoid.
- When cycling through my shaders after having reached the last shader preset and reaching the start again (
- You may prefix the filters to get them into the order / clustering you want, see e.g.
zz-fakelottes.glslpwhich I wanted to be last.
Handheld gaming platforms point to my favorite LCD handheld shader preset dir (N:1)
Handheld core configuration files (overrides)
Both core-X.cfg + core-Y.cfg again have these attributes in them, among potential further customizations:
video_shader_dir = "/path/to/shader-favorites/handheld"
video_shader_remember_last_dir = "false"
Handheld shader favorite directory
/path/to/shader-favorites/handheld contains my favorite presets for handheld video games:
000.glslp
01-bevel.glslp
02-retro-v2.glslp
11-dot.glslp
21-zfast-lcd.glslp
31-lcd-grid-v2.glslp
32-lcd-grid.glslp
80-lcd-grid-v2-vba-color-motionblur.glslp
90-simpletex_lcd_720p+gbc-color.glslp
000.glslpyet again as the "empty shader" (aka "null shader") at the start or end (zzz.glslp) if you prefer.- The other presets now all use a sorting prefix, sorted them from brightest to darkest output that they produce.
In each of those shader preset directories you create shader preset files
- Using the simple preset format containing only a reference to a shader (preset) file somewhere located in the central shader directory.
/path/to/shader-favorites/handheld/11-dot.glslp contains:
#reference "/data/user/0/com.retroarch.aarch64/shaders/shaders_glsl/handheld/dot.glslp"
Flaws of shader toggling and cycling
- See my collaboration offer.
- In case you prefer to make up your own mind, also compiled here quite in depth:
Cycling issues
- #4857 with the default shader directory, which on root has no presets!
- And even worse on Android the central shader directory is inaccessible (as it's within the app sandbox directory)
- Cycling position is remembered
- But only during session.
- Preferably should be remembered (=persisted) cross sessions too.
- Per core: If
config/core-name/retroarch.glslporcore-cfg-designated-video_shader_dir/retroarch.glslpexists load it.- Bit fuzzy though: Currently not persisted by cycling, only by toggling OFF, it is saved into
current-shader-dir/retroarch.glslp - In
retroarch.glslp: Ideally it just uses#reference=/path/to/current-favorite-preset.glslpwhich is a relative link to a preset file in a directory that it cycles through (but again only if restricted withvideo_shader_remember_last_dir=false, you see how unpredictable the current framework is…) - While cycling through the current directory when you reach the preset currently referenced in
retroarch.glslpit should useretroarch.glslpinstead (with its parameter overrides, otherwise its the same), andretroarch.glslpitself is always omitted from the cycle. That way the cycle is always regular. We avoid that a preset occurs twice (once as itself, and once as its copy inretroarch.glslp). - So when cycling is active, effectively
retroarch.glspis just a disk-persisted pointer to one of its favorite preset files, which themselves all are just links (plus optionally some parameter overrides) to presets in the central shader directory. - For remembering shader per game I guess its the same just as
config/core-name/game-name.glslp
- Bit fuzzy though: Currently not persisted by cycling, only by toggling OFF, it is saved into
Toggling issues
- When toggling OFF and the current directory (where-ever that may be, interplay with
video_shader_remember_last_diris unpredictable) has noretroarch.glslpfile, it creates it, and copies the currently active shader preset (and any parameter tweaks you made made in the current session via shader UI) into it. - I consider this a feature not a bug. When combined cleverly with my workaround setup you can create this order
- 000.glslp — The empty shader preset is always at position 1
- 01-preset.glslp — Then come your desired presets with the ordinal number
- 02-preset.glslp
- 03-preset.glslp
- retroarch.glslp — Always guaranteed last. If we omit it from the series (as proposed) then we would not even need the ordinal numbers necessarily. Otherwise ordinal numbers are a simply way to guarantee
retroarch.glslpis last (and as such a dupe of one of the presets in the series, specifically the preset which was last active before shaders were toggled OFF thus that preset being persisted by reference intoretroarch.glslpthus acting as a copy of it (plus parameter overrides potentially)).
Cycling only and refraining from toggling to reduce complexity
- If you have only a handful of shader presets, then inserting a 000.glslp "null shader" suffices as a method to toggle off the shader.
- You can then only use the prev/next shader hotkeys and never use the shader toggle hotkey to avoid all the complexity when mixing cycling with shader toggling (especially as long as it works in its current chaotic way).
- But then you cannot persist the currently active shader. As this is currently persisted into
retroarch.glslpwhich itself is intrinsically tied to toggling. - If the toggling hotkey could be totally independent of creating a or looking for a retroarch.glslp and just to set the shader off and when on resume at the same cycling position that would be fine too.
- As I see it from now very likely some restrictions need to be put in how all these options can be combined in order to have some consistent behavior.
Closing words
- You see the manifold interplay of cycling and toggling and retroarch.glslp and video_shader_remember_last_dir require a deep analysis prior redesigning this.
- There is a quite capable workaround available thought which satisfies most needs.
- But ideally cycling/toggling/remembering shaders could be done way better UX wise!
- Dominant language
- C
- Stars
- 14.1k
- Forks
- 2.2k
- Avg merge
- 7h 35m
- Merged PRs (30d)
- 51
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from libretro/RetroArch
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
feature request
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 1/5 Under an hour Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
All issues in libretro/RetroArch
Similar issues
-
[adam] AdamNet network read doesn't cap to MAX_ADAM_PACKET_LEN, overflows client receive buffers Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
FujiNetWIFI/fujinet-firmware#1649 · 2 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
HarbourMasters/Shipwright#7229 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
riscv-software-src/riscv-isa-sim#2435 · 1 comment ·
-
bug Self Built Image SNAPSHOT Supported Device target/ramips
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100