Added
- noise,
- “soft pixel” size,
- 2 masks CGWG & BGR,
- mask size,
- color shifting,
- brightness fixes for Sega and Amiga.
#version 450
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float blur, MASK, beaml, beamh, scanl, scanh,INGAMMA,OUTGAMMA,SAT, WPR,WPG,
WPB, SIZE, BOOST, MSK_SIZE,Shadowmask, noise, SEGA;
} params;
#pragma parameter SIZE "Soft Pixel Size" 0.5 0.125 4.0 0.125
#define SIZE params.SIZE
#pragma parameter blur "Pixel Softness" 0.7 0.0 1.0 0.05
#define blur params.blur
#pragma parameter beamh "Beam Low" 6.0 2.0 15.0 1.0
#define beamh params.beamh
#pragma parameter beaml "Beam High" 8.0 2.0 15.0 1.0
#define beaml params.beaml
#pragma parameter scanl "Scanline Dark" 1.35 0.3 3.0 0.05
#define scanl params.scanl
#pragma parameter scanh "Scanline Bright" 1.05 0.3 3.0 0.05
#define scanh params.scanh
#pragma parameter Shadowmask "Mask Type" 0.0 -1.0 2.0 1.0
#define Shadowmask params.Shadowmask
#pragma parameter MASK "Mask Brightness" 0.7 0.0 1.0 0.05
#define MASK params.MASK
#pragma parameter MSK_SIZE "Mask Size" 1.0 1.0 2.0 1.0
#define MSK_SIZE params.MSK_SIZE
#pragma parameter INGAMMA " Gamma In" 2.4 1.0 4.0 0.05
#define INGAMMA params.INGAMMA
#pragma parameter OUTGAMMA " Gamma Out" 2.25 1.0 4.0 0.05
#define OUTGAMMA params.OUTGAMMA
#pragma parameter SAT " Saturation" 1.1 0.0 2.0 0.05
#define SAT params.SAT
#pragma parameter WPR " Shift to Red" 0.1 -0.25 0.25 0.01
#define WPR params.WPR
#pragma parameter WPG " Shift to Green" -0.1 -0.25 0.25 0.01
#define WPG params.WPG
#pragma parameter WPB " Shift to Blue" 0.1 -0.25 0.25 0.01
#define WPB params.WPB
#pragma parameter BOOST " Bright Boost" 1.3 1.0 2.0 0.05
#define BOOST params.BOOST
#pragma parameter noise " Add Noise" 0.2 0.0 1.0 0.01
#define noise params.noise
#pragma parameter SEGA " Brightness Fix 1.0:Sega, 2:Amiga/ST" 0.0 0.0 2.0 1.0
#define SEGA params.SEGA
#define iTimer (float(params.FrameCount) / 60.0)
#define SourceSize params.SourceSize
#define OutputSize params.OutputSize
#define OriginalSize params.OriginalSize
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
vec3 mask( float x)
{
float m = floor(x/MSK_SIZE);
if (Shadowmask == 0.0)
{
m = fract(m*0.5);
if (m<0.5) return vec3(MASK); else return vec3(1.0);
}
else if (Shadowmask == 1.0)
{
m = fract(m*0.3333);
if (m<0.3333) return vec3(MASK,MASK,1.0);
else if (m<0.6666) return vec3(MASK,1.0,MASK);
else return vec3(1.0,MASK,MASK);
}
else return vec3(1.0);
}
// GUEST.R-DR.VENOM SCANLINES
float scan(float y, float l)
{
float beam = mix(beaml,beamh,y);
float scan = mix(scanl,scanh,l);
//the less y is (= the more is raised to), the less pronounced scanlines we get.
float ex = y*scan;
return exp2(-beam*ex*ex);
}
float snow(vec2 pos)
{
return fract(sin(iTimer * dot(pos.xy ,vec2(13,78.233))) * 43758.5453);
}
void main()
{
vec2 pos = vTexCoord.xy;
/// SHARP-BILINEAR Author: rsn8887
vec2 texel = pos * SourceSize.xy;
vec2 texel2 = pos * OutputSize.xy;
vec2 scale = max(floor(OutputSize.xy / SourceSize.xy), vec2(1.0, 1.0));
vec2 pixel = vec2(SIZE/OutputSize.x,0.0);
vec2 pixely = vec2(0.0,SIZE/OutputSize.y);
vec2 texel_floored = floor(texel);
vec2 texel_floored2 = floor(texel2);
vec2 s = fract(texel);
vec2 s2 = fract(texel2);
vec2 region_range = 0.5 - 0.5 / scale;
// Figure out where in the texel to sample to get correct pre-scaled bilinear.
// Uses the hardware bilinear interpolator to avoid having to sample 4 times manually.
vec2 center_dist = s - 0.5;
vec2 center_dist2 = s2 - 0.5;
vec2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;
vec2 f2 = (center_dist2 - clamp(center_dist2, -region_range, region_range))/scale + 0.5;
vec2 mod_texel = texel_floored + f;
vec2 mod_texel2 = texel_floored2 + f2;
vec2 uv=mod_texel / SourceSize.xy;
vec2 uv2=mod_texel2 / OutputSize.xy;
/// "GHOST" PIXELS LEFT/RIGHT CALCULATION
vec3 col = texture(Source, uv).rgb;
vec3 colr = texture(Source, uv2-pixel).rgb;
vec3 coll = texture(Source, uv2+pixel).rgb;
vec3 cold = texture(Source, uv2-pixely).rgb;
vec3 res = vec3 (col.r*(1.0-blur) + coll.r*blur,
col.g*(1.0-blur) + cold.g*blur,
col.b*(1.0-blur) + colr.b*blur);
vec3 lumweight = vec3(max(max(res.r,res.b),res.g));
float lum = dot(vec3(0.22,0.7,0.08),res);
res = pow(res,vec3(INGAMMA));
res = res*scan(fract(texel.y+0.5),lum)+res*scan(1.0-fract(texel.y+0.5),lum) ;
res *= mask(pos.x*OutputSize.x);
res *= mix(1.0,BOOST,lum);
res *= vec3(1.0+WPR, 1.0-WPR/2.0, 1.0-WPR/2.0);
res *= vec3(1.0-WPG/2.0, 1.0+WPG, 1.0-WPG/2.0);
res *= vec3(1.0-WPB/2.0, 1.0-WPB/2.0, 1.0+WPB);
res *= 1.0 + snow(uv * 2.0) * (1.0-lumweight) *noise;
res = pow(res,vec3(1.0/OUTGAMMA));
if (SEGA == 1.0) res *= 1.0625; else if (SEGA == 2.0) res *=2.0; else res;
res = mix(vec3(lum),res,SAT);
FragColor = vec4(res,1.0);
}
Untouchables, another Amiga game with dark ST palette fixed