Bsnes-gamma-ramp.cg

Came across this post:

http://i.imgur.com/AR9lcGq.png

So I’ve been messing around with the gamma shader on RA, which apparently is supposed to mimic the gamma ramp that higan uses, but after comparing it to higan proper, the results are not what I would call exact.

For clarification, the higan shot is the one on the left, with RA on the right. As you can see, it looks quite a bit darker, even though the settings on both higan and the gamma shader are exactly the same.

nothing I do makes it match the higan gamma ramp, which itself is also set to 150% if you check. I have a feeling the shader implementation itself is flawed.

I’ve noticed this too. At the default setting of 1.50, it’s way too strong.

Here’s a simpler, single-purpose gamma correction shader that should be more straightforward:

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

#define monitor_gamma 2.2
#define crt_gamma 2.4

// VERTEX SHADER //

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

    uniform float4x4 modelViewProj,

    out float4 oPosition : POSITION,
    out float2 otexCoord : TEXCOORD
)
{
    oPosition = mul(modelViewProj, position);
    otexCoord = texCoord;
}

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

struct output 
{
  float4 col    : COLOR;
};

// FRAGMENT SHADER //

output main_fragment(in float2 texCoord : TEXCOORD0,
uniform input IN,
uniform sampler2D texture : TEXUNIT0
)
{
float3 gamma = float3(1.0 - (crt_gamma - monitor_gamma));
float3 res = tex2D(IN.texture, texCoord).rgb;

   output OUT;
   OUT.col = float4(pow(res, 1.0 / gamma.rgb), 1.0);
   return OUT;
}

There are #defines at the top for monitor and crt gamma, and it will apply the exponential correction function based on the difference between those two numbers (just like in cgwg’s CRT shaders, among others).

Thank you my good man. I’m testing it out now. Seems to be working good. Not too dark. Seems as much as it should. I uploaded it to mediafire if anyone wants a quick download. Gave it a rather generic name.

http://www.mediafire.com/view/bkxxdflpp … terk%29.cg

That gamma calculation is wrong. The exponents multiply. (a ^ gamma) ^ invmonitor = a ^ (gamma / monitor).

>.< you’re right. Arithmetic fail. That was making it a smidge too dark, still. They do it the same way in this GLSL tutorial. Is that a difference between GLSL and Cg?

Is this better? It looks right, I think.

/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
*/

#define monitor_gamma 2.2
#define crt_gamma 2.4

// VERTEX SHADER //

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

    uniform float4x4 modelViewProj,

    out float4 oPosition : POSITION,
    out float2 otexCoord : TEXCOORD
)
{
    oPosition = mul(modelViewProj, position);
    otexCoord = texCoord;
}

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

struct output 
{
  float4 col    : COLOR;
};

// FRAGMENT SHADER //

output main_fragment(in float2 texCoord : TEXCOORD0,
uniform input IN,
uniform sampler2D texture : TEXUNIT0
)
{
float3 gamma = float3(crt_gamma / monitor_gamma);
float3 res = tex2D(IN.texture, texCoord).rgb;

   output OUT;
   OUT.col = float4(pow(res, gamma), 1.0);
   return OUT;
}

EDIT: it should have been a division of crt_gamma by monitor_gamma, rather than the difference. I updated the above code accordingly. Thanks, guys :slight_smile:

Thanks.

Should this be added to the common shaders repository?