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);
}