mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-14 02:17:36 +08:00
103 lines
2.6 KiB
HLSL
103 lines
2.6 KiB
HLSL
/*
|
|
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();
|
|
}
|
|
}
|