Add crt-consumer and crt-cyclon. Update others. (#3223)
- Add crt-consumer.glsl; - Add crt-cyclon.fx and its bezel.png texture; - Fix crt-newpixie.fx Frame adjust to game's aspect ratio; - Update others shaders to the new functions to get uniform values.
This commit is contained in:
parent
54097fc14e
commit
2a90a88055
|
@ -0,0 +1,780 @@
|
|||
// Crt-Consumer
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[configuration]
|
||||
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Pre-Scale Sharpening
|
||||
OptionName = PRE_SCALE
|
||||
MinValue = 1.0
|
||||
MaxValue = 4.0
|
||||
StepAmount = 0.1
|
||||
DefaultValue = 1.5
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Convergence X
|
||||
OptionName = blurx
|
||||
MinValue = -4.0
|
||||
MaxValue = 4.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 0.25
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Convergence Y
|
||||
OptionName = blury
|
||||
MinValue = -4.0
|
||||
MaxValue = 4.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = -0.1
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Curvature X
|
||||
OptionName = warpx
|
||||
MinValue = 0.0
|
||||
MaxValue = 0.12
|
||||
StepAmount = 0.01
|
||||
DefaultValue = 0.03
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Curvature Y
|
||||
OptionName = warpy
|
||||
MinValue = 0.0
|
||||
MaxValue = 0.12
|
||||
StepAmount = 0.01
|
||||
DefaultValue = 0.04
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Corner size
|
||||
OptionName = corner
|
||||
MinValue = 0.0
|
||||
MaxValue = 0.10
|
||||
StepAmount = 0.01
|
||||
DefaultValue = 0.03
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Border Smoothness
|
||||
OptionName = smoothness
|
||||
MinValue = 100.0
|
||||
MaxValue = 600.0
|
||||
StepAmount = 5.0
|
||||
DefaultValue = 400.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Interlacing Toggle
|
||||
OptionName = inter
|
||||
MinValue = 0.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Interlacing Downscale Scanlines
|
||||
OptionName = Downscale
|
||||
MinValue = 1.0
|
||||
MaxValue = 8.0
|
||||
StepAmount = 1.
|
||||
DefaultValue = 2.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Beam low
|
||||
OptionName = scanlow
|
||||
MinValue = 1.0
|
||||
MaxValue = 15.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 6.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Beam high
|
||||
OptionName = scanhigh
|
||||
MinValue = 1.0
|
||||
MaxValue = 15.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 8.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Scanlines dark
|
||||
OptionName = beamlow
|
||||
MinValue = 0.5
|
||||
MaxValue = 2.5
|
||||
StepAmount = 0.0
|
||||
DefaultValue = 1.45
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Scanlines bright
|
||||
OptionName = beamhigh
|
||||
MinValue = 0.5
|
||||
MaxValue = 2.5
|
||||
StepAmount = 0.0
|
||||
DefaultValue = 1.05
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Protect White On Masks
|
||||
OptionName = preserve
|
||||
MinValue = 0.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.01
|
||||
DefaultValue = 0.98
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Bright boost dark pixels
|
||||
OptionName = brightboost1
|
||||
MinValue = 0.0
|
||||
MaxValue = 3.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 1.25
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Bright boost bright pixels
|
||||
OptionName = brightboost2
|
||||
MinValue = 0.0
|
||||
MaxValue = 3.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Glow pixels per axis
|
||||
OptionName = glow
|
||||
MinValue = 1.0
|
||||
MaxValue = 6.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 3.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Glow quality
|
||||
OptionName = quality
|
||||
MinValue = 0.25
|
||||
MaxValue = 4.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Glow intensity
|
||||
OptionName = glow_str
|
||||
MinValue = 0.0001
|
||||
MaxValue = 2.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 0.3
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Add Noise
|
||||
OptionName = nois
|
||||
MinValue = 0.0
|
||||
MaxValue = 32.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Post Brightness
|
||||
OptionName = postbr
|
||||
MinValue = 0.0
|
||||
MaxValue = 2.5
|
||||
StepAmount = 0.02
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Palette Fixes. Sega, PUAE Atari ST dark colors
|
||||
OptionName = palette_fix
|
||||
MinValue = 0.0
|
||||
MaxValue = 2.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Mask Type
|
||||
OptionName = Shadowmask
|
||||
MinValue = -1.0
|
||||
MaxValue = 8.0
|
||||
StepAmount = 1.
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Mask Size
|
||||
OptionName = masksize
|
||||
MinValue = 1.0
|
||||
MaxValue = 2.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Mask dark
|
||||
OptionName = MaskDark
|
||||
MinValue = 0.0
|
||||
MaxValue = 2.0
|
||||
StepAmount = 0.1
|
||||
DefaultValue = 0.2
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Mask light
|
||||
OptionName = MaskLight
|
||||
MinValue = 0.0
|
||||
MaxValue = 2.0
|
||||
StepAmount = 0.1
|
||||
DefaultValue = 1.5
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Slot Mask Strength
|
||||
OptionName = slotmask
|
||||
MinValue = 0.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Slot Mask Width
|
||||
OptionName = slotwidth
|
||||
MinValue = 1.0
|
||||
MaxValue = 6.0
|
||||
StepAmount = 0.5
|
||||
DefaultValue = 2.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Slot Mask Height: 2x1 or 4x1
|
||||
OptionName = double_slot
|
||||
MinValue = 1.0
|
||||
MaxValue = 2.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Slot Mask Size
|
||||
OptionName = slotms
|
||||
MinValue = 1.0
|
||||
MaxValue = 2.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Gamma Out
|
||||
OptionName = GAMMA_OUT
|
||||
MinValue = 0.0
|
||||
MaxValue = 4.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 2.25
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Saturation
|
||||
OptionName = sat
|
||||
MinValue = 0.0
|
||||
MaxValue = 2.0
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Contrast, 1.0:Off
|
||||
OptionName = contrast
|
||||
MinValue = 0.00
|
||||
MaxValue = 2.00
|
||||
StepAmount = 0.05
|
||||
DefaultValue = 1.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Color Temperature %
|
||||
OptionName = WP
|
||||
MinValue = -100.0
|
||||
MaxValue = 100.0
|
||||
StepAmount = 5.
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Red-Green Tint
|
||||
OptionName = rg
|
||||
MinValue = -1.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.005
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Red-Blue Tint
|
||||
OptionName = rb
|
||||
MinValue = -1.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.005
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Green-Red Tint
|
||||
OptionName = gr
|
||||
MinValue = -1.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.005
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Green-Blue Tint
|
||||
OptionName = gb
|
||||
MinValue = -1.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.005
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Blue-Red Tint
|
||||
OptionName = br
|
||||
MinValue = -1.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.005
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Blue-Green Tint
|
||||
OptionName = bg
|
||||
MinValue = -1.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.005
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Vignette On/Off
|
||||
OptionName = vignette
|
||||
MinValue = 0.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 0.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Vignette Power
|
||||
OptionName = vpower
|
||||
MinValue = 0.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 0.01
|
||||
DefaultValue = 0.15
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Vignette strength
|
||||
OptionName = vstr
|
||||
MinValue = 0.0
|
||||
MaxValue = 50.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 40.0
|
||||
|
||||
[OptionRangeFloat]
|
||||
GUIName = Switch off shader
|
||||
OptionName = alloff
|
||||
MinValue = 0.0
|
||||
MaxValue = 1.0
|
||||
StepAmount = 1.0
|
||||
DefaultValue = 0.0
|
||||
|
||||
|
||||
[/configuration]
|
||||
*/
|
||||
|
||||
#define iTime (float(GetTime())/2.0)
|
||||
#define iTimer (float(GetTime())/60.0)
|
||||
|
||||
#define SourceSize (vec4(1.0/GetInvNativePixelSize(),GetInvNativePixelSize()))
|
||||
|
||||
vec2 Warp(vec2 pos)
|
||||
{
|
||||
pos = pos * 2.0 - 1.0;
|
||||
pos *= vec2(1.0 + (pos.y * pos.y) * warpx, 1.0 + (pos.x * pos.x) * warpy);
|
||||
return pos * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float sw(float y, float l)
|
||||
{
|
||||
float beam = mix(scanlow, scanhigh, y);
|
||||
float scan = mix(beamlow, beamhigh, l);
|
||||
float ex = y * scan;
|
||||
return exp2(-beam * ex * ex);
|
||||
}
|
||||
|
||||
vec3 mask(vec2 x, vec3 col, float l)
|
||||
{
|
||||
x = floor(x / masksize);
|
||||
|
||||
if (Shadowmask == 0.0)
|
||||
{
|
||||
float m = fract(x.x * 0.4999);
|
||||
if (m < 0.4999) return vec3(1.0, MaskDark, 1.0);
|
||||
else return vec3(MaskDark, 1.0, MaskDark);
|
||||
}
|
||||
|
||||
else if (Shadowmask == 1.0)
|
||||
{
|
||||
vec3 Mask = vec3(MaskDark, MaskDark, MaskDark);
|
||||
float line = MaskLight;
|
||||
float odd = 0.0;
|
||||
|
||||
if (fract(x.x / 6.0) < 0.5) odd = 1.0;
|
||||
if (fract((x.y + odd) / 2.0) < 0.5) line = MaskDark;
|
||||
|
||||
float m = fract(x.x / 3.0);
|
||||
if (m < 0.333) Mask.b = MaskLight;
|
||||
else if (m < 0.666) Mask.g = MaskLight;
|
||||
else Mask.r = MaskLight;
|
||||
|
||||
Mask *= line;
|
||||
return Mask;
|
||||
}
|
||||
|
||||
else if (Shadowmask == 2.0)
|
||||
{
|
||||
float m = fract(x.x*0.3333);
|
||||
if (m < 0.3333) return vec3(MaskDark, MaskDark, MaskLight);
|
||||
if (m < 0.6666) return vec3(MaskDark, MaskLight, MaskDark);
|
||||
else return vec3(MaskLight, MaskDark, MaskDark);
|
||||
}
|
||||
|
||||
if (Shadowmask == 3.0)
|
||||
{
|
||||
float m = fract(x.x * 0.5);
|
||||
if (m < 0.5) return vec3(1.0, 1.0, 1.0);
|
||||
else return vec3(MaskDark, MaskDark, MaskDark);
|
||||
}
|
||||
|
||||
else if (Shadowmask == 4.0)
|
||||
{
|
||||
vec3 Mask = vec3(col.rgb);
|
||||
float line = MaskLight;
|
||||
float odd = 0.0;
|
||||
|
||||
if (fract(x.x / 4.0) < 0.5) odd = 1.0;
|
||||
if (fract((x.y + odd) / 2.0) < 0.5) line = MaskDark;
|
||||
|
||||
float m = fract(x.x / 2.0);
|
||||
if (m < 0.5) { Mask.r = 1.0; Mask.b = 1.0; }
|
||||
else Mask.g = 1.0;
|
||||
|
||||
Mask *= line;
|
||||
return Mask;
|
||||
}
|
||||
|
||||
else if (Shadowmask == 5.0)
|
||||
{
|
||||
vec3 Mask = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
if (fract(x.x / 4.0) < 0.5)
|
||||
{
|
||||
if (fract(x.y / 3.0) < 0.666)
|
||||
{
|
||||
if (fract(x.x / 2.0) < 0.5) Mask = vec3(1.0, MaskDark, 1.0);
|
||||
else Mask = vec3(MaskDark, 1.0, MaskDark);
|
||||
}
|
||||
else Mask *= l;
|
||||
}
|
||||
else if (fract(x.x / 4.0) >= 0.5)
|
||||
{
|
||||
if (fract(x.y / 3.0) > 0.333)
|
||||
{
|
||||
if (fract(x.x / 2.0) < 0.5) Mask = vec3(1.0, MaskDark, 1.0);
|
||||
else Mask = vec3(MaskDark, 1.0, MaskDark);
|
||||
}
|
||||
else Mask *= l;
|
||||
}
|
||||
|
||||
return Mask;
|
||||
}
|
||||
|
||||
else if (Shadowmask == 6.0)
|
||||
{
|
||||
vec3 Mask = vec3(MaskDark, MaskDark, MaskDark);
|
||||
if (fract(x.x / 6.0) < 0.5)
|
||||
{
|
||||
if (fract(x.y / 4.0) < 0.75)
|
||||
{
|
||||
if (fract(x.x / 3.0) < 0.3333) Mask.r = MaskLight;
|
||||
else if (fract(x.x / 3.0) < 0.6666) Mask.g = MaskLight;
|
||||
else Mask.b = MaskLight;
|
||||
}
|
||||
else Mask * l * 0.9;
|
||||
}
|
||||
else if (fract(x.x / 6.0) >= 0.5)
|
||||
{
|
||||
if (fract(x.y / 4.0) >= 0.5 || fract(x.y / 4.0) < 0.25)
|
||||
{
|
||||
if (fract(x.x / 3.0) < 0.3333) Mask.r = MaskLight;
|
||||
else if (fract(x.x / 3.0) < 0.6666) Mask.g = MaskLight;
|
||||
else Mask.b = MaskLight;
|
||||
}
|
||||
else Mask * l * 0.9;
|
||||
}
|
||||
return Mask;
|
||||
}
|
||||
|
||||
else if (Shadowmask == 7.0)
|
||||
{
|
||||
float m = fract(x.x * 0.3333);
|
||||
|
||||
if (m < 0.3333) return vec3(MaskDark, MaskLight, MaskLight * col.b); //Cyan
|
||||
if (m < 0.6666) return vec3(MaskLight * col.r, MaskDark, MaskLight); //Magenta
|
||||
else return vec3(MaskLight, MaskLight * col.g, MaskDark); //Yellow
|
||||
}
|
||||
|
||||
else if (Shadowmask == 8.0)
|
||||
{
|
||||
vec3 Mask = vec3(MaskDark, MaskDark, MaskDark);
|
||||
|
||||
float bright = MaskLight;
|
||||
float left = 0.0;
|
||||
if (fract(x.x / 6.0) < 0.5) left = 1.0;
|
||||
|
||||
float m = fract(x.x / 3.0);
|
||||
if (m < 0.333) Mask.b = 0.9;
|
||||
else if (m < 0.666) Mask.g = 0.9;
|
||||
else Mask.r = 0.9;
|
||||
|
||||
if (mod(x.y, 2.0) == 1.0 && left == 1.0 || mod(x.y, 2.0) == 0.0 && left == 0.0)
|
||||
Mask *= bright;
|
||||
|
||||
return Mask;
|
||||
}
|
||||
|
||||
else return vec3(1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
float SlotMask(vec2 pos, vec3 c)
|
||||
{
|
||||
if (slotmask == 0.0) return 1.0;
|
||||
|
||||
pos = floor(pos / slotms);
|
||||
float mx = pow(max(max(c.r, c.g), c.b), 1.33);
|
||||
float mlen = slotwidth * 2.0;
|
||||
float px = fract(pos.x / mlen);
|
||||
float py = floor(fract(pos.y / (2.0 * double_slot)) * 2.0 * double_slot);
|
||||
float slot_dark = mix(1.0 - slotmask, 1.0 - 0.80 * slotmask, mx);
|
||||
float slot = 1.0 + 0.7 * slotmask * (1.0 - mx);
|
||||
|
||||
if (py == 0.0 && px < 0.5) slot = slot_dark;
|
||||
else if (py == double_slot && px >= 0.5) slot = slot_dark;
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
mat4 contrastMatrix(float contrast)
|
||||
{
|
||||
float t = (1.0 - contrast) / 2.0;
|
||||
|
||||
return mat4(contrast, 0, 0, 0,
|
||||
0, contrast, 0, 0,
|
||||
0, 0, contrast, 0,
|
||||
t, t, t, 1);
|
||||
}
|
||||
|
||||
mat3 vign(float l)
|
||||
{
|
||||
// vec2 vpos = vTexCoord;
|
||||
vec2 vpos = GetCoordinates();
|
||||
vpos *= 1.0 - vpos.xy;
|
||||
|
||||
float vig = vpos.x * vpos.y * vstr;
|
||||
vig = min(pow(vig, vpower), 1.0);
|
||||
if (vignette == 0.0) vig = 1.0;
|
||||
|
||||
return mat3(vig, 0, 0,
|
||||
0, vig, 0,
|
||||
0, 0, vig);
|
||||
}
|
||||
|
||||
vec3 saturation(vec3 textureColor)
|
||||
{
|
||||
float luminance = length(textureColor.rgb) * 0.5775;
|
||||
|
||||
vec3 luminanceWeighting = vec3(0.4, 0.5, 0.1);
|
||||
if (luminance < 0.5) luminanceWeighting.rgb = (luminanceWeighting.rgb * luminanceWeighting.rgb)
|
||||
+ (luminanceWeighting.rgb * luminanceWeighting.rgb);
|
||||
|
||||
luminance = dot(textureColor.rgb, luminanceWeighting);
|
||||
vec3 greyScaleColor = vec3(luminance, luminance, luminance);
|
||||
|
||||
vec3 res = vec3(mix(greyScaleColor, textureColor.rgb, sat));
|
||||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vec3 glow0 (vec2 texcoord, vec3 col)
|
||||
{
|
||||
|
||||
// the more quality, the smaller the offset and better quality, less visible glow too
|
||||
vec2 size = SourceSize.zw/quality;
|
||||
|
||||
vec3 c01;
|
||||
vec3 sum = vec3(0.0);
|
||||
|
||||
// glow = pixels per axis, the more the slower!
|
||||
|
||||
for (float x = -glow; x <= glow; x = x+1.0)
|
||||
{
|
||||
|
||||
// multiply texture, the more far away the less pronounced
|
||||
float factor = 1.0/glow;
|
||||
for (float y = -glow; y <= glow; y = y+1.0)
|
||||
{
|
||||
|
||||
vec2 offset = vec2(x, y) * size;
|
||||
|
||||
c01 = SampleLocation(texcoord + offset).rgb*factor; c01 = c01*c01;
|
||||
|
||||
sum += c01;
|
||||
}
|
||||
}
|
||||
|
||||
return (glow_str * sum / (glow * glow )) ;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
float noise(vec2 co)
|
||||
{
|
||||
return fract(sin(iTimer * dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float corner0(vec2 coord)
|
||||
{
|
||||
coord = (coord - vec2(0.5, 0.5)) * 1.0 + vec2(0.5, 0.5);
|
||||
coord = min(coord, vec2(1.0, 1.0) - coord) * vec2(1.0, SourceSize.y / SourceSize.x);
|
||||
|
||||
vec2 cdist = vec2(corner, corner);
|
||||
coord = (cdist - min(coord, cdist));
|
||||
float dist = sqrt(dot(coord, coord));
|
||||
|
||||
return clamp((cdist.x - dist) * smoothness, 0.0, 1.0);
|
||||
}
|
||||
|
||||
const mat3 D65_to_XYZ = mat3(
|
||||
0.4306190, 0.2220379, 0.0201853,
|
||||
0.3415419, 0.7066384, 0.1295504,
|
||||
0.1783091, 0.0713236, 0.9390944);
|
||||
|
||||
const mat3 XYZ_to_D65 = mat3(
|
||||
3.0628971, -0.9692660, 0.0678775,
|
||||
-1.3931791, 1.8760108, -0.2288548,
|
||||
-0.4757517, 0.0415560, 1.0693490);
|
||||
|
||||
const mat3 D50_to_XYZ = mat3(
|
||||
0.4552773, 0.2323025, 0.0145457,
|
||||
0.3675500, 0.7077956, 0.1049154,
|
||||
0.1413926, 0.0599019, 0.7057489);
|
||||
|
||||
const mat3 XYZ_to_D50 = mat3(
|
||||
2.9603944, -0.9787684, 0.0844874,
|
||||
-1.4678519, 1.9161415, -0.2545973,
|
||||
-0.4685105, 0.0334540, 1.4216174);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 vTexCoord = GetCoordinates();
|
||||
vec2 pos = Warp(vTexCoord.xy);
|
||||
vec2 tex_size = 1.0 / GetInvNativePixelSize();
|
||||
vec2 OutputSize = GetWindowSize();
|
||||
|
||||
|
||||
vec2 pC4 = (pos + 0.5/tex_size);
|
||||
vec2 fp = fract(pos * tex_size);
|
||||
if (inter < 0.5 && tex_size.y > 400.0){ fp.y = fract(pos.y * tex_size.y*1.0/Downscale);}
|
||||
|
||||
vec4 res = vec4(1.0);
|
||||
|
||||
if (alloff == 1.0)
|
||||
res = SampleLocation(pC4);
|
||||
else
|
||||
{
|
||||
|
||||
vec2 texel = pos * tex_size;
|
||||
vec2 texel_floored = floor(texel);
|
||||
|
||||
float scale = PRE_SCALE;
|
||||
float 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 = fp - 0.5;
|
||||
|
||||
vec2 fpp = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;
|
||||
|
||||
vec2 mod_texel = texel_floored + fpp;
|
||||
vec2 coords = mod_texel / SourceSize.xy;
|
||||
|
||||
vec3 sample1 = SampleLocation(vec2(coords.x + blurx*SourceSize.z, coords.y - blury*SourceSize.w)).rgb;
|
||||
vec3 sample2 = SampleLocation(coords).rgb;
|
||||
vec3 sample3 = SampleLocation(vec2(coords.x - blurx*SourceSize.z, coords.y + blury*SourceSize.w )).rgb;
|
||||
|
||||
vec3 color = vec3(sample1.r * 0.5 + sample2.r * 0.5,
|
||||
sample1.g * 0.25 + sample2.g * 0.5 + sample3.g * 0.25,
|
||||
sample2.b * 0.5 + sample3.b * 0.5);
|
||||
if (palette_fix != 0.0)
|
||||
{
|
||||
if (palette_fix == 1.0) color = color* 1.0667;
|
||||
else if (palette_fix == 2.0) color = color * 2.0;
|
||||
}
|
||||
|
||||
//COLOR TEMPERATURE FROM GUEST.R-DR.VENOM
|
||||
if (WP != 0.0)
|
||||
{
|
||||
vec3 warmer = D50_to_XYZ * color;
|
||||
warmer = XYZ_to_D65 * warmer;
|
||||
|
||||
vec3 cooler = D65_to_XYZ * color;
|
||||
cooler = XYZ_to_D50 * cooler;
|
||||
|
||||
float m = abs(WP) / 100.0;
|
||||
vec3 comp = (WP < 0.0) ? cooler : warmer;
|
||||
comp = clamp(comp, 0.0, 1.0);
|
||||
|
||||
color = vec3(mix(color, comp, m));
|
||||
}
|
||||
|
||||
mat3 hue = mat3 (1., rg, rb, //red tint
|
||||
gr, 1., gb, //green tint
|
||||
br, bg, 1.); //blue tint
|
||||
|
||||
color = hue * color;
|
||||
|
||||
color = (2.0*pow(color,vec3(2.8))) - pow(color,vec3(3.6));
|
||||
|
||||
float lum = color.r * 0.3 + color.g * 0.6 + color.b * 0.1;
|
||||
|
||||
float f = fract(fp.y -0.5);
|
||||
|
||||
if (inter > 0.5 && tex_size.y > 400.0) color = color;
|
||||
else
|
||||
{color = color * sw(f,lum) + color * sw (1.0-f,lum);}
|
||||
|
||||
float lum1 = color.r * 0.3 + color.g * 0.6 + color.b * 0.1;
|
||||
|
||||
|
||||
color *= mix(mask((vTexCoord * OutputSize.xy), color,lum1), vec3(1.0), lum1*preserve);
|
||||
|
||||
|
||||
if (slotmask != 0.0) color *= SlotMask((vTexCoord * OutputSize.xy) * 1.0001, color);
|
||||
|
||||
color *= mix(brightboost1, brightboost2, max(max(color.r, color.g), color.b));
|
||||
|
||||
|
||||
|
||||
color = pow(color,vec3(1.0 / GAMMA_OUT));
|
||||
if (glow_str != 0.0) color += glow0(coords,color);
|
||||
|
||||
if (sat != 1.0) color = saturation(color);
|
||||
if (corner != 0.0) color *= corner0(pC4);
|
||||
if (nois != 0.0) color *= 1.0 + noise(coords * 2.0) / nois;
|
||||
|
||||
color *= mix(1.0, postbr, lum);
|
||||
res = vec4(color, 1.0);
|
||||
if (contrast != 1.0) res = contrastMatrix(contrast) * res;
|
||||
if (inter > 0.5 && SourceSize.y > 400.0 && fract(iTime) < 0.5) res = res * 0.95;
|
||||
res.rgb *= vign(lum);
|
||||
|
||||
}
|
||||
|
||||
SetOutput(res);
|
||||
}
|
|
@ -256,7 +256,7 @@ void main()
|
|||
float scan_weight = 1.0 - pow(cos(vTexCoord.y * 2.0 * PI * SourceSize.y) * 0.5 + 0.5, scan_beam) * GetOption(SCANLINE_STRENGTH);
|
||||
|
||||
float mask = 1.0 - GetOption(MASK_STRENGTH);
|
||||
vec2 mod_fac = floor(vTexCoord * GetResolution().xy * SourceSize.xy / (SourceSize.xy * vec2(GetOption(MASK_SIZE), GetOption(MASK_DOT_HEIGHT) * GetOption(MASK_SIZE))));
|
||||
vec2 mod_fac = floor(vTexCoord * GetWindowSize().xy * SourceSize.xy / (SourceSize.xy * vec2(GetOption(MASK_SIZE), GetOption(MASK_DOT_HEIGHT) * GetOption(MASK_SIZE))));
|
||||
int dot_no = int(mod((mod_fac.x + mod(mod_fac.y, 2.0) * GetOption(MASK_STAGGER)) / GetOption(MASK_DOT_WIDTH), 3.0));
|
||||
vec3 mask_weight;
|
||||
|
||||
|
|
|
@ -502,7 +502,7 @@ void main()
|
|||
|
||||
color = color_boost*GAMMA_OUT(color);
|
||||
|
||||
vec2 mask_coords =vTexCoord.xy * GetResolution().xy;
|
||||
vec2 mask_coords =vTexCoord.xy * GetWindowSize().xy;
|
||||
|
||||
mask_coords = mix(mask_coords.xy, mask_coords.yx, GetOption(VSCANLINES));
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ else {
|
|||
}
|
||||
|
||||
float steps; if (GetOption(TYPE) == 0.0) steps = 0.5; else steps = 0.3333;
|
||||
float whichmask = fract(vTexCoord.x*GetResolution().x*steps);
|
||||
float whichmask = fract(vTexCoord.x*GetWindowSize().x*steps);
|
||||
float mask = 1.0 + float(whichmask < steps) * (-GetOption(MASK_DARK));
|
||||
|
||||
colour.rgb = mix(mask*colour, colour, dot(colour.rgb,vec3(maskFade)));
|
||||
|
|
|
@ -132,7 +132,7 @@ void main()
|
|||
{
|
||||
vec2 texCoord = GetCoordinates();
|
||||
vec2 SourceSize = 1.0 / GetInvNativePixelSize();
|
||||
float aa_factor = 2.0* (1.0/GetResolution().x) * SourceSize.x;
|
||||
float aa_factor = 2.0* (1.0/GetWindowSize().x) * SourceSize.x;
|
||||
|
||||
vec4 edri, edr, edr_l, edr_u, px; // px = pixel, edr = edge detection rule
|
||||
vec4 irlv0, irlv1, irlv2l, irlv2u;
|
||||
|
|
|
@ -34,7 +34,7 @@ void main()
|
|||
vec2 vTexCoord = GetCoordinates();
|
||||
vec2 SourceSize = 1.0 / GetInvNativePixelSize();
|
||||
vec2 texelSize = 1.0 / SourceSize.xy;
|
||||
vec2 OutputSize = GetResolution().xy;
|
||||
vec2 OutputSize = GetWindowSize().xy;
|
||||
|
||||
vec2 range = vec2(abs(SourceSize.x / (OutputSize.x * SourceSize.x)), abs(SourceSize.y / (OutputSize.y * SourceSize.y)));
|
||||
range = range / 2.0 * 0.999;
|
||||
|
|
|
@ -109,6 +109,8 @@ float4 PS_NewPixie_Blur(float4 pos : SV_Position, float2 uv_tx : TEXCOORD0) : SV
|
|||
|
||||
//PASS 4
|
||||
uniform int FCount < source = "framecount"; >;
|
||||
uniform float2 BufferViewportRatio < source = "buffer_to_viewport_ratio"; >;
|
||||
|
||||
texture tFrame < source = "crt-newpixie/crtframe.png"; >
|
||||
{
|
||||
Width = 1024;
|
||||
|
@ -261,7 +263,8 @@ float4 PS_NewPixie_Final(float4 pos: SV_Position, float2 uv_tx : TEXCOORD0) : SV
|
|||
/* Frame */
|
||||
float2 fscale = float2( 0.026, -0.018);//float2( -0.018, -0.013 );
|
||||
uv = float2(uv.x, 1.-uv.y);
|
||||
float4 f= tex2D(sFrame,uv_tx.xy);//*((1.0)+2.0*fscale)-fscale-float2(-0.0, 0.005));
|
||||
// float4 f= tex2D(sFrame,uv_tx.xy);//*((1.0)+2.0*fscale)-fscale-float2(-0.0, 0.005));
|
||||
float4 f= tex2D(sFrame,(uv_tx-float2(0.5,0.5)) * BufferViewportRatio + float2(0.5,0.5));//*((1.0)+2.0*fscale)-fscale-float2(-0.0, 0.005));
|
||||
f.xyz = lerp( f.xyz, float3(0.5,0.5,0.5), 0.5 );
|
||||
float fvig = clamp( -0.00+512.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y), 0.2, 0.8 );
|
||||
col = lerp( col, lerp( max( col, 0.0), pow( abs( f.xyz ), float3( 1.4,1.4,1.4 ) ) * fvig, f.w * f.w), float3( use_frame,use_frame,use_frame ) );
|
||||
|
|
|
@ -0,0 +1,555 @@
|
|||
#include "ReShade.fxh"
|
||||
|
||||
|
||||
// DariusG presents
|
||||
|
||||
// 'crt-Cyclon'
|
||||
|
||||
// Why? Because it's speedy!
|
||||
|
||||
// A super-fast shader based on the magnificent crt-Geom, optimized for full speed
|
||||
// on a Xiaomi Note 3 Pro cellphone (around 170(?) gflops gpu or so)
|
||||
|
||||
// This shader uses parts from:
|
||||
// crt-Geom (scanlines)
|
||||
// Quillez (main filter)
|
||||
// Grade (some primaries)
|
||||
// Dogway's inverse Gamma
|
||||
// Masks-slot-color handling, tricks etc are mine.
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation; either version 2 of the License, or (at your option)
|
||||
// any later version.
|
||||
|
||||
|
||||
|
||||
uniform float SCANLINE <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.2;
|
||||
ui_max = 0.6;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Scanline Weight";
|
||||
> = 0.3;
|
||||
|
||||
uniform float INTERLACE <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Interlacing On/Off";
|
||||
> = 1.0;
|
||||
|
||||
uniform float bogus_msk <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 0.0;
|
||||
ui_step = 0.0;
|
||||
ui_label = " [ MASK SETTINGS ] ";
|
||||
> = 0.0;
|
||||
|
||||
uniform float M_TYPE <
|
||||
ui_type = "drag";
|
||||
ui_min = -1.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Mask Type: -1:None, 0:CGWG, 1:RGB";
|
||||
> = 1.0;
|
||||
|
||||
uniform float MSIZE <
|
||||
ui_type = "drag";
|
||||
ui_min = 1.0;
|
||||
ui_max = 2.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Mask Size";
|
||||
> = 1.0;
|
||||
|
||||
uniform float SLOT <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Slot Mask On/Off";
|
||||
> = 1.0;
|
||||
|
||||
uniform float SLOTW <
|
||||
ui_type = "drag";
|
||||
ui_min = 2.0;
|
||||
ui_max = 3.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Slot Mask Width";
|
||||
> = 3.0;
|
||||
|
||||
uniform float BGR <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Subpixels BGR/RGB";
|
||||
> = 0.0;
|
||||
|
||||
uniform float Maskl <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Mask Brightness Dark";
|
||||
> = 0.3;
|
||||
|
||||
uniform float Maskh <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Mask Brightness Bright";
|
||||
> = 0.75;
|
||||
|
||||
uniform float bogus_geom <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 0.0;
|
||||
ui_step = 0.0;
|
||||
ui_label = " [ GEOMETRY SETTINGS ] ";
|
||||
> = 0.0;
|
||||
|
||||
uniform float bzl <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Bezel On/Off";
|
||||
> = 1.0;
|
||||
|
||||
uniform float ambient <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Ambient Light";
|
||||
> = 0.40;
|
||||
|
||||
uniform float zoomx <
|
||||
ui_type = "drag";
|
||||
ui_min = -1.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 0.005;
|
||||
ui_label = "Zoom Image X";
|
||||
> = 0.0;
|
||||
|
||||
uniform float zoomy <
|
||||
ui_type = "drag";
|
||||
ui_min = -1.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 0.005;
|
||||
ui_label = "Zoom Image Y";
|
||||
> = 0.0;
|
||||
|
||||
uniform float centerx <
|
||||
ui_type = "drag";
|
||||
ui_min = -5.0;
|
||||
ui_max = 5.0;
|
||||
ui_step = 0.0;
|
||||
ui_label = "Image Center X";
|
||||
> = 0.0;
|
||||
|
||||
uniform float centery <
|
||||
ui_type = "drag";
|
||||
ui_min = -5.0;
|
||||
ui_max = 5.0;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Image Center Y";
|
||||
> = 0.0;
|
||||
|
||||
uniform float WARPX <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.00;
|
||||
ui_max = 0.25;
|
||||
ui_step = 0.01;
|
||||
ui_label = "Curvature Horizontal";
|
||||
> = 0.02;
|
||||
|
||||
uniform float WARPY <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.00;
|
||||
ui_max = 0.25;
|
||||
ui_step = 0.01;
|
||||
ui_label = "Curvature Vertical";
|
||||
> = 0.01;
|
||||
|
||||
uniform float vig <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Vignette On/Off";
|
||||
> = 1.0;
|
||||
|
||||
uniform float bogus_col <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 0.0;
|
||||
ui_step = 0.0;
|
||||
ui_label = " [ COLOR SETTINGS ] ";
|
||||
> = 0.0;
|
||||
|
||||
uniform float BR_DEP <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 0.333;
|
||||
ui_step = 0.01;
|
||||
ui_label = "Scan/Mask Brightness Dependence";
|
||||
> = 0.2;
|
||||
|
||||
uniform float c_space <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 3.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Color Space: sRGB,PAL,NTSC-U,NTSC-J";
|
||||
> = 0.0;
|
||||
|
||||
uniform float EXT_GAMMA <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "External Gamma In (Glow etc)";
|
||||
> = 0.0;
|
||||
|
||||
uniform float SATURATION <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 2.0;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Saturation";
|
||||
> = 1.0;
|
||||
|
||||
uniform float BRIGHTNESS_ <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 2.0;
|
||||
ui_step = 0.01;
|
||||
ui_label = "Brightness, Sega fix:1.06";
|
||||
> = 1.0;
|
||||
|
||||
uniform float BLACK <
|
||||
ui_type = "drag";
|
||||
ui_min = -0.20;
|
||||
ui_max = 0.20;
|
||||
ui_step = 0.0;
|
||||
ui_label = "Black Level";
|
||||
> = 0.0;
|
||||
|
||||
uniform float RG <
|
||||
ui_type = "drag";
|
||||
ui_min = -0.25;
|
||||
ui_max = 0.25;
|
||||
ui_step = 0.01;
|
||||
ui_label = "Green <-to-> Red Hue";
|
||||
> = 0.0;
|
||||
|
||||
uniform float RB <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = -0.25;
|
||||
ui_step = 0.2;
|
||||
ui_label = "Blue <-to-> Red Hue";
|
||||
> = 0.0;
|
||||
|
||||
uniform float GB <
|
||||
ui_type = "drag";
|
||||
ui_min = -0.25;
|
||||
ui_max = 0.25;
|
||||
ui_step = 0.01;
|
||||
ui_label = "Blue <-to-> Green Hue";
|
||||
> = 0.0;
|
||||
|
||||
uniform float bogus_con <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 0.0;
|
||||
ui_step = 0.0;
|
||||
ui_label = " [ CONVERGENCE SETTINGS ] ";
|
||||
> = 0.0;
|
||||
|
||||
uniform float C_STR <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 0.5;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Convergence Overall Strength";
|
||||
> = 0.0;
|
||||
|
||||
uniform float CONV_R <
|
||||
ui_type = "drag";
|
||||
ui_min = -1.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Convergence Red X-Axis";
|
||||
> = 0.0;
|
||||
|
||||
uniform float CONV_G <
|
||||
ui_type = "drag";
|
||||
ui_min = -1.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Convergence Green X-axis";
|
||||
> = 0.0;
|
||||
|
||||
uniform float CONV_B <
|
||||
ui_type = "drag";
|
||||
ui_min = -1.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 0.05;
|
||||
ui_label = "Convergence Blue X-Axis";
|
||||
> = 0.0;
|
||||
|
||||
uniform float POTATO <
|
||||
ui_type = "drag";
|
||||
ui_min = 0.0;
|
||||
ui_max = 1.0;
|
||||
ui_step = 1.0;
|
||||
ui_label = "Potato Boost(Simple Gamma, adjust Mask)";
|
||||
> = 0.0;
|
||||
|
||||
|
||||
#define blck ((1.0)/(1.0-BLACK))
|
||||
#define pi 3.1415926535897932384626433
|
||||
|
||||
uniform float2 BufferViewportRatio < source = "buffer_to_viewport_ratio"; >;
|
||||
uniform float2 InternalPixelSize < source = "internal_pixel_size"; >;
|
||||
uniform float2 NativePixelSize < source = "native_pixel_size"; >;
|
||||
uniform float2 NormalizedInternalPixelSize < source = "normalized_internal_pixel_size"; >;
|
||||
uniform float2 NormalizedNativePixelSize < source = "normalized_native_pixel_size"; >;
|
||||
uniform float UpscaleMultiplier < source = "upscale_multiplier"; >;
|
||||
uniform float2 ViewportSize < source = "viewportsize"; >;
|
||||
|
||||
|
||||
uniform int FrameCount < source = "framecount"; >;
|
||||
texture tBezel < source = "crt-cyclon/bezel.png"; >
|
||||
{
|
||||
Width = BUFFER_WIDTH;
|
||||
Height = BUFFER_HEIGHT;
|
||||
MipLevels = 1;
|
||||
};
|
||||
|
||||
sampler sBezel { Texture = tBezel; AddressU = BORDER; AddressV = BORDER; MinFilter = LINEAR; MagFilter = LINEAR;};
|
||||
|
||||
float3 Mask(float2 pos, float CGWG)
|
||||
{
|
||||
float3 mask = float3(CGWG,CGWG,CGWG);
|
||||
|
||||
|
||||
if (M_TYPE == 0.0){
|
||||
|
||||
if (POTATO == 1.0) { float pot = (1.0-CGWG)*sin(pos.x*pi)+CGWG; return float3(pot,pot,pot); }
|
||||
else{
|
||||
float m = frac(pos.x*0.5);
|
||||
|
||||
if (m<0.5) mask.rb = float2(1.0,1.0);
|
||||
else mask.g = 1.0;
|
||||
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
|
||||
if (M_TYPE == 1.0){
|
||||
|
||||
if (POTATO == 1.0) { float pot = (1.0-CGWG)*sin(pos.x*pi*0.6667)+CGWG; return float3(pot,pot,pot );}
|
||||
else{
|
||||
float m = frac(pos.x*0.3333);
|
||||
|
||||
if (m<0.3333) mask.rgb = (BGR == 0.0) ? float3(mask.r, mask.g, 1.0) : float3(1.0, mask.g, mask.b);
|
||||
else if (m<0.6666) mask.g = 1.0;
|
||||
else mask.rgb = (BGR == 0.0) ? float3(1.0, mask.g, mask.b) : float3(mask.r, mask.g, 1.0);
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
else return float3(1.0,1.0,1.0);
|
||||
|
||||
}
|
||||
|
||||
float scanlineWeights(float distance, float3 color, float x)
|
||||
{
|
||||
// "wid" controls the width of the scanline beam, for each RGB
|
||||
// channel The "weights" lines basically specify the formula
|
||||
// that gives you the profile of the beam, i.e. the intensity as
|
||||
// a function of distance from the vertical center of the
|
||||
// scanline. In this case, it is gaussian if width=2, and
|
||||
// becomes nongaussian for larger widths. Ideally this should
|
||||
// be normalized so that the integral across the beam is
|
||||
// independent of its width. That is, for a narrower beam
|
||||
// "weights" should have a higher peak at the center of the
|
||||
// scanline than for a wider beam.
|
||||
float wid = SCANLINE + 0.15 * dot(color, float3(0.25-0.8*x, 0.25-0.8*x, 0.25-0.8*x)); //0.8 vignette strength
|
||||
float weights = distance / wid;
|
||||
return 0.4 * exp(-weights * weights ) / wid;
|
||||
}
|
||||
|
||||
#define pwr float3(1.0/((-1.0*SCANLINE+1.0)*(-0.8*CGWG+1.0))-1.2,1.0/((-1.0*SCANLINE+1.0)*(-0.8*CGWG+1.0))-1.2,1.0/((-1.0*SCANLINE+1.0)*(-0.8*CGWG+1.0))-1.2)
|
||||
// Returns gamma corrected output, compensated for scanline+mask embedded gamma
|
||||
float3 inv_gamma(float3 col, float3 power)
|
||||
{
|
||||
float3 cir = col-1.0;
|
||||
cir *= cir;
|
||||
col = lerp(sqrt(col),sqrt(1.0-cir),power);
|
||||
return col;
|
||||
}
|
||||
|
||||
// standard 6500k
|
||||
static const float3x3 PAL = float3x3(
|
||||
1.0740 , -0.0574 , -0.0119 ,
|
||||
0.0384 , 0.9699 , -0.0059 ,
|
||||
-0.0079 , 0.0204 , 0.9884 );
|
||||
|
||||
// standard 6500k
|
||||
static const float3x3 NTSC = float3x3(
|
||||
0.9318 , 0.0412 , 0.0217 ,
|
||||
0.0135 , 0.9711 , 0.0148 ,
|
||||
0.0055 , -0.0143 , 1.0085 );
|
||||
|
||||
// standard 8500k
|
||||
static const float3x3 NTSC_J = float3x3(
|
||||
0.9501 , -0.0431 , 0.0857 ,
|
||||
0.0265 , 0.9278 , 0.0432 ,
|
||||
0.0011 , -0.0206 , 1.3153 );
|
||||
|
||||
float3 slot(float2 pos)
|
||||
{
|
||||
float h = frac(pos.x/SLOTW);
|
||||
float v = frac(pos.y);
|
||||
|
||||
float odd;
|
||||
if (v<0.5) odd = 0.0; else odd = 1.0;
|
||||
|
||||
if (odd == 0.0)
|
||||
{if (h<0.5) return float3(0.5,0.5,0.5); else return float3(1.5,1.5,1.5);}
|
||||
|
||||
else if (odd == 1.0)
|
||||
{if (h<0.5) return float3(1.5,1.5,1.5); else return float3(0.5,0.5,0.5);}
|
||||
}
|
||||
|
||||
float2 Warp(float2 pos)
|
||||
{
|
||||
pos = pos*2.0-1.0;
|
||||
pos *= float2(1.0+pos.y*pos.y*WARPX, 1.0+pos.x*pos.x*WARPY);
|
||||
pos = pos*0.5+0.5;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
uniform float2 BufferHeight < source = "bufferheight"; >;
|
||||
|
||||
float4 CRT_CYCLON_PS(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD0) : SV_Target
|
||||
{
|
||||
float4 SourceSize = float4(1.0 / (NormalizedInternalPixelSize * UpscaleMultiplier), NormalizedInternalPixelSize * UpscaleMultiplier);
|
||||
float2 OutputSize = ViewportSize;
|
||||
float2 scale = BufferViewportRatio.xy;
|
||||
float2 warpcoords = (vTexCoord-float2(0.5,0.5)) * BufferViewportRatio + float2(0.5,0.5);
|
||||
|
||||
// Hue matrix inside main() to avoid GLES error
|
||||
float3x3 hue = float3x3(
|
||||
1.0, -RG, -RB,
|
||||
RG, 1.0, -GB,
|
||||
RB, GB, 1.0
|
||||
);
|
||||
// zoom in and center screen for bezel
|
||||
float2 pos = Warp((vTexCoord*float2(1.0-zoomx,1.0-zoomy)-float2(centerx,centery)/100.0));
|
||||
float4 bez = float4(0.0,0.0,0.0,0.0);
|
||||
// if (bzl == 1.0) bez = tex2D(sBezel,vTexCoord*SourceSize.xy/OriginalSize.xy*0.97+float2(0.015,0.015));
|
||||
// if (bzl == 1.0) bez = tex2D(sBezel,vTexCoord*scale*0.97+float2(0.015,0.015));
|
||||
if (bzl == 1.0) bez = tex2D(sBezel,warpcoords*0.97+float2(0.015,0.015)); // This fix Bezel to adjust to Game's aspect ratio.
|
||||
|
||||
bez.rgb = lerp(bez.rgb, float3(ambient,ambient,ambient),0.5);
|
||||
|
||||
float2 bpos = pos;
|
||||
float2 ps = SourceSize.zw;
|
||||
float2 dx = float2(ps.x,0.0);
|
||||
// Quilez
|
||||
float2 ogl2 = pos*SourceSize.xy;
|
||||
float2 i = floor(pos*SourceSize.xy) + 0.5;
|
||||
float f = ogl2.y - i.y;
|
||||
pos.y = (i.y + 4.0*f*f*f)*ps.y; // smooth
|
||||
pos.x = lerp(pos.x, i.x*ps.x, 0.2);
|
||||
|
||||
// Convergence
|
||||
float3 res0 = tex2D(ReShade::BackBuffer,pos).rgb;
|
||||
float resr = tex2D(ReShade::BackBuffer,pos + dx*CONV_R).r;
|
||||
float resb = tex2D(ReShade::BackBuffer,pos + dx*CONV_B).b;
|
||||
float resg = tex2D(ReShade::BackBuffer,pos + dx*CONV_G).g;
|
||||
|
||||
float3 res = float3( res0.r*(1.0-C_STR) + resr*C_STR,
|
||||
res0.g*(1.0-C_STR) + resg*C_STR,
|
||||
res0.b*(1.0-C_STR) + resb*C_STR
|
||||
);
|
||||
// Vignette
|
||||
float x = 0.0;
|
||||
if (vig == 1.0){
|
||||
x = vTexCoord.x*scale.x-0.5;
|
||||
// x = vTexCoord.x-0.5;
|
||||
x = x*x;}
|
||||
|
||||
float l = dot(float3(BR_DEP,BR_DEP,BR_DEP),res);
|
||||
|
||||
// Color Spaces
|
||||
if(EXT_GAMMA != 1.0) res *= res;
|
||||
if (c_space != 0.0) {
|
||||
if (c_space == 1.0) res = mul(PAL,res);
|
||||
if (c_space == 2.0) res = mul(NTSC,res);
|
||||
if (c_space == 3.0) res = mul(NTSC_J,res);
|
||||
// Apply CRT-like luminances
|
||||
res /= float3(0.24,0.69,0.07);
|
||||
res *= float3(0.29,0.6,0.11);
|
||||
res = clamp(res,0.0,1.0);
|
||||
}
|
||||
float s = frac(bpos.y*SourceSize.y-0.5);
|
||||
// handle interlacing
|
||||
if (SourceSize.y > 400.0)
|
||||
{
|
||||
s = frac(bpos.y*SourceSize.y/2.0-0.5);
|
||||
// if (INTERLACE == 1.0) s = mod(float(FrameCount),2.0) < 1.0 ? s: s+0.5;
|
||||
if (INTERLACE == 1.0) s = (float(FrameCount) % 2.0) < 1.0 ? s: s+0.5;
|
||||
}
|
||||
// Calculate CRT-Geom scanlines weight and apply
|
||||
float weight = scanlineWeights(s, res, x);
|
||||
float weight2 = scanlineWeights(1.0-s, res, x);
|
||||
res *= weight + weight2;
|
||||
|
||||
// Masks
|
||||
float2 xy = vTexCoord*OutputSize.xy*scale/MSIZE;
|
||||
// float2 xy = vTexCoord*OutputSize.xy/MSIZE;
|
||||
float CGWG = lerp(Maskl, Maskh, l);
|
||||
res *= Mask(xy, CGWG);
|
||||
// Apply slot mask on top of Trinitron-like mask
|
||||
if (SLOT == 1.0) res *= lerp(slot(xy/2.0),float3(1.0,1.0,1.0),CGWG);
|
||||
|
||||
if (POTATO == 0.0) res = inv_gamma(res,pwr);
|
||||
else {res = sqrt(res); res *= lerp(1.3,1.1,l);}
|
||||
|
||||
// Saturation
|
||||
float lum = dot(float3(0.29,0.60,0.11),res);
|
||||
res = lerp(float3(lum,lum,lum),res,SATURATION);
|
||||
|
||||
// Brightness, Hue and Black Level
|
||||
res *= BRIGHTNESS_;
|
||||
res = mul(hue,res);
|
||||
res -= float3(BLACK,BLACK,BLACK);
|
||||
res *= blck;
|
||||
// Apply bezel code, adapted from New-Pixie
|
||||
if (bzl >0.0)
|
||||
res.rgb = lerp(res.rgb, lerp(max(res.rgb, 0.0), pow( abs(bez.rgb), float3( 1.4,1.4,1.4 ) ), bez.w * bez.w), float3( 1.0,1.0,1.0 ) );
|
||||
|
||||
|
||||
return float4(res, 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
technique CRT_CYCLON
|
||||
{
|
||||
pass PS_CRT_CYCLON
|
||||
{
|
||||
VertexShader = PostProcessVS;
|
||||
PixelShader = CRT_CYCLON_PS;
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
Loading…
Reference in New Issue