Image Adjustment Shader

This is a combination of the bsnes-gamma-ramp shader and overscan correction. It allows you to modify overscan, color saturation, luminance (aka brightness) and, of course, gamma.

The default values of each option are set to no-change, but they’re easy to modify using the included #defines at the top of the file. You can add it at a 1.0 scale before (almost) any other shader to pre-process the image.

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

#define overscan float2(0.00, 0.00)
#define saturation 1.0
#define gamma 1.0
#define luminance 1.0

struct input
{
  float2 video_size;
  float2 texture_size;
  float2 output_size;
  float  frame_count;
  float  frame_direction;
  float frame_rotation;
  sampler2D texture;
};

void main_vertex
(
    float4 position    : POSITION,
    float4 color    : COLOR,
    float2 texCoord : TEXCOORD0,

    uniform float4x4 modelViewProj,
    uniform input IN,

    out float4 oPosition : POSITION,
    out float4 oColor    : COLOR,
    out float2 otexCoord : TEXCOORD
)
{
    oPosition = mul(modelViewProj, position);
    oColor = color;
    float2 shift = 0.5 * IN.video_size / IN.texture_size;
    float2 overscan_coord = (texCoord - shift) * (1.0 - overscan) + shift;
    otexCoord = overscan_coord;
}

struct output 
{
  float4 color    : COLOR;
};

float3 grayscale(float3 col)
{
   // Non-conventional way to do grayscale, but whatever
   return float3(dot(col, float3(0.3333)));
}

float4 main_fragment(float2 texCoord : TEXCOORD, uniform input IN) : COLOR
{
   float3 res = tex2D(IN.texture, texCoord).xyz;
   res = lerp(grayscale(res), res, saturation); // Apply saturation
   res = pow(res, float3(gamma)); // Apply gamma
   return float4(saturate(res * luminance), 1.0);
}
1 Like

Great! It can be very useful with many shader combinations. Thanks!

1 Like