[FFXI + Linux] Getting vkBasalt Working
vkBasalt and ReShade have driven me nuts ever since I began exploring post-processing in FFXI on Linux. I finally did it, and here’s the fruit of my blood, sweat and sleep deprivation. :D
I’ve still got a few settings to iron out, but for now, I’m very happy with this :) it’s quite close to what I had on Windows with ReShade.
This article is a bit rough around the edges because I’m tired and I can’t really be bothered to write this :‘D so please excuse the bad.
1. Laying the Groundwork
Prerequisites
- A working Final Fantasy XI install
- Lutris or Steam to use as a launcher (if you’re insane enough to use Wine purely from the CLI, I won’t stop you… but you probably wouldn’t even need this guide with those skills :p)
- One of the Direct3D8 to Direct3D9 proxies (eg. dgVoodoo, DXVK (D8VK has been merged in), or atom0s’ proxy)
- ReShade filters of your choosing (You will need to download the .fx files from the repositories, not the .exe)
- MangoHud and vkBasalt (
lib32-mangohud
andlib32-vkbasalt
) - Ashita or Windower (Optional)
Getting DXVK to work
In a basic vanilla install, put the D3D8 to D3D9 (let’s just call it a proxy from now on) into your FINAL FANTASY XI folder (the one with the ROM folders in it).
If you’re using Windower or Ashita, you will need to put the proxy wherever the bootloaders are.
For Ashita v4, that will be your boot folder where pol.exe and xiloader.exe live. For Windower, it’s the main folder where Windower.exe and xiloader.exe live.
You can check if the proxy works by setting DXVK_HUD=fps
in Lutris and Steam. If an FPS counter appears at the top left, congratulations, it works. :D
However, life is often not so simple (for Ashita users specifically in my experience LOL). If your game crashes after you log into your character and run around for a bit, change the value of 0034 (game window mode) in your boot config. If that still doesn’t work, try a different proxy such as atom0s’ one, which should be the simplest option of the three.
Once DXVK works, the rest of the setup is a breeze.
Note
You may need to include D3DImm.dll and DDraw.dll in the same directory as pol.exe if you get a black screen when running PlayOnline.
This does not affect people who play on private servers, as they bypass PlayOnline.
If you choose dgVoodoo, please note that versions beyond 2.8.2 do not work for Linux.
2. vkBasalt and MangoHud
Setup
Make sure to install the 32-bit versions of these, or you will be banging your head on the table for hours.
For their default config files, copy them from /usr/share
into your ~/.config
folder in their own directories.
I didn’t figure out how to individually enable MangoHud and vkBasalt individually for FFXI because I think my system is a bit borked… but theoretically, if
you put your vkBasalt config with the proxy, it should work. If not, just stick your config in ~/.config/vkBasalt
as vkbasalt.conf and it will apply to everything with vkBasalt enabled.
As for MangoHud, you can enable it with MANGOHUD=1 %command%
on Steam, or as an environment variable on Lutris. Alternatively if you want it in everything,
you can export MANGOHUD=1
and ENABLE_VKBASALT=1
in your ~/.profile
or wherever your startup scripts are where you export your variables (looking at my fellow WM users).
To check vkBasalt is working, uncomment the vkBasalt option from your default MangoHud config. When you run the game, if MangoHud says it’s on, congratulations! It works.
Troubleshooting Tips
If you get stuck on something, run vkcube from cli with and without MangoHud and vkBasalt. It should tell you what you need to know if there’s an error in your config.
Additionally, you can use vkCube to get a baseline on your vkBasalt filters. vkCube is the easiest place to test things because you can restart it very easily.
Getting ReShade filters to work with vkBasalt
Download the ReShade filters to your desired location, and include the paths for them in your vkBasalt config file.
You will also need to include the uniform values (defaults) in your config as specified in the ReShade files.
Here’s an example of what you will see when you open a ReShade file:
Levels.fx
#include "ReShadeUI.fxh"
uniform int BlackPoint < __UNIFORM_SLIDER_INT1
ui_min = 0; ui_max = 255;
ui_label = "Black Point";
ui_tooltip = "The black point is the new black - literally. Everything darker than this will become completely black.";
> = 16;
uniform int WhitePoint < __UNIFORM_SLIDER_INT1
ui_min = 0; ui_max = 255;
ui_label = "White Point";
ui_tooltip = "The new white point. Everything brighter than this becomes completely white";
> = 235;
uniform bool HighlightClipping <
ui_label = "Highlight clipping pixels";
ui_tooltip = "Colors between the two points will stretched, which increases contrast, but details above and below the points are lost (this is called clipping).\n"
"This setting marks the pixels that clip.\n"
"Red: Some detail is lost in the highlights\n"
"Yellow: All detail is lost in the highlights\n"
"Blue: Some detail is lost in the shadows\n"
"Cyan: All detail is lost in the shadows.";
> = false;
You need to include these uniform values as values in your vkBasalt config. Here’s my file to give you an idea on how it’s supposed to be used.
#effects is a colon seperated list of effect to use
#e.g.: effects = fxaa:cas
#effects will be run in order from left to right
#one effect can be run multiple times e.g. smaa:smaa:cas
#cas - Contrast Adaptive Sharpening
#dls - Denoised Luma Sharpening
#fxaa - Fast Approximate Anti-Aliasing
#smaa - Enhanced Subpixel Morphological Antialiasing
#lut - Color LookUp Table
effects = vibrance:levels:fxaa:smaa:cas:dls
vibrance = "/home/jasmint/Games/ReShade/reshade-shaders-slim/Shaders/Vibrance.fx"
levels = "/home/jasmint/Games/ReShade/reshade-shaders-slim/Shaders/Levels.fx"
reshadeTexturePath = "/home/jasmint/Games/ReShade/reshade-shaders-slim/Textures"
reshadeIncludePath = "/home/jasmint/Games/ReShade/reshade-shaders-slim/Shaders"
depthCapture = off
#ReShade filter uniforms (must be the same names as what's in the fx files!)
#Vibrance
Vibrance = 0.2
#Levels
BlackPoint = 10
WhitePoint = 255
HighlightClipping = false
#toggleKey toggles the effects on/off
toggleKey = End
#enableOnLaunch sets if the effects are enabled when started
enableOnLaunch = True
#casSharpness specifies the amount of sharpning in the CAS shader.
#0.0 less sharp, less artefacts, but not off
#1.0 maximum sharp more artefacts
#Everything in between is possible
#negative values sharpen even less, up to -1.0 make a visible difference
casSharpness = 0.3
#dlsSharpness specifies the amount of sharpening in the Denoised Luma Sharpening shader.
#Increase to sharpen details within the image.
#0.0 less sharp, less artefacts, but not off
#1.0 maximum sharp more artefacts
dlsSharpness = 0.2
#dlsDenoise specifies the amount of denoising in the Denoised Luma Sharpening shader.
#Increase to limit how intensely film grain within the image gets sharpened.
#0.0 min
#1.0 max
dlsDenoise = 1
#fxaaQualitySubpix can effect sharpness.
#1.00 - upper limit (softer)
#0.75 - default amount of filtering
#0.50 - lower limit (sharper, less sub-pixel aliasing removal)
#0.25 - almost off
#0.00 - completely off
fxaaQualitySubpix = 1.00
#fxaaQualityEdgeThreshold is the minimum amount of local contrast required to apply algorithm.
#0.333 - too little (faster)
#0.250 - low quality
#0.166 - default
#0.125 - high quality
#0.063 - overkill (slower)
fxaaQualityEdgeThreshold = 0.063
#fxaaQualityEdgeThresholdMin trims the algorithm from processing darks.
#0.0833 - upper limit (default, the start of visible unfiltered edges)
#0.0625 - high quality (faster)
#0.0312 - visible limit (slower)
#Special notes: due to the current implementation you
#Likely want to set this to zero.
#As colors that are mostly not-green
#will appear very dark in the green channel!
#Tune by looking at mostly non-green content,
#then start at zero and increase until aliasing is a problem.
fxaaQualityEdgeThresholdMin = 0.0312
#smaaEdgeDetection changes the edge detection shader
#luma - default
#color - might catch more edges, but is more expensive
smaaEdgeDetection = color
#smaaThreshold specifies the threshold or sensitivity to edges
#Lowering this value you will be able to detect more edges at the expense of performance.
#Range: [0, 0.5]
#0.1 is a reasonable value, and allows to catch most visible edges.
#0.05 is a rather overkill value, that allows to catch 'em all.
smaaThreshold = 0.05
#smaaMaxSearchSteps specifies the maximum steps performed in the horizontal/vertical pattern searches
#Range: [0, 112]
#4 - low
#8 - medium
#16 - high
#32 - ultra
smaaMaxSearchSteps = 32
#smaaMaxSearchStepsDiag specifies the maximum steps performed in the diagonal pattern searches
#Range: [0, 20]
#0 - low, medium
#8 - high
#16 - ultra
smaaMaxSearchStepsDiag = 16
#smaaCornerRounding specifies how much sharp corners will be rounded
#Range: [0, 100]
#25 is a reasonable value
smaaCornerRounding = 25
#lutFile is the path to the LUT file that will be used
#supported are .CUBE files and .png with width == height * height
lutFile = "/home/jasmint/Games/ReShade/reshade-shaders-slim/Textures/lut.png"
I hope that made sense. :)
If it didn’t, SearXNG is your friend, and you can also ask me.
So… what if none of the proxies work?
If you’re an Ashita user, use Windower, or just use the vanilla client. You may also have to disable a few HD mods depending on what your error is.
(Run your game with Lutris debugging output enabled, or with Steam open via the cli!)
This applies to private server players such as HorizonXI, which use Ashita for their installs.
Your only other option is to attempt to use ReShade with OpenGL. Consider using this: https://github.com/kevinlekiller/reshade-steam-proton/tree/main
Hopefully it works for you.
If absolutely nothing works and you can’t play the game without post-processing… unfortunately, you will have to take the nuclear route.
That’s what I had to do after a long time of fighting this and not receiving any help, because I asked in the wrong places and said people didn’t understand
how important it was to have post-processing in my case as a mod developer. Big thanks to the Ashita community after I realised it was only happening on Ashita for me.
I will have to update the screenshots on my NexusMods page soon :)
That’s all I have for now. The sadder part of using vkBasalt is that you need to restart the game every time you change your vkBasalt config, but that’s still better than not having any post-processing at all. :)
Hope this helped, and if you have any questions, send me a message or email.
(Really though, I mainly wrote this for myself because this was driving me nutso and I never want to repeat this again)