Welcome, Guest.
Username: Password: Remember me

TOPIC: EGA shader

EGA shader 2 years 7 months ago #1

Hi!

There is a nice EGA shader for DosBox created by VileR. (I know there already is the Nostalgia shader but it's a bit different)
/*
   Downsamples to 16 colors using quantization.
   Uses 4-bit RGBI values for an "EGA"/"Tandy" look
   
   Author: VileR
   License: public domain
*/

// 1.0 is the 'proper' value, 1.2 seems to give better results but brighter
// colors may clip.
#define color_enhance 1.2

// The name of this effect
string name : NAME = "EGAfilter";

// combineTechnique: Final combine steps. Outputs to destination frame buffer
string combineTechique : COMBINETECHNIQUE = "EGAfilter";

// Matrix Definitions for Scaler Effects
matrix World                : WORLD;
matrix View                 : VIEW;
matrix Projection           : PROJECTION;
matrix WorldView            : WORLDVIEW; // world * view
matrix ViewProjection       : VIEWPROJECTION; // view * projection
matrix WorldViewProjection  : WORLDVIEWPROJECTION; // world * view * projection

// Source Texture
texture SourceTexture : SOURCETEXTURE;

// Point Sampler
sampler SourcePointSampler = sampler_state {
 Texture   = (SourceTexture);
 MinFilter = POINT;
 MagFilter = POINT;
};  

// Vertex Shader Output
struct VS_OUTPUT_PRODUCT {
  float4  coord : POSITION;
  float2  TexCoord   : TEXCOORD0;
};

// Color lookup table (RGBI palette with brown fix)
const half3 rgbi_palette[16] = {
  half3(0.0,     0.0,     0.0),
  half3(0.0,     0.0,     0.66667),
  half3(0.0,     0.66667, 0.0),
  half3(0.0,     0.66667, 0.66667),
  half3(0.66667, 0.0,     0.0),
  half3(0.66667, 0.0,     0.66667),
  half3(0.66667, 0.33333, 0.0),
  half3(0.66667, 0.66667, 0.66667),
  half3(0.33333, 0.33333, 0.33333),
  half3(0.33333, 0.33333, 1.0),
  half3(0.33333, 1.0,     0.33333),
  half3(0.33333, 1.0,     1.0),
  half3(1.0,     0.33333, 0.33333),
  half3(1.0,     0.33333, 1.0),
  half3(1.0,     1.0,     0.33333),
  half3(1.0,     1.0,     1.0),
};

// Compare vector distances and return nearest RGBI color
half3 nearest_rgbi (half3 original) {
  half dst;
  half min_dst = 2.0;
  int idx = 0;
  for (int i=0; i<16; i++) {
    dst = distance(original, rgbi_palette[i]);
    if (dst < min_dst) {
      min_dst = dst;
      idx = i;
    }
  }
  return rgbi_palette[idx];
}

// Vertex shader
VS_OUTPUT_PRODUCT S_VERTEX (float3 p : POSITION, float2 tc : TEXCOORD0)
{
  VS_OUTPUT_PRODUCT OUT = (VS_OUTPUT_PRODUCT)0;

  OUT.coord = mul(float4(p,1),WorldViewProjection);
  OUT.TexCoord = tc;
  return OUT;
}

// Pixel shader
float4 S_FRAGMENT ( in VS_OUTPUT_PRODUCT VAR ) : COLOR
{
  half3 fragcolor = tex2D(SourcePointSampler, VAR.TexCoord).rgb;
  return half4(nearest_rgbi(fragcolor*color_enhance), 1);
}

technique EGAfilter
{
  pass P0
  {
    VertexShader = compile vs_3_0 S_VERTEX();
    PixelShader  = compile ps_3_0 S_FRAGMENT();
  }  
}

The same shader but with dithering is also available here:
https://github.com/ddionisio/MateImageEffects/blob/master/Shaders/EGAFilter.shader

sample image:



Can it be made compatible with reshade?
Thank you very much!
Last Edit: 2 years 7 months ago by psionic.
The administrator has disabled public write access.

EGA shader 2 years 7 months ago #2

I don't get why this shader is so complicated. A simple round(color.rgb*3.0)/3.0 should do the exact same.
The administrator has disabled public write access.

EGA shader 2 months 2 weeks ago #3

The Nostalgia shader does exactly the same only with a different palette.
I've updated Nostalgia so the user can select presets and the EGA palette will produce the same result if you first multiply the input color by 1.2 (this can be done with Lift Gamma Gain - it's a gain setting)

@Marty :
a round to 2-bit per component will yield 6 bit color so 64 color.
This reduces it to 16 colors.
The administrator has disabled public write access.