MariENB FO4 3.2.7b
This commit is contained in:
parent
8fa0d0eb97
commit
d4df9ee642
23 changed files with 1190 additions and 1304 deletions
|
|
@ -34,25 +34,19 @@ float2 sres
|
|||
> = {0.0,0.0};
|
||||
/*
|
||||
palette type:
|
||||
-2 : Standard VGA 256-color palette
|
||||
-1 : disable
|
||||
0 : CGA (320x200 4-color, or 640x200 monochrome)
|
||||
1 : EGA (320x200, 16 colors)
|
||||
2 : RGB2 (64-color quarter VGA palette, used in AOS)
|
||||
3 : RGB323 (8-bit RGB, I don't think this was a real thing)
|
||||
4 : VGA (256 colors, standard palette)
|
||||
5 : Doom (256 colors, does not cover a lot)
|
||||
6 : Quake I (256 colors, covers even less)
|
||||
7 : RGB4 (4bpc, I also don't think this was ever used in real hardware)
|
||||
8 : RGB565 (ol' 16-bit "true color")
|
||||
9 : RGB6 (typical screens incapable of 8bpc)
|
||||
3 : VGA (256 colors)
|
||||
4 : RGB565 (ol' 16-bit "true color")
|
||||
*/
|
||||
int paltype
|
||||
<
|
||||
string UIName = "Palette Type";
|
||||
string UIWidget = "Spinner";
|
||||
int UIMin = -1;
|
||||
int UIMax = 9;
|
||||
int UIMax = 4;
|
||||
> = {1};
|
||||
/*
|
||||
CGA palette to use:
|
||||
|
|
@ -83,22 +77,46 @@ int egapal
|
|||
int UIMin = 0;
|
||||
int UIMax = 1;
|
||||
> = {0};
|
||||
/*
|
||||
VGA palette to use:
|
||||
0 : Standard VGA
|
||||
1 : Amulets & Armor
|
||||
2 : Blood
|
||||
3 : Doom
|
||||
4 : Duke Nukem 3D
|
||||
5 : Hacx 2.0
|
||||
6 : Heretic
|
||||
7 : Hexen
|
||||
8 : Hexen 2
|
||||
9 : Quake
|
||||
10 : Quake 2
|
||||
11 : Rise of the Triad
|
||||
12 : Shadow Warrior
|
||||
13 : Strife
|
||||
14 : Wolfenstein 3D
|
||||
TODO Project .Blank palette (when the design is finished)
|
||||
*/
|
||||
int vgapal
|
||||
<
|
||||
string UIName = "VGA Palette";
|
||||
string UIWidget = "Spinner";
|
||||
int UIMin = 0;
|
||||
int UIMax = 14;
|
||||
> = {0};
|
||||
/*
|
||||
Dithering mode:
|
||||
-1 : No dithering, just raw banding
|
||||
0 : 2x2 checkerboard dithering, looks like ass
|
||||
1 : 2x2 ordered dithering
|
||||
2 : 3x3 ordered dithering
|
||||
3 : 4x4 ordered dithering
|
||||
4 : 8x8 ordered dithering
|
||||
2 : 8x8 ordered dithering
|
||||
*/
|
||||
int dither
|
||||
<
|
||||
string UIName = "Dithering Pattern";
|
||||
string UIWidget = "Spinner";
|
||||
int UIMin = -1;
|
||||
int UIMax = 4;
|
||||
> = {4};
|
||||
int UIMax = 2;
|
||||
> = {2};
|
||||
/* gamma modifier for base color, lower values raise midtones and viceversa */
|
||||
float bgamma
|
||||
<
|
||||
|
|
@ -125,25 +143,6 @@ float bdmult
|
|||
string UIWidget = "Spinner";
|
||||
float UIMin = 0.0;
|
||||
> = {0.25};
|
||||
/* ASCII art filter */
|
||||
string str_ascii = "Luma ASCII Art Filter";
|
||||
bool asciienable
|
||||
<
|
||||
string UIName = "Enable ASCII";
|
||||
string UIWidget = "Checkbox";
|
||||
> = {false};
|
||||
bool asciimono
|
||||
<
|
||||
string UIName = "ASCII Monochrome";
|
||||
string UIWidget = "Checkbox";
|
||||
> = {true};
|
||||
float asciiblend
|
||||
<
|
||||
string UIName = "ASCII Blend";
|
||||
string UIWidget = "Spinner";
|
||||
float UIMin = 0.0;
|
||||
float UIMax = 1.0;
|
||||
> = {0.0};
|
||||
string str_mask = "Depth Chroma Key";
|
||||
bool maskenable
|
||||
<
|
||||
|
|
@ -162,64 +161,6 @@ float maskd
|
|||
float UIMin = 0.0;
|
||||
float UIMax = 1.0;
|
||||
> = {0.5};
|
||||
string str_dot = "RGBI Dot Matrix";
|
||||
bool dotenable
|
||||
<
|
||||
string UIName = "Enable Dot Matrix";
|
||||
string UIWidget = "Checkbox";
|
||||
> = {false};
|
||||
int dotsize
|
||||
<
|
||||
string UIName = "Dot Size";
|
||||
string UIWidget = "Spinner";
|
||||
int UIMin = 1;
|
||||
> = {1};
|
||||
float dotblend
|
||||
<
|
||||
string UIName = "Dot Blend";
|
||||
string UIWidget = "Spinner";
|
||||
float UIMin = 0.0;
|
||||
float UIMax = 1.0;
|
||||
> = {0.4};
|
||||
float dotmult
|
||||
<
|
||||
string UIName = "Dot Intensity";
|
||||
string UIWidget = "Spinner";
|
||||
float UIMin = 0.0;
|
||||
> = {1.0};
|
||||
float dotpow
|
||||
<
|
||||
string UIName = "Dot Contrast";
|
||||
string UIWidget = "Spinner";
|
||||
float UIMin = 0.0;
|
||||
> = {1.0};
|
||||
string str_curve = "Lens Curvature";
|
||||
bool curveenable
|
||||
<
|
||||
string UIName = "Enable Curvature";
|
||||
string UIWidget = "Checkbox";
|
||||
> = {false};
|
||||
float chromaab
|
||||
<
|
||||
string UIName = "Curve Chromatic Aberration";
|
||||
string UIWidget = "Spinner";
|
||||
> = {0.0};
|
||||
float lenszoom
|
||||
<
|
||||
string UIName = "Curve Zooming";
|
||||
string UIWidget = "Spinner";
|
||||
> = {50.0};
|
||||
float lensdist
|
||||
<
|
||||
string UIName = "Curve Distortion";
|
||||
string UIWidget = "Spinner";
|
||||
> = {0.0};
|
||||
float curvesoft
|
||||
<
|
||||
string UIName = "Curve Sampling Soften";
|
||||
string UIWidget = "Spinner";
|
||||
float UIMin = 0.0;
|
||||
> = {0.0};
|
||||
/* BlurSharpShift, some people are obsessed with this nonsense */
|
||||
string str_bss = "BlurSharpShift";
|
||||
bool bssblurenable
|
||||
|
|
@ -286,6 +227,25 @@ float lsharpblend
|
|||
string UIWidget = "Spinner";
|
||||
float UIMin = 0.0;
|
||||
> = {1.2};
|
||||
/* very cinematic black bars */
|
||||
string str_box = "Black Bars";
|
||||
bool boxenable
|
||||
<
|
||||
string UIName = "Enable Black Bars";
|
||||
string UIWidget = "Checkbox";
|
||||
> = {false};
|
||||
float boxh
|
||||
<
|
||||
string UIName = "Box Horizontal Ratio";
|
||||
string UIWidget = "Spinner";
|
||||
float UIMin = 1.0;
|
||||
> = {2.39};
|
||||
float boxv
|
||||
<
|
||||
string UIName = "Box Vertical Ratio";
|
||||
string UIWidget = "Spinner";
|
||||
float UIMin = 1.0;
|
||||
> = {1.0};
|
||||
|
||||
/*
|
||||
dithering threshold maps
|
||||
|
|
@ -303,23 +263,6 @@ static const float ordered2[4] =
|
|||
d(4),d(2)
|
||||
};
|
||||
#undef d
|
||||
#define d(x) x/9.0
|
||||
static const float ordered3[9] =
|
||||
{
|
||||
d(2),d(6),d(3),
|
||||
d(5),d(0),d(8),
|
||||
d(1),d(7),d(4)
|
||||
};
|
||||
#undef d
|
||||
#define d(x) x/16.0
|
||||
static const float ordered4[16] =
|
||||
{
|
||||
d( 0),d( 8),d( 2),d(10),
|
||||
d(12),d( 4),d(14),d( 6),
|
||||
d( 3),d(11),d( 1),d( 9),
|
||||
d(15),d( 7),d(13),d( 5)
|
||||
};
|
||||
#undef d
|
||||
#define d(x) x/64.0
|
||||
static const float ordered8[64] =
|
||||
{
|
||||
|
|
@ -333,94 +276,6 @@ static const float ordered8[64] =
|
|||
d(42),d(26),d(38),d(22),d(41),d(25),d(37),d(21)
|
||||
};
|
||||
#undef d
|
||||
/*
|
||||
palettes
|
||||
don't touch unless you know what you're doing
|
||||
*/
|
||||
#define d(x) x/3.0
|
||||
static const float3 cga1l[4] =
|
||||
{
|
||||
float3(d(0),d(0),d(0)),
|
||||
float3(d(0),d(2),d(2)),
|
||||
float3(d(2),d(0),d(2)),
|
||||
float3(d(2),d(2),d(2))
|
||||
};
|
||||
static const float3 cga1h[4] =
|
||||
{
|
||||
float3(d(0),d(0),d(0)),
|
||||
float3(d(1),d(3),d(3)),
|
||||
float3(d(3),d(1),d(3)),
|
||||
float3(d(3),d(3),d(3))
|
||||
};
|
||||
static const float3 cga2l[4] =
|
||||
{
|
||||
float3(d(0),d(0),d(0)),
|
||||
float3(d(0),d(2),d(0)),
|
||||
float3(d(2),d(0),d(0)),
|
||||
float3(d(2),d(1),d(0))
|
||||
};
|
||||
static const float3 cga2h[4] =
|
||||
{
|
||||
float3(d(0),d(0),d(0)),
|
||||
float3(d(1),d(3),d(1)),
|
||||
float3(d(3),d(1),d(1)),
|
||||
float3(d(3),d(2),d(1))
|
||||
};
|
||||
static const float3 cga3l[4] =
|
||||
{
|
||||
float3(d(0),d(0),d(0)),
|
||||
float3(d(0),d(2),d(2)),
|
||||
float3(d(2),d(0),d(0)),
|
||||
float3(d(2),d(2),d(2))
|
||||
};
|
||||
static const float3 cga3h[4] =
|
||||
{
|
||||
float3(d(0),d(0),d(0)),
|
||||
float3(d(1),d(3),d(3)),
|
||||
float3(d(3),d(1),d(1)),
|
||||
float3(d(3),d(3),d(3))
|
||||
};
|
||||
static const float3 stdega[16] =
|
||||
{
|
||||
float3(d(0),d(0),d(0)),
|
||||
float3(d(2),d(0),d(0)),
|
||||
float3(d(0),d(2),d(0)),
|
||||
float3(d(2),d(1),d(0)),
|
||||
float3(d(0),d(0),d(2)),
|
||||
float3(d(2),d(0),d(2)),
|
||||
float3(d(0),d(2),d(2)),
|
||||
float3(d(2),d(2),d(2)),
|
||||
float3(d(1),d(1),d(1)),
|
||||
float3(d(3),d(1),d(1)),
|
||||
float3(d(1),d(3),d(1)),
|
||||
float3(d(3),d(3),d(1)),
|
||||
float3(d(1),d(1),d(3)),
|
||||
float3(d(3),d(1),d(3)),
|
||||
float3(d(1),d(3),d(3)),
|
||||
float3(d(3),d(3),d(3))
|
||||
};
|
||||
#undef d
|
||||
#define d(x) x/256.0
|
||||
static const float3 aosega[16] =
|
||||
{
|
||||
float3(d( 0),d( 0),d( 0)),
|
||||
float3(d(128),d( 0),d( 0)),
|
||||
float3(d( 32),d(128),d( 0)),
|
||||
float3(d(160),d( 64),d( 32)),
|
||||
float3(d( 0),d( 32),d( 88)),
|
||||
float3(d( 60),d( 0),d( 88)),
|
||||
float3(d( 16),d(160),d(208)),
|
||||
float3(d( 88),d( 88),d( 88)),
|
||||
float3(d( 32),d( 32),d( 32)),
|
||||
float3(d(256),d( 64),d( 64)),
|
||||
float3(d( 72),d(256),d( 64)),
|
||||
float3(d(256),d(224),d( 60)),
|
||||
float3(d( 48),d(128),d(256)),
|
||||
float3(d(192),d( 48),d(256)),
|
||||
float3(d( 72),d(224),d(256)),
|
||||
float3(d(256),d(256),d(256)),
|
||||
};
|
||||
#undef d
|
||||
/* gauss stuff */
|
||||
float gauss3[3] =
|
||||
{
|
||||
|
|
@ -431,21 +286,13 @@ float4 ScreenSize;
|
|||
Texture2D TextureOriginal;
|
||||
Texture2D TextureColor;
|
||||
Texture2D TextureDepth;
|
||||
Texture2D TextureFont
|
||||
Texture2D TextureCGA
|
||||
<
|
||||
string ResourceName = "menbvgaluma.png";
|
||||
string ResourceName = "menbcgalut.png";
|
||||
>;
|
||||
Texture2D TextureDots
|
||||
Texture2D TextureEGA
|
||||
<
|
||||
string ResourceName = "menbdots.png";
|
||||
>;
|
||||
Texture2D TextureDoom
|
||||
<
|
||||
string ResourceName = "menbdoomlut.png";
|
||||
>;
|
||||
Texture2D TextureQuake
|
||||
<
|
||||
string ResourceName = "menbquakelut.png";
|
||||
string ResourceName = "menbegalut.png";
|
||||
>;
|
||||
Texture2D TextureVGA
|
||||
<
|
||||
|
|
@ -464,22 +311,6 @@ SamplerState SamplerB
|
|||
AddressU = Border;
|
||||
AddressV = Border;
|
||||
};
|
||||
SamplerState SamplerFont
|
||||
{
|
||||
Filter = MIN_LINEAR_MAG_MIP_POINT;
|
||||
AddressU = Wrap;
|
||||
AddressV = Wrap;
|
||||
MaxLOD = 0;
|
||||
MinLOD = 0;
|
||||
};
|
||||
SamplerState SamplerDots
|
||||
{
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
AddressU = Wrap;
|
||||
AddressV = Wrap;
|
||||
MaxLOD = 0;
|
||||
MinLOD = 0;
|
||||
};
|
||||
SamplerState SamplerLUT
|
||||
{
|
||||
Filter = MIN_MAG_MIP_POINT;
|
||||
|
|
@ -541,10 +372,6 @@ float4 ReducePrepass( in float4 col, in float2 coord )
|
|||
else if ( dither == 1 )
|
||||
col += bdbump+ordered2[int(coord.x%2)+2*int(coord.y%2)]*bdmult;
|
||||
else if ( dither == 2 )
|
||||
col += bdbump+ordered3[int(coord.x%3)+3*int(coord.y%3)]*bdmult;
|
||||
else if ( dither == 3 )
|
||||
col += bdbump+ordered4[int(coord.x%4)+4*int(coord.y%4)]*bdmult;
|
||||
else if ( dither == 4 )
|
||||
col += bdbump+ordered8[int(coord.x%8)+8*int(coord.y%8)]*bdmult;
|
||||
col = saturate(col);
|
||||
return col;
|
||||
|
|
@ -559,75 +386,10 @@ float4 ReducePrepass( in float4 col, in float2 coord )
|
|||
*/
|
||||
float4 ReduceCGA( in float4 color, in float2 coord )
|
||||
{
|
||||
float4 dac = ReducePrepass(color,coord);
|
||||
if ( cgapal == 0 )
|
||||
{
|
||||
dac.a = (dac.r+dac.g+dac.b)/3.0;
|
||||
return (dac.a>0.5);
|
||||
}
|
||||
float dist = 2.0;
|
||||
int idx = 0;
|
||||
if ( cgapal == 1 )
|
||||
{
|
||||
[unroll] for ( int i=0; i<4; i++ )
|
||||
if ( distance(dac.rgb,cga1l[i]) < dist )
|
||||
{
|
||||
idx = i;
|
||||
dist = distance(dac.rgb,cga1l[i]);
|
||||
}
|
||||
color.rgb = cga1l[idx];
|
||||
}
|
||||
else if ( cgapal == 2 )
|
||||
{
|
||||
[unroll] for ( int i=0; i<4; i++ )
|
||||
if ( distance(dac.rgb,cga1h[i]) < dist )
|
||||
{
|
||||
idx = i;
|
||||
dist = distance(dac.rgb,cga1h[i]);
|
||||
}
|
||||
color.rgb = cga1h[idx];
|
||||
}
|
||||
else if ( cgapal == 3 )
|
||||
{
|
||||
[unroll] for ( int i=0; i<4; i++ )
|
||||
if ( distance(dac.rgb,cga2l[i]) < dist )
|
||||
{
|
||||
idx = i;
|
||||
dist = distance(dac.rgb,cga2l[i]);
|
||||
}
|
||||
color.rgb = cga2l[idx];
|
||||
}
|
||||
else if ( cgapal == 4 )
|
||||
{
|
||||
[unroll] for ( int i=0; i<4; i++ )
|
||||
if ( distance(dac.rgb,cga2h[i]) < dist )
|
||||
{
|
||||
idx = i;
|
||||
dist = distance(dac.rgb,cga2h[i]);
|
||||
}
|
||||
color.rgb = cga2h[idx];
|
||||
}
|
||||
else if ( cgapal == 5 )
|
||||
{
|
||||
[unroll] for ( int i=0; i<4; i++ )
|
||||
if ( distance(dac.rgb,cga3l[i]) < dist )
|
||||
{
|
||||
idx = i;
|
||||
dist = distance(dac.rgb,cga3l[i]);
|
||||
}
|
||||
color.rgb = cga3l[idx];
|
||||
}
|
||||
else if ( cgapal == 6 )
|
||||
{
|
||||
[unroll] for ( int i=0; i<4; i++ )
|
||||
if ( distance(dac.rgb,cga3h[i]) < dist )
|
||||
{
|
||||
idx = i;
|
||||
dist = distance(dac.rgb,cga3h[i]);
|
||||
}
|
||||
color.rgb = cga3h[idx];
|
||||
}
|
||||
return color;
|
||||
float4 dac = clamp(ReducePrepass(color,coord)+0.005,0.005,0.995);
|
||||
float2 lc = float2((dac.r+cgapal)/7.0,
|
||||
dac.g/64.0+floor(dac.b*64.0)/64.0);
|
||||
return TextureCGA.Sample(SamplerLUT,lc);
|
||||
}
|
||||
/*
|
||||
EGA technically only had the 320x200 16-colour graphic mode, but when VGA
|
||||
|
|
@ -637,30 +399,10 @@ float4 ReduceCGA( in float4 color, in float2 coord )
|
|||
*/
|
||||
float4 ReduceEGA( in float4 color, in float2 coord )
|
||||
{
|
||||
float4 dac = ReducePrepass(color,coord);
|
||||
float dist = 2.0;
|
||||
int idx = 0;
|
||||
if ( egapal == 0 )
|
||||
{
|
||||
[unroll] for ( int i=0; i<16; i++ )
|
||||
if ( distance(dac.rgb,stdega[i]) < dist )
|
||||
{
|
||||
idx = i;
|
||||
dist = distance(dac.rgb,stdega[i]);
|
||||
}
|
||||
color.rgb = stdega[idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
[unroll] for ( int i=0; i<16; i++ )
|
||||
if ( distance(dac.rgb,aosega[i]) < dist )
|
||||
{
|
||||
idx = i;
|
||||
dist = distance(dac.rgb,aosega[i]);
|
||||
}
|
||||
color.rgb = aosega[idx];
|
||||
}
|
||||
return color;
|
||||
float4 dac = clamp(ReducePrepass(color,coord)+0.005,0.005,0.995);
|
||||
float2 lc = float2((dac.r+egapal)/2.0,
|
||||
dac.g/64.0+floor(dac.b*64.0)/64.0);
|
||||
return TextureEGA.Sample(SamplerLUT,lc);
|
||||
}
|
||||
/* A two bits per channel mode that can usually fit VGA mode 13h and mode x */
|
||||
float4 ReduceRGB2( in float4 color, in float2 coord )
|
||||
|
|
@ -669,20 +411,6 @@ float4 ReduceRGB2( in float4 color, in float2 coord )
|
|||
color.rgb = trunc(dac.rgb*4.0)/4.0;
|
||||
return color;
|
||||
}
|
||||
/* Effectively has 256 colours, with a magenta tint due to precision loss */
|
||||
float4 ReduceRGB323( in float4 color, in float2 coord )
|
||||
{
|
||||
float4 dac = ReducePrepass(color,coord);
|
||||
color.rgb = trunc(dac.rgb*float3(8.0,4.0,8.0))/float3(8.0,4.0,8.0);
|
||||
return color;
|
||||
}
|
||||
/* 4096 colours, no actual graphics hardware existed that used 4bpc, though */
|
||||
float4 ReduceRGB4( in float4 color, in float2 coord )
|
||||
{
|
||||
float4 dac = ReducePrepass(color,coord);
|
||||
color.rgb = trunc(dac.rgb*16.0)/16.0;
|
||||
return color;
|
||||
}
|
||||
/*
|
||||
The classic 16-bit colour mode everyone from my generation would remember,
|
||||
especially that subtle green tint and the banding due to lack of dithering
|
||||
|
|
@ -695,38 +423,12 @@ float4 ReduceRGB565( in float4 color, in float2 coord )
|
|||
/float3(32.0,64.0,32.0);
|
||||
return color;
|
||||
}
|
||||
/*
|
||||
If you see no difference when using this, then it could be because your
|
||||
own screen is already 6bpc. This is the case for a lot of LCDs, both old
|
||||
and modern. 8bpc tends to be the norm on IPS, though. 10bpc is the next
|
||||
step, but for now it's only used internally in video codecs for more
|
||||
efficient compression with lower quality loss. I seem to recall that in
|
||||
most *nix systems such as Linux it's possible to have 10bpc already with
|
||||
NVIDIA, but it causes compatibility issues with a lot of programs.
|
||||
*/
|
||||
float4 ReduceRGB6( in float4 color, in float2 coord )
|
||||
{
|
||||
float4 dac = ReducePrepass(color,coord);
|
||||
color.rgb = trunc(dac.rgb*64.0)/64.0;
|
||||
return color;
|
||||
}
|
||||
/* Various VGA 256-colour palettes: Doom, Quake I, and the standard. */
|
||||
float4 ReduceDoom( in float4 color, in float2 coord )
|
||||
{
|
||||
float4 dac = clamp(ReducePrepass(color,coord)+0.005,0.005,0.995);
|
||||
float2 lc = float2(dac.r,dac.g/64.0+floor(dac.b*64.0)/64.0);
|
||||
return TextureDoom.Sample(SamplerLUT,lc);
|
||||
}
|
||||
float4 ReduceQuake( in float4 color, in float2 coord )
|
||||
{
|
||||
float4 dac = clamp(ReducePrepass(color,coord)+0.005,0.005,0.995);
|
||||
float2 lc = float2(dac.r,dac.g/64.0+floor(dac.b*64.0)/64.0);
|
||||
return TextureQuake.Sample(SamplerLUT,lc);
|
||||
}
|
||||
/* Various VGA 256-colour palettes */
|
||||
float4 ReduceVGA( in float4 color, in float2 coord )
|
||||
{
|
||||
float4 dac = clamp(ReducePrepass(color,coord)+0.005,0.005,0.995);
|
||||
float2 lc = float2(dac.r,dac.g/64.0+floor(dac.b*64.0)/64.0);
|
||||
float2 lc = float2((dac.r+vgapal)/15.0,
|
||||
dac.g/64.0+floor(dac.b*64.0)/64.0);
|
||||
return TextureVGA.Sample(SamplerLUT,lc);
|
||||
}
|
||||
|
||||
|
|
@ -758,13 +460,8 @@ float4 PS_Retro( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
|||
if ( paltype == 0 ) res = ReduceCGA(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 1 ) res = ReduceEGA(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 2 ) res = ReduceRGB2(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 3 ) res = ReduceRGB323(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 4 ) res = ReduceVGA(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 5 ) res = ReduceDoom(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 6 ) res = ReduceQuake(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 7 ) res = ReduceRGB4(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 8 ) res = ReduceRGB565(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 9 ) res = ReduceRGB6(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 3 ) res = ReduceVGA(tcol,(coord*rresl)/sresl);
|
||||
else if ( paltype == 4 ) res = ReduceRGB565(tcol,(coord*rresl)/sresl);
|
||||
else res = tcol;
|
||||
if ( ncoord.x < 0 || ncoord.x >= 1 || ncoord.y < 0 || ncoord.y >= 1 )
|
||||
res *= 0;
|
||||
|
|
@ -772,41 +469,6 @@ float4 PS_Retro( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
|||
return res;
|
||||
}
|
||||
|
||||
/* ASCII art (more like CP437 art) */
|
||||
float4 PS_ASCII( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
||||
{
|
||||
float2 coord = IN.txcoord.xy;
|
||||
float4 res = TextureColor.Sample(Sampler,coord);
|
||||
if ( !asciienable ) return res;
|
||||
float2 bresl = float2(ScreenSize.x,ScreenSize.x*ScreenSize.w);
|
||||
float2 fresl = float2(FONT_WIDTH,FONT_HEIGHT);
|
||||
float2 cresl = float2(GLYPH_WIDTH,GLYPH_HEIGHT);
|
||||
float2 bscl = floor(bresl/cresl);
|
||||
/*
|
||||
Here I use the "cheap" method, based on the overall luminance of each
|
||||
glyph, rather than attempt to search for the best fitting glyph for
|
||||
each cell. If you want to know why, take a look at the ASCII filter
|
||||
bundled with the Dolphin emulator, and be prepared for the resulting
|
||||
seconds per frame it runs at. The calculations needed for such a filter
|
||||
are completely insane even for the highest-end GPUs.
|
||||
*/
|
||||
float3 col = TextureOriginal.Sample(Sampler,floor(bscl*coord)/bscl).rgb;
|
||||
int lum = clamp(luminance(col)*FONT_LEVELS,0,FONT_LEVELS);
|
||||
float2 itx = floor(coord*bresl);
|
||||
float2 blk = floor(itx/cresl)*cresl;
|
||||
float2 ofs = itx-blk;
|
||||
ofs.y += lum*cresl.y;
|
||||
ofs /= fresl;
|
||||
float gch = TextureFont.Sample(SamplerFont,ofs).x;
|
||||
if ( gch < 0.5 ) res.rgb = res.rgb*asciiblend;
|
||||
else
|
||||
{
|
||||
if ( asciimono ) res.rgb = 1.0;
|
||||
else res.rgb = col;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
float4 PS_ChromaKey( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
||||
{
|
||||
float2 coord = IN.txcoord.xy;
|
||||
|
|
@ -817,87 +479,6 @@ float4 PS_ChromaKey( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
|||
return res;
|
||||
}
|
||||
|
||||
/* 2x2 RGBI dot matrix, not even close to anything that exists IRL but meh */
|
||||
float4 PS_DotMatrix( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
||||
{
|
||||
float2 coord = IN.txcoord.xy;
|
||||
float4 res = TextureColor.Sample(Sampler,coord);
|
||||
if ( !dotenable ) return res;
|
||||
float2 bresl = float2(ScreenSize.x,ScreenSize.x*ScreenSize.w);
|
||||
bresl.xy *= 1.0/(dotsize*2.0);
|
||||
float4 dac = float4(res.r*0.5,res.g*0.5,res.b*0.5,
|
||||
(res.r+res.g+res.b)/6.0);
|
||||
/*
|
||||
There are two types of CRTs: aperture grille and shadow mask.
|
||||
The former is blurry and has scanlines (rather big ones, even), but
|
||||
is cheap to emulate; while the latter is the one most known for its
|
||||
crisp, square pixels with minimal distortion. Most individuals into
|
||||
this whole "retro graphics" stuff prefer aperture grille, which
|
||||
looks like shit, then again, that's the sort of visual quality they
|
||||
want. The main issue with shadow mask CRTs is that it's impossible
|
||||
to accurately emulate them unless done on a screen with a HUGE
|
||||
resolution. After all, the subpixels need to be clearly visible, and
|
||||
if on top of it you add curvature distortion, you need to reduce
|
||||
moire patterns that will inevitably show up at low resolutions.
|
||||
|
||||
It would be more desirable to eventually have flat panels that can
|
||||
display arbitrary resolutions using a form of scaling that preserves
|
||||
square pixels with unnoticeable distortion (typically, with nearest
|
||||
neighbour you'd get some pixels that are bigger/smaller than others
|
||||
if the upscale resolution isn't an integer multiple of the real
|
||||
resolution.
|
||||
|
||||
This 2x2 RGBI thing is a rather naïve filter I made many years ago,
|
||||
it looks unlike any real CRT, but scales well. Its only problem is
|
||||
moire patterns when using the default size of 2x2.
|
||||
*/
|
||||
float4 dots = TextureDots.Sample(SamplerDots,coord*bresl)*dac;
|
||||
float3 tcol = pow(max(0,dots.rgb+dots.a),dotpow)*dotmult;
|
||||
res.rgb = res.rgb*(1-dotblend)+tcol*dotblend;
|
||||
return res;
|
||||
}
|
||||
/* that's right, CRT curvature */
|
||||
float4 PS_Curvature( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
||||
{
|
||||
float2 coord = IN.txcoord.xy;
|
||||
float4 res = TextureColor.Sample(Sampler,coord);
|
||||
if ( !curveenable ) return res;
|
||||
float2 bresl = float2(ScreenSize.x,ScreenSize.x*ScreenSize.w);
|
||||
float2 bof = (1.0/bresl)*curvesoft;
|
||||
float3 eta = float3(1+chromaab*0.009,1+chromaab*0.006,1+chromaab
|
||||
*0.003);
|
||||
float2 center = float2(coord.x-0.5,coord.y-0.5);
|
||||
float zfact = 100.0/lenszoom;
|
||||
float r2 = center.x*center.x+center.y*center.y;
|
||||
float f = 1+r2*lensdist*0.01;
|
||||
float x = f*zfact*center.x+0.5;
|
||||
float y = f*zfact*center.y+0.5;
|
||||
float2 rcoord = (f*eta.r)*zfact*(center.xy*0.5)+0.5;
|
||||
float2 gcoord = (f*eta.g)*zfact*(center.xy*0.5)+0.5;
|
||||
float2 bcoord = (f*eta.b)*zfact*(center.xy*0.5)+0.5;
|
||||
int i,j;
|
||||
float4 idist = float4(0,0,0,0);
|
||||
/*
|
||||
sticking a 5x5 gaussian blur with a tweakable radius in here to
|
||||
attempt to reduce moire patterns in some cases. Supersampling would
|
||||
be more useful for that, but ENB sucks ass through a crazy straw in
|
||||
that aspect, so it would be more desirable to use GeDoSaTo (I sure
|
||||
hope I can port all my stuff to it one day, at least the damn thing
|
||||
is FOSS).
|
||||
*/
|
||||
[unroll] for ( i=-2; i<=2; i++ ) [unroll] for ( j=-2; j<=2; j++ )
|
||||
{
|
||||
idist += gauss3[abs(i)]*gauss3[abs(j)]
|
||||
*float4(TextureColor.Sample(Sampler,rcoord+bof
|
||||
*float2(i,j)).r,TextureColor.Sample(SamplerB,gcoord+bof
|
||||
*float2(i,j)).g,TextureColor.Sample(SamplerB,bcoord+bof
|
||||
*float2(i,j)).b,TextureColor.Sample(SamplerB,float2(x,
|
||||
y)+bof*float2(i,j)).a);
|
||||
}
|
||||
res.rgb = idist.rgb;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Why am I doing this */
|
||||
float4 PS_Blur( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
||||
{
|
||||
|
|
@ -988,6 +569,24 @@ float4 PS_LumaSharp( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
|||
return theywillnotheal;
|
||||
}
|
||||
|
||||
/* ultimate super-cinematic immersive black bars */
|
||||
float4 PS_Cinematic( VS_OUTPUT_POST IN, float4 v0 : SV_Position0 ) : SV_Target
|
||||
{
|
||||
float2 coord = IN.txcoord.xy;
|
||||
float4 res = TextureColor.Sample(Sampler,coord);
|
||||
if ( !boxenable ) return res;
|
||||
float2 bresl = float2(ScreenSize.x,ScreenSize.x*ScreenSize.w);
|
||||
float sar = bresl.x/bresl.y;
|
||||
float tar = boxh/boxv;
|
||||
float2 box = (sar<tar)?float2(0.0,(bresl.y-(bresl.x/tar))*0.5)
|
||||
:float2((bresl.x-(bresl.y*tar))*0.5,0.0);
|
||||
box /= bresl;
|
||||
/* this is some kind of advanced black magic I can't understand */
|
||||
float2 test = saturate((coord*coord-coord)-(box*box-box));
|
||||
if ( -test.x != test.y ) res *= 0.0;
|
||||
return res;
|
||||
}
|
||||
|
||||
technique11 ExtraFilters <string UIName="MariENB";>
|
||||
{
|
||||
pass p0
|
||||
|
|
@ -1041,22 +640,6 @@ technique11 ExtraFilters6
|
|||
pass p0
|
||||
{
|
||||
SetVertexShader(CompileShader(vs_5_0,VS_PostProcess()));
|
||||
SetPixelShader(CompileShader(ps_5_0,PS_ASCII()));
|
||||
}
|
||||
}
|
||||
technique11 ExtraFilters7
|
||||
{
|
||||
pass p0
|
||||
{
|
||||
SetVertexShader(CompileShader(vs_5_0,VS_PostProcess()));
|
||||
SetPixelShader(CompileShader(ps_5_0,PS_DotMatrix()));
|
||||
}
|
||||
}
|
||||
technique11 ExtraFilters8
|
||||
{
|
||||
pass p0
|
||||
{
|
||||
SetVertexShader(CompileShader(vs_5_0,VS_PostProcess()));
|
||||
SetPixelShader(CompileShader(ps_5_0,PS_Curvature()));
|
||||
SetPixelShader(CompileShader(ps_5_0,PS_Cinematic()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue