In-game shader toggling and cycling within favorite presets (per RetroArch / Core / Content-Dir)

Open
#17,900 0 comments 0 reactions 0 assignees View on GitHub

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

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

feature request

User Goal

  1. 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.
  2. ✅ 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

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 Shader input_shader_prev input_shader_next + Remember last shader directory video_shader_remember_last_dir all 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.
  • 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

Shader favorites directories - Realistic setup

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_dir in the main retroarch.cfg points 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)
  • video_shader_remember_last_dir = "true"
    • For exploring in general this may be helpful, because then the in game hotkeys prev/next shader are relative to that directory.
    • For core specific configurations of video_shader_dir (see below) we'll intentionally set video_shader_remember_last_dir to false.

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_dir for 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_dir set to false guarantees that preset file cycling via hotkeys Prev shader input_shader_prev and Next shader input_shader_next always remains within the defined video_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.glslp is 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_toggle which has its own usability shortcomings to better avoid.
  • You may prefix the filters to get them into the order / clustering you want, see e.g. zz-fakelottes.glslp which 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.glslp yet 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.glslp or core-cfg-designated-video_shader_dir/retroarch.glslp exists 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.glslp which is a relative link to a preset file in a directory that it cycles through (but again only if restricted with video_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.glslp it should use retroarch.glslp instead (with its parameter overrides, otherwise its the same), and retroarch.glslp itself 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 in retroarch.glslp).
      • So when cycling is active, effectively retroarch.glsp is 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

Toggling issues

  • When toggling OFF and the current directory (where-ever that may be, interplay with video_shader_remember_last_dir is unpredictable) has no retroarch.glslp file, 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.glslp is 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 into retroarch.glslp thus 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.glslp which 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from libretro/RetroArch

All issues in libretro/RetroArch

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.