Describe frame-rate shadow scaling

This commit is contained in:
RallyBlock committed 2026-10-25 07:06:28 -04:00
1 parent 2c7cb006db
commit 861f7d320e
1 file changed
+45 -4
+45 -4
View File
@@ -1,12 +1,53 @@
# ShaderFit
Client module for Blockland v21. It keeps the shadow map at a size this 32-bit game can allocate.
Client module for Blockland v21. While a world is drawing, it watches the frame rate and changes the shadow map to match. A low frame rate steps the map down. A stretch of high frame rate steps it back up. The map also stays inside the size this 32-bit process can allocate.
Place `ShaderFit.dll` in the game's `modules` folder, then quit and start Blockland from Steam. A DLL that is already loaded stays mapped until that restart.
Shader source is not modified.
The largest shadow map this build will use is 8192 with 4 cascades. 16384 is 2 GB and the game runs out of memory there, so that size is not used.
## Install
The DLL only changes rendering on this client.
Place `ShaderFit.dll` in the game's `modules` folder, then quit and start Blockland from Steam. A DLL that is already loaded stays mapped until that restart. The module only changes rendering on this client.
## What it follows
The shader quality setting chooses a shadow resolution and a cascade count. ShaderFit remembers that pair. Automatic changes are a temporary limit on top of it. Choosing a different quality replaces the remembered pair and clears the limit.
Each presented frame updates a smoothed frame rate. A frame longer than a quarter second is ignored, so a hitch does not look like a low rate. Scaling waits one second after shadows start, and then waits 2.5 seconds after every change.
Shadows have to be in use. Scaling pauses when shaders are off, when the shader name is `minimum`, or when the shadow size or cascade count is 0. It starts again when shadows are back.
## Stepping down and up
Under 50 fps for one second, the resolution is cut in half. The floor is 1024. At 1024, the next step removes one cascade. It will not go below one cascade.
Over 70 fps for eight seconds, one cascade is restored, up to the count from the quality setting. After the cascades are back, the resolution doubles, up to the cap for this adapter.
The frame rate gained by a step down is not treated as spare room. The map is raised only when the rate would still be about 65 fps after giving that gain back. If a raise drops the rate under 50 within the following second, the step is undone and another raise is blocked for 45 seconds.
Each change rebuilds the shadow map and writes a console line with the frame rate, resolution, and cascade count.
## How large a map can be
The shadow map is one 16-bit depth array: width times height times cascades times 2 bytes. The cap is the largest power of two that fits all of these:
- under 2 GB
- under a quarter of dedicated video memory
- inside `GL_MAX_TEXTURE_SIZE`
- at least 1024
8192 with 4 cascades is 512 MB. 16384 with 4 cascades is exactly 2 GB. This process runs out of memory at that size, so it is not chosen. If a rebuild larger than 8192 still turns shaders off, ShaderFit turns them back on at 8192.
An unknown adapter is not used as a reason to shrink the quality setting. Once an OpenGL context exists, the cap is taken from the current renderer, dedicated memory, and the maximum texture size. Before that, a vendor guess is used: NVIDIA 8192, AMD 4096, and Intel from the amount of dedicated memory.
## Console variables
- `$ShaderFit::Vendor`
- `$ShaderFit::Renderer`
- `$ShaderFit::DedicatedMB`
- `$ShaderFit::ShadowCap`
- `$ShaderFit::FrameRate`
The first shadow rebuild also logs the vendor, renderer name, dedicated memory, and cap.
## Build