Automatic porting of libretro shaders to mpv #14246
Replies: 2 comments 1 reply
-
|
This is seriously amazing, mad props for going to all this effort. It's also a bit sad, though, as I really dislike the mpv shader system and want to kill it, but I haven't yet found the time to rework the shader system from scratch. One of the numerous things we could do to improve the situation is to integrate slang directly into mpv/libplacebo. I noticed you mentioned I think it would make much more sense to use
You can hook |
Beta Was this translation helpful? Give feedback.
-
|
I use MPV all the time, but I currently watch some old anime through Retroarch because i cant get CRT-Royale to look the same in MPV as i do in Retroarch (using the CRT-Royale port someone made). But Retroarch's video player broke support for soft-subs long ago and it never got fixed. I would LOVE to use this. Please let me know when this becomes something the average user can use. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello!
I would like to showcase
mpv-libretroa project I made to convert libretro shaders (.slangp preset files & associated .slang source files) to the formatmpv --glsl-shaderexpects.Here's a presentation of the problem as well as some difficulties i encountered along the way.
(disclaimer: i'm still learning about shaders, some things i say here might be wrong)
Motivation
I wanted to watch Tool-Assisted Speedruns of retro games. These speedruns are encoded in the resolution of the actual console (e.g. 256x224 pixels).
While using
--scale=nearestis fine to a degree, libretro offers better upscaling filters for this type of content, e.g. emulating old CRT screens.However libretro shaders aren't compatible with mpv as-is, you need to transform them to use them in mpv, which is what
mpv-libretrodoes.Screenshots
Here are some screenshots at 1440p of some speedruns:
On the left,
--scale=nearestis used. On the right,--glsl-shader=crt-royale-fb-intel.glslis used (CRT Royale, fake bloom, intel preset), which has been ported from these sources: https://github.com/libretro/slang-shaders/blob/6cb93ce1be67b314a96f5e346befb2b58b63eb04/crt/crt-royale-fake-bloom-intel.slangp.--scale=nearest--glsl-shader=crt-royale-fb-intel.glslUsage
The sources are there: https://github.com/hhirtz/mpv-libretro
I don't have CI setup so it needs to be built from source. It's a rust project and as far as i can tell, only requires (an up-to-date enough) Rust to build.
The tool must be called from the command line, with the shader preset file as first and only argument. It prints the mpv-compatible GLSL shader to standard output, so you need to call it like so:
cargo run -- crt-geom-ntsc-composite-sharp.slangp >crt-geom.glslThe output shader uses
//!PARAMdirectives as well aslinearize/delinearize, so you need--vo=gpu-nextto use it, e.g.:The video must be of correct size. If it's already been upscaled, you need to downscale (and possibly crop) it first. This can be done in different ways:
mpv --vf=..., see https://github.com/hhirtz/mpv-retro-shaders/blob/073159d5465979f902cfe2147605e69de496dd05/README.md#usage-with-upscaled-videosThe correct size depends on the game and console.
How it's done and some difficulties
libretro shaders are organized this way: a shader preset file (
.slangpextension) lists all the shader passes and external textures (PNG and JPEG files), as well as some metadata for each pass.Each shader pass is in its separate
.slangfile.For some reason libretro allows shader authors to define their own vertex shaders (this might be for 3D games?). The structure of each
.slangfile is thus as follows:The conversion is done in several steps:
.slangpshader preset, to list all the passes, external textures and shader parameters. It also separates each .slang file into two (for the vertex and fragment shaders).//!PARAMas per libplacebo shader format. Both mpv's and libretro's parameter spec closely match so it's been easy to convert them//!TEXTURE, with a//!FORMAT rgba8, as I found is compatible with most hardware? All texture metadata (exceptmipmap, see limitations) are also added//!HOOK MAINpass. This has been by far the hardest step to do.MAINtexture from sRGB to linear RGB. libretro shaders work with linear RGB, and I think mpv converts the different color types to sRGB only, there is no way to say a shader works in linear RGB only.The reason the vertex and the fragment shaders have to be merged is that it turns out a lot of libretro shaders do interesting stuff in the vertex stage (other than
gl_Position=MVP*Position), so it cannot be just discarded. So we prefix all globals withvertex_andfragment_, merge the two Abstract Syntax Trees, and add the hook function:Some notes:
layout(set=..) in/out) are made into simple global variables that are shared between the two stages.framecount, and shader parameters). The list of dependencies to//!BINDfor each pass is built with this, as well as the samplers defined in the libretro shader.mat4(1.0), andPositionis set asvec4(HOOKED_pos, 0.0, 1.0).Here is a list of libretro shaders ported to mpv:
https://github.com/hhirtz/mpv-retro-shaders
With the exception of
crt-guest-advanced-ntsc.glsl,crt-lottes.glslandgba.glsl, all of these shaders have been ported using this method.Limitations
Naming issues aside, the two shader systems are fairly similar. Doing the conversion between the two has been actually pretty straightforward. The mpv docs and libplacebo website helped a lot. However, some advanced features in libretro are not present in mpv and prevent the correct conversion of some shaders:
wrap_mode, basically//!BORDER <CLAMP | REPEAT | MIRROR>in mpv, but not limited to external texturese.g. https://github.com/libretro/slang-shaders/blob/6cb93ce1be67b314a96f5e346befb2b58b63eb04/crt/crt-royale.slangp#L203
filter_linear, basically//!FILTER <LINEAR | NEAREST>in mpv, but not limited to external texturese.g. https://github.com/libretro/slang-shaders/blob/6cb93ce1be67b314a96f5e346befb2b58b63eb04/crt/crt-royale.slangp#L160
mipmap_input,float_framebufferandsrgb_framebuffer, which i actually am not sure what they do. mpv does not offer such settings//!BUFFER, but the size of the buffer has to be hardcoded). see Shader stage expansion for temporal shaders/algorithms? #8137Overall I'm very happy with mpv's shader system and the software in general, and wanted to contribute back a little. I will go back to enjoy some nice retro speedruns! Thank you to everyone involved in the project.
Beta Was this translation helpful? Give feedback.
All reactions