Skip to content

Instantly share code, notes, and snippets.

@safijari
Created November 30, 2023 14:55
Show Gist options
  • Save safijari/1b936cbbdebe341fbe340bcfecb04450 to your computer and use it in GitHub Desktop.
Save safijari/1b936cbbdebe341fbe340bcfecb04450 to your computer and use it in GitHub Desktop.
Defringing for OLED Steam Deck Samsung Panel

tldr: Fringing happens because the subpixels are not properly aligned. It can be alleviated by "shifting" the underlying data to colocale in the center of the pixel. On the Samsung Panel, a simplistic solution to this is as follows:

green_amt = 0.2
red_amt = 0.4
blue_amt = 0.3
for i in range(1, im.shape[0]-1):
    for j in range(1, im.shape[1]-1):
        green_out[i, j] = green[i, j+1]*(green_amt) + green[i, j]*(1-green_amt)
        red_out[i, j] = red[i, j-1]*(red_amt) + red[i, j]*(1-red_amt)
        blue_out[i, j] = blue[i+1, j]*(blue_amt) + blue[i, j]*(1-blue_amt)
outim[:, :, 1] = green_out

The above ignores that green/red are a bit above the center and blue alternates between being in the left and right. Refinements are possible but for my personal usecases are not necessary at the moment.

@safijari
Copy link
Author

safijari commented Nov 30, 2023

@safijari
Copy link
Author

safijari commented Dec 1, 2023

uniform int Type <
        ui_type = "combo";
        ui_items = "Defring\0";
> = 0;

#include "ReShade.fxh"
#define pixel float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT)

float3 PS_Defring(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target
{
        float3 input = tex2D(ReShade::BackBuffer, texcoord).rgb;

        // these values are eyeballed
        float green_amt = 0.2;
        float red_amt = 0.4;
        float blue_amt = 0.3;

        float3 right = tex2D(ReShade::BackBuffer, float2(texcoord.x + 1.0*pixel.x, texcoord.y)).rgb;
        float3 left = tex2D(ReShade::BackBuffer, float2(texcoord.x - 1.0*pixel.x, texcoord.y)).rgb;
        float3 bottom = tex2D(ReShade::BackBuffer, float2(texcoord.x, texcoord.y + 1.0*pixel.y)).rgb;

        float3 correction;
        correction.r = input.r*(1-red_amt) + left.r*red_amt;
        correction.g = input.g*(1-green_amt) + right.g*green_amt;
        correction.b = input.b*(1-blue_amt) + bottom.b*blue_amt;

        return correction;
}

technique Defring
{
        pass
        {
                VertexShader = PostProcessVS;
                PixelShader = PS_Defring;
        }
}

@safijari
Copy link
Author

safijari commented Dec 2, 2023

Setting with vkbasalt

Installer: https://github.com/simons-public/steam-deck-vkbasalt-install

Copy shader to ~/.config/reshade/Shaders

Put the following in ~/.config/vkBasalt/vkBasalt.conf

effects = defring
defring = "/home/deck/.config/reshade/Shaders/Defring.fx"
reshadeTexturePath = "/home/deck/.config/reshade/Textures"
reshadeIncludePath = "/home/deck/.config/reshade/Shaders"
depthCapture = off
toggleKey = Home
enableOnLaunch = True

@p2ir
Copy link

p2ir commented Apr 22, 2024

Hey,

Thought I would comment here, hopefully this isn't totally the wrong place :) Thank you for creating the defring shader and for your work with reshadeck.

I have been using the shader with reshadeck, but I keep getting pretty high performance impact, most notably in elden ring and no mans sky. I tested it in injected reshade and it works perfectly with no performance impact. So I guess gamescope is having some issues. Anyway, I thought I would test it out in vkbasalt, as that would allow enabling it globally, but can't seem to get it working. I am just getting a blackscreen.

I installed vkbasalt and it is working normally, but when I add the "defring" to the effects and boot into games I get an black screen, I understand this is an issue often with reshade shaders and vkbasalt, and I was wondering if you had a similar issue or an idea why this might be happening? or if there are some prerequisites I am missing?

@safijari
Copy link
Author

Hey,

Thought I would comment here, hopefully this isn't totally the wrong place :) Thank you for creating the defring shader and for your work with reshadeck.

I have been using the shader with reshadeck, but I keep getting pretty high performance impact, most notably in elden ring and no mans sky. I tested it in injected reshade and it works perfectly with no performance impact. So I guess gamescope is having some issues. Anyway, I thought I would test it out in vkbasalt, as that would allow enabling it globally, but can't seem to get it working. I am just getting a blackscreen.

I installed vkbasalt and it is working normally, but when I add the "defring" to the effects and boot into games I get an black screen, I understand this is an issue often with reshade shaders and vkbasalt, and I was wondering if you had a similar issue or an idea why this might be happening? or if there are some prerequisites I am missing?

It's been a long time since I looked at the vkBasalt stuff. Sorry :(

How bad is the performance impact? I know some frame drops are possible but I've never seen something egregious. vkBasalt more than likely would have the same issues as gamescope though so maybe you're better off with injected reshade.

@p2ir
Copy link

p2ir commented Apr 22, 2024

No problem, thanks for the quick response! :)

In no mans sky I am mainly seeing the wattage jump up about 3-4w, fps is about the same as I locked it at 50. As for elden ring the frametimes jump quite a lot.. First I thought it is just something funky happening with vsync, but I disabled it through launch options and was still seeing it. The fps is about the same, just the frametimes are more jittery compared to default. But yea, not seeing these issues when injected through reshade. These tests aren't too scientific :D sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment