Moved shaders to a separate repo
|
@ -1,93 +0,0 @@
|
|||
#version 150
|
||||
|
||||
// AntiAliased Nearest Neighbor
|
||||
// by jimbo1qaz and wareya
|
||||
// Licensed MIT
|
||||
|
||||
precision highp float;
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
#define NOT(fl) (1-fl)
|
||||
#define YES(fl) fl
|
||||
|
||||
vec4 vpow(vec4 n, float e)
|
||||
{
|
||||
return vec4(pow(n.x, e), pow(n.y, e), pow(n.z, e), pow(n.w, e));
|
||||
}
|
||||
|
||||
vec4 getLQV(vec3 mine) {
|
||||
return vec4
|
||||
( mine.r
|
||||
, mine.g
|
||||
, mine.b
|
||||
, mine.r*0.2989 + mine.g*0.5870 + mine.b*0.1140);
|
||||
}
|
||||
vec3 fromLQV(vec4 mine) {
|
||||
float f = mine.w/(mine.r*0.2989 + mine.g*0.5870 + mine.b*0.1140);
|
||||
return vec3(mine.rgb)*f;
|
||||
}
|
||||
|
||||
vec3 percent(float ssize, float tsize, float coord) {
|
||||
float minfull = (coord*tsize - 0.5) /tsize*ssize;
|
||||
float maxfull = (coord*tsize + 0.5) /tsize*ssize;
|
||||
|
||||
float realfull = floor(maxfull);
|
||||
|
||||
if (minfull > realfull) {
|
||||
return vec3(1, (realfull+0.5)/ssize, (realfull+0.5)/ssize);
|
||||
}
|
||||
|
||||
return vec3(
|
||||
(maxfull - realfull) / (maxfull - minfull),
|
||||
(realfull-0.5) / ssize,
|
||||
(realfull+0.5) / ssize
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
float cheapsrgb = 2.1;
|
||||
float gamma = 3.0;
|
||||
vec3 xstuff = percent(sourceSize[0].x, targetSize[0].x, texCoord.x);
|
||||
vec3 ystuff = percent(sourceSize[0].y, targetSize[0].y, texCoord.y);
|
||||
|
||||
float xkeep = xstuff[0];
|
||||
float ykeep = ystuff[0];
|
||||
|
||||
// get points to interpolate across, in linear rgb
|
||||
vec4 a = getLQV(vpow(texture(source[0],vec2(xstuff[1],ystuff[1])), cheapsrgb).rgb);
|
||||
vec4 b = getLQV(vpow(texture(source[0],vec2(xstuff[2],ystuff[1])), cheapsrgb).rgb);
|
||||
vec4 c = getLQV(vpow(texture(source[0],vec2(xstuff[1],ystuff[2])), cheapsrgb).rgb);
|
||||
vec4 d = getLQV(vpow(texture(source[0],vec2(xstuff[2],ystuff[2])), cheapsrgb).rgb);
|
||||
|
||||
// use perceptual gamma for luminance component
|
||||
a.w = pow(a.w, 1/gamma);
|
||||
b.w = pow(b.w, 1/gamma);
|
||||
c.w = pow(c.w, 1/gamma);
|
||||
d.w = pow(d.w, 1/gamma);
|
||||
|
||||
// interpolate
|
||||
vec4 gammaLQVresult =
|
||||
NOT(xkeep)*NOT(ykeep)*a +
|
||||
YES(xkeep)*NOT(ykeep)*b +
|
||||
NOT(xkeep)*YES(ykeep)*c +
|
||||
YES(xkeep)*YES(ykeep)*d;
|
||||
|
||||
// change luminance gamma back to linear
|
||||
vec4 LQVresult = gammaLQVresult;
|
||||
LQVresult.w = pow(gammaLQVresult.w, gamma);
|
||||
|
||||
// convert back to srgb; lqv -> lrgb -> srgb
|
||||
vec4 c1 = vpow(vec4(fromLQV(LQVresult), 1), 1/cheapsrgb);
|
||||
|
||||
fragColor = c1;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
input
|
||||
filter: nearest
|
||||
|
||||
program
|
||||
fragment: AANN.fs
|
||||
|
||||
output
|
||||
filter: nearest
|
|
@ -1,297 +0,0 @@
|
|||
#version 150
|
||||
|
||||
/*
|
||||
CRT-interlaced
|
||||
|
||||
Copyright (C) 2010-2012 cgwg, Themaister and DOLLS
|
||||
|
||||
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.
|
||||
|
||||
(cgwg gave their consent to have the original version of this shader
|
||||
distributed under the GPL in this message:
|
||||
|
||||
http://board.byuu.org/viewtopic.php?p=26075#p26075
|
||||
|
||||
"Feel free to distribute my shaders under the GPL. After all, the
|
||||
barrel distortion code was taken from the Curvature shader, which is
|
||||
under the GPL."
|
||||
)
|
||||
This shader variant is pre-configured with screen curvature
|
||||
*/
|
||||
|
||||
//#define INTERLACED
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
uniform int phase;
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Comment the next line to disable interpolation in linear gamma (and gain speed).
|
||||
#define LINEAR_PROCESSING
|
||||
|
||||
// Enable screen curvature.
|
||||
#define CURVATURE
|
||||
|
||||
// Enable 3x oversampling of the beam profile
|
||||
#define OVERSAMPLE
|
||||
|
||||
// Use the older, purely gaussian beam profile
|
||||
//#define USEGAUSSIAN
|
||||
|
||||
// vertex params //
|
||||
|
||||
// gamma of simulated CRT
|
||||
#define CRTgamma 2.4
|
||||
// gamma of display monitor (typically 2.2 is correct)
|
||||
#define monitorgamma 2.2
|
||||
// overscan (e.g. 1.02 for 2% overscan)
|
||||
#define overscan vec2(1.0 , 1.0)//(0.93 , 0.915)
|
||||
// aspect ratio
|
||||
#define aspect vec2(1.0, 0.75)
|
||||
// lengths are measured in units of (approximately) the width of the monitor
|
||||
// simulated distance from viewer to monitor
|
||||
#define d 2.0
|
||||
// radius of curvature
|
||||
#define R 2.0
|
||||
// tilt angle in radians
|
||||
// (behavior might be a bit wrong if both components are nonzero)
|
||||
#define angle vec2(0.0,-0.0)
|
||||
// size of curved corners
|
||||
#define cornersize 0.02
|
||||
// border smoothness parameter
|
||||
// decrease if borders are too aliased
|
||||
#define cornersmooth 80.0
|
||||
|
||||
#define sinangle sin(angle)
|
||||
#define cosangle cos(angle)
|
||||
#define stretch maxscale()
|
||||
#define ilfac vec2(1.0, floor(sourceSize[0].y / 200.0))
|
||||
#define one (ilfac / sourceSize[0].xy)
|
||||
#define mod_factor (texCoord.x * targetSize.x)
|
||||
|
||||
// END of vertex params //
|
||||
|
||||
// Macros.
|
||||
#define FIX(c) max(abs(c), 1e-5);
|
||||
#define PI 3.141592653589
|
||||
|
||||
#ifdef LINEAR_PROCESSING
|
||||
# define TEX2D(c) pow(texture(source[0], (c)), vec4(CRTgamma))
|
||||
#else
|
||||
# define TEX2D(c) texture(source[0], (c))
|
||||
#endif
|
||||
|
||||
#define FIX(c) max(abs(c), 1e-5);
|
||||
|
||||
float intersect(vec2 xy)
|
||||
{
|
||||
float A = dot(xy,xy)+d*d;
|
||||
float B = 2.0*(R*(dot(xy,sinangle)-d*cosangle.x*cosangle.y)-d*d);
|
||||
float C = d*d + 2.0*R*d*cosangle.x*cosangle.y;
|
||||
return (-B-sqrt(B*B-4.0*A*C))/(2.0*A);
|
||||
}
|
||||
|
||||
vec2 bkwtrans(vec2 xy)
|
||||
{
|
||||
float c = intersect(xy);
|
||||
vec2 point = vec2(c)*xy;
|
||||
point -= vec2(-R)*sinangle;
|
||||
point /= vec2(R);
|
||||
vec2 tang = sinangle/cosangle;
|
||||
vec2 poc = point/cosangle;
|
||||
float A = dot(tang,tang)+1.0;
|
||||
float B = -2.0*dot(poc,tang);
|
||||
float C = dot(poc,poc)-1.0;
|
||||
float a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
|
||||
vec2 uv = (point-a*sinangle)/cosangle;
|
||||
float r = R*acos(a);
|
||||
return uv*r/sin(r/R);
|
||||
}
|
||||
|
||||
vec2 fwtrans(vec2 uv)
|
||||
{
|
||||
float r = FIX(sqrt(dot(uv,uv)));
|
||||
uv *= sin(r/R)/r;
|
||||
float x = 1.0-cos(r/R);
|
||||
float D = d/R + x*cosangle.x*cosangle.y+dot(uv,sinangle);
|
||||
return d*(uv*cosangle-x*sinangle)/D;
|
||||
}
|
||||
|
||||
vec3 maxscale()
|
||||
{
|
||||
vec2 c = bkwtrans(-R * sinangle / (1.0 + R/d*cosangle.x*cosangle.y));
|
||||
vec2 a = vec2(0.5,0.5)*aspect;
|
||||
vec2 lo = vec2(fwtrans(vec2(-a.x,c.y)).x,
|
||||
fwtrans(vec2(c.x,-a.y)).y)/aspect;
|
||||
vec2 hi = vec2(fwtrans(vec2(+a.x,c.y)).x,
|
||||
fwtrans(vec2(c.x,+a.y)).y)/aspect;
|
||||
return vec3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));
|
||||
}
|
||||
|
||||
vec2 transform(vec2 coord)
|
||||
{
|
||||
coord = (coord-vec2(0.5))*aspect*stretch.z+stretch.xy;
|
||||
return (bkwtrans(coord)/overscan/aspect+vec2(0.5));
|
||||
}
|
||||
|
||||
float corner(vec2 coord)
|
||||
{
|
||||
coord = (coord - vec2(0.5)) * overscan + vec2(0.5);
|
||||
coord = min(coord, vec2(1.0)-coord) * aspect;
|
||||
vec2 cdist = vec2(cornersize);
|
||||
coord = (cdist - min(coord,cdist));
|
||||
float dist = sqrt(dot(coord,coord));
|
||||
return clamp((cdist.x-dist)*cornersmooth,0.0, 1.0);
|
||||
}
|
||||
|
||||
// Calculate the influence of a scanline on the current pixel.
|
||||
//
|
||||
// 'distance' is the distance in texture coordinates from the current
|
||||
// pixel to the scanline in question.
|
||||
// 'color' is the colour of the scanline at the horizontal location of
|
||||
// the current pixel.
|
||||
vec4 scanlineWeights(float distance, vec4 color)
|
||||
{
|
||||
// "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.
|
||||
#ifdef USEGAUSSIAN
|
||||
vec4 wid = 0.3 + 0.1 * pow(color, vec4(3.0));
|
||||
vec4 weights = vec4(distance / wid);
|
||||
return 0.4 * exp(-weights * weights) / wid;
|
||||
#else
|
||||
vec4 wid = 2.0 + 2.0 * pow(color, vec4(4.0));
|
||||
vec4 weights = vec4(distance / 0.3);
|
||||
return 1.4 * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid);
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// Here's a helpful diagram to keep in mind while trying to
|
||||
// understand the code:
|
||||
//
|
||||
// | | | | |
|
||||
// -------------------------------
|
||||
// | | | | |
|
||||
// | 01 | 11 | 21 | 31 | <-- current scanline
|
||||
// | | @ | | |
|
||||
// -------------------------------
|
||||
// | | | | |
|
||||
// | 02 | 12 | 22 | 32 | <-- next scanline
|
||||
// | | | | |
|
||||
// -------------------------------
|
||||
// | | | | |
|
||||
//
|
||||
// Each character-cell represents a pixel on the output
|
||||
// surface, "@" represents the current pixel (always somewhere
|
||||
// in the bottom half of the current scan-line, or the top-half
|
||||
// of the next scanline). The grid of lines represents the
|
||||
// edges of the texels of the underlying texture.
|
||||
|
||||
// Texture coordinates of the texel containing the active pixel.
|
||||
#ifdef CURVATURE
|
||||
vec2 xy = transform(texCoord);
|
||||
#else
|
||||
vec2 xy = texCoord;
|
||||
#endif
|
||||
float cval = corner(xy);
|
||||
|
||||
// Of all the pixels that are mapped onto the texel we are
|
||||
// currently rendering, which pixel are we currently rendering?
|
||||
#ifdef INTERLACED
|
||||
vec2 ilvec = vec2(0.0,ilfac.y > 1.5 ? mod(float(phase),2.0) : 0.0);
|
||||
#else
|
||||
vec2 ilvec = vec2(0.0,ilfac.y);
|
||||
#endif
|
||||
vec2 ratio_scale = (xy * sourceSize[0].xy - vec2(0.5) + ilvec)/ilfac;
|
||||
#ifdef OVERSAMPLE
|
||||
float filter_ = sourceSize[0].y / targetSize.y;
|
||||
#endif
|
||||
vec2 uv_ratio = fract(ratio_scale);
|
||||
|
||||
// Snap to the center of the underlying texel.
|
||||
xy = (floor(ratio_scale)*ilfac + vec2(0.5) - ilvec) / sourceSize[0].xy;
|
||||
|
||||
// Calculate Lanczos scaling coefficients describing the effect
|
||||
// of various neighbour texels in a scanline on the current
|
||||
// pixel.
|
||||
vec4 coeffs = PI * vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
|
||||
|
||||
// Prevent division by zero.
|
||||
coeffs = FIX(coeffs);
|
||||
|
||||
// Lanczos2 kernel.
|
||||
coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
|
||||
|
||||
// Normalize.
|
||||
coeffs /= dot(coeffs, vec4(1.0));
|
||||
|
||||
// Calculate the effective colour of the current and next
|
||||
// scanlines at the horizontal location of the current pixel,
|
||||
// using the Lanczos coefficients above.
|
||||
vec4 col = clamp(mat4(
|
||||
TEX2D(xy + vec2(-one.x, 0.0)),
|
||||
TEX2D(xy),
|
||||
TEX2D(xy + vec2(one.x, 0.0)),
|
||||
TEX2D(xy + vec2(2.0 * one.x, 0.0))) * coeffs,
|
||||
0.0, 1.0);
|
||||
vec4 col2 = clamp(mat4(
|
||||
TEX2D(xy + vec2(-one.x, one.y)),
|
||||
TEX2D(xy + vec2(0.0, one.y)),
|
||||
TEX2D(xy + one),
|
||||
TEX2D(xy + vec2(2.0 * one.x, one.y))) * coeffs,
|
||||
0.0, 1.0);
|
||||
|
||||
#ifndef LINEAR_PROCESSING
|
||||
col = pow(col , vec4(CRTgamma));
|
||||
col2 = pow(col2, vec4(CRTgamma));
|
||||
#endif
|
||||
|
||||
// Calculate the influence of the current and next scanlines on
|
||||
// the current pixel.
|
||||
vec4 weights = scanlineWeights(uv_ratio.y, col);
|
||||
vec4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2);
|
||||
#ifdef OVERSAMPLE
|
||||
uv_ratio.y =uv_ratio.y+1.0/3.0*filter_;
|
||||
weights = (weights+scanlineWeights(uv_ratio.y, col))/3.0;
|
||||
weights2=(weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2))/3.0;
|
||||
uv_ratio.y =uv_ratio.y-2.0/3.0*filter_;
|
||||
weights=weights+scanlineWeights(abs(uv_ratio.y), col)/3.0;
|
||||
weights2=weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2)/3.0;
|
||||
#endif
|
||||
vec3 mul_res = (col * weights + col2 * weights2).rgb * vec3(cval);
|
||||
|
||||
// dot-mask emulation:
|
||||
// Output pixels are alternately tinted green and magenta.
|
||||
vec3 dotMaskWeights = mix(
|
||||
vec3(1.0, 0.7, 1.0),
|
||||
vec3(0.7, 1.0, 0.7),
|
||||
floor(mod(mod_factor, 2.0))
|
||||
);
|
||||
|
||||
mul_res *= dotMaskWeights;
|
||||
|
||||
// Convert the image gamma for display on our output device.
|
||||
mul_res = pow(mul_res, vec3(1.0 / monitorgamma));
|
||||
|
||||
// Color the texel.
|
||||
fragColor = vec4(mul_res, 1.0);
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
in vec4 sourceSize[];
|
||||
in vec4 targetSize;
|
||||
|
||||
out Vertex {
|
||||
vec2 texCoord;
|
||||
} vertexOut;
|
||||
|
||||
float CRTgamma;
|
||||
float monitorgamma;
|
||||
vec2 overscan;
|
||||
vec2 aspect;
|
||||
float d;
|
||||
float R;
|
||||
float cornersize;
|
||||
float cornersmooth;
|
||||
|
||||
vec3 stretch;
|
||||
vec2 sinangle;
|
||||
vec2 cosangle;
|
||||
|
||||
vec2 one;
|
||||
float mod_factor;
|
||||
vec2 ilfac;
|
||||
|
||||
#define FIX(c) max(abs(c), 1e-5);
|
||||
|
||||
float intersect(vec2 xy)
|
||||
{
|
||||
float A = dot(xy,xy)+d*d;
|
||||
float B = 2.0*(R*(dot(xy,sinangle)-d*cosangle.x*cosangle.y)-d*d);
|
||||
float C = d*d + 2.0*R*d*cosangle.x*cosangle.y;
|
||||
return (-B-sqrt(B*B-4.0*A*C))/(2.0*A);
|
||||
}
|
||||
|
||||
vec2 bkwtrans(vec2 xy)
|
||||
{
|
||||
float c = intersect(xy);
|
||||
vec2 point = vec2(c)*xy;
|
||||
point -= vec2(-R)*sinangle;
|
||||
point /= vec2(R);
|
||||
vec2 tang = sinangle/cosangle;
|
||||
vec2 poc = point/cosangle;
|
||||
float A = dot(tang,tang)+1.0;
|
||||
float B = -2.0*dot(poc,tang);
|
||||
float C = dot(poc,poc)-1.0;
|
||||
float a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
|
||||
vec2 uv = (point-a*sinangle)/cosangle;
|
||||
float r = R*acos(a);
|
||||
return uv*r/sin(r/R);
|
||||
}
|
||||
|
||||
vec2 fwtrans(vec2 uv)
|
||||
{
|
||||
float r = FIX(sqrt(dot(uv,uv)));
|
||||
uv *= sin(r/R)/r;
|
||||
float x = 1.0-cos(r/R);
|
||||
float D = d/R + x*cosangle.x*cosangle.y+dot(uv,sinangle);
|
||||
return d*(uv*cosangle-x*sinangle)/D;
|
||||
}
|
||||
|
||||
vec3 maxscale()
|
||||
{
|
||||
vec2 c = bkwtrans(-R * sinangle / (1.0 + R/d*cosangle.x*cosangle.y));
|
||||
vec2 a = vec2(0.5,0.5)*aspect;
|
||||
vec2 lo = vec2(fwtrans(vec2(-a.x,c.y)).x,
|
||||
fwtrans(vec2(c.x,-a.y)).y)/aspect;
|
||||
vec2 hi = vec2(fwtrans(vec2(+a.x,c.y)).x,
|
||||
fwtrans(vec2(c.x,+a.y)).y)/aspect;
|
||||
return vec3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// START of parameters
|
||||
|
||||
// gamma of simulated CRT
|
||||
CRTgamma = 2.4;
|
||||
// gamma of display monitor (typically 2.2 is correct)
|
||||
monitorgamma = 2.2;
|
||||
// overscan (e.g. 1.02 for 2% overscan)
|
||||
overscan = vec2(0.99,0.99);
|
||||
// aspect ratio
|
||||
aspect = vec2(1.0, 0.75);
|
||||
// lengths are measured in units of (approximately) the width of the monitor
|
||||
// simulated distance from viewer to monitor
|
||||
d = 2.0;
|
||||
// radius of curvature
|
||||
R = 2.0;
|
||||
// tilt angle in radians
|
||||
// (behavior might be a bit wrong if both components are nonzero)
|
||||
const vec2 angle = vec2(0.0,-0.0);
|
||||
// size of curved corners
|
||||
cornersize = 0.03;
|
||||
// border smoothness parameter
|
||||
// decrease if borders are too aliased
|
||||
cornersmooth = 80.0;
|
||||
|
||||
// END of parameters
|
||||
|
||||
vertexOut.texCoord = texCoord.xy;
|
||||
gl_Position = position;
|
||||
|
||||
// Precalculate a bunch of useful values we'll need in the fragment
|
||||
// shader.
|
||||
sinangle = sin(angle);
|
||||
cosangle = cos(angle);
|
||||
stretch = maxscale();
|
||||
|
||||
ilfac = vec2(1.0,floor(sourceSize[0].y/200.0));
|
||||
|
||||
// The size of one texel, in texture-coordinates.
|
||||
one = ilfac / sourceSize[0].xy;
|
||||
|
||||
// Resulting X pixel-coordinate of the pixel we're drawing.
|
||||
mod_factor = texCoord.x * targetSize.x;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
#version 150
|
||||
#define distortion 0.08
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
vec2 radialDistortion(vec2 coord) {
|
||||
vec2 cc = coord - vec2(0.5);
|
||||
float dist = dot(cc, cc) * distortion;
|
||||
return coord + cc * (1.0 - dist) * dist;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
fragColor = texture(source[0], radialDistortion(texCoord));
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
program
|
||||
vertex: crt-geom.vs
|
||||
fragment: crt-geom.fs
|
||||
modulo: 2
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
// Higher value, more centered glow.
|
||||
// Lower values might need more taps.
|
||||
#define GLOW_FALLOFF 0.35
|
||||
#define TAPS 4
|
||||
|
||||
#define kernel(x) exp(-GLOW_FALLOFF * (x) * (x))
|
||||
|
||||
void main() {
|
||||
vec3 col = vec3(0.0);
|
||||
float dx = 4.0 * sourceSize[0].z; // Mipmapped
|
||||
|
||||
float k_total = 0.0;
|
||||
for (int i = -TAPS; i <= TAPS; i++)
|
||||
{
|
||||
float k = kernel(i);
|
||||
k_total += k;
|
||||
col += k * texture(source[0], vTexCoord + vec2(float(i) * dx, 0.0)).rgb;
|
||||
}
|
||||
|
||||
FragColor = vec4(col / k_total, 1.0);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
uniform vec4 targetSize;
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
// Higher value, more centered glow.
|
||||
// Lower values might need more taps.
|
||||
#define GLOW_FALLOFF 0.35
|
||||
#define TAPS 4
|
||||
|
||||
#define kernel(x) exp(-GLOW_FALLOFF * (x) * (x))
|
||||
|
||||
void main() {
|
||||
vec3 col = vec3(0.0);
|
||||
float dy = sourceSize[0].w;
|
||||
|
||||
float k_total = 0.0;
|
||||
for (int i = -TAPS; i <= TAPS; i++)
|
||||
{
|
||||
float k = kernel(i);
|
||||
k_total += k;
|
||||
col += k * texture(source[0], vTexCoord + vec2(0.0, float(i) * dy)).rgb;
|
||||
}
|
||||
|
||||
FragColor = vec4(col / k_total, 1.0);
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#define INV_SQRT_2_PI 0.38 // Doesn't have to be accurate.
|
||||
|
||||
#define HORIZ_GAUSS_WIDTH 0.5
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
float data_pix_no;
|
||||
float data_one;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
float texel = floor(data_pix_no);
|
||||
float phase = data_pix_no - texel;
|
||||
float base_phase = phase - 0.5;
|
||||
vec2 tex = vec2((texel + 0.5) * sourceSize[0].z, vTexCoord.y);
|
||||
|
||||
vec3 col = vec3(0.0);
|
||||
for (int i = -2; i <= 2; i++)
|
||||
{
|
||||
float phase = base_phase - float(i);
|
||||
float g = INV_SQRT_2_PI * exp(-0.5 * phase * phase / (HORIZ_GAUSS_WIDTH * HORIZ_GAUSS_WIDTH)) / HORIZ_GAUSS_WIDTH;
|
||||
col += texture(source[0], tex + vec2(float(i) * data_one, 0.0)).rgb * g;
|
||||
}
|
||||
|
||||
FragColor = vec4(col, 1.0);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
float data_pix_no;
|
||||
float data_one;
|
||||
};
|
||||
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
|
||||
data_pix_no = vTexCoord.x * sourceSize[0].x;
|
||||
data_one = sourceSize[0].z;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#define BOOST 1.0
|
||||
#define CRT_GEOM_BEAM 1
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
vec2 data_pix_no;
|
||||
float data_one;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
vec3 beam(vec3 color, float dist)
|
||||
{
|
||||
#if CRT_GEOM_BEAM
|
||||
vec3 wid = 2.0 + 2.0 * pow(color, vec3(4.0));
|
||||
vec3 weights = vec3(abs(dist) * 3.333333333);
|
||||
|
||||
return 2.0 * color * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid);
|
||||
#else
|
||||
float reciprocal_width = 4.0;
|
||||
vec3 x = dist * reciprocal_width;
|
||||
|
||||
return 2.0 * color * exp(-0.5 * x * x) * reciprocal_width;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 texel = floor(data_pix_no);
|
||||
float phase = data_pix_no.y - texel.y;
|
||||
vec2 tex = vec2(texel + 0.5) * sourceSize[0].zw;
|
||||
|
||||
vec3 top = texture(source[0], tex + vec2(0.0, 0 * data_one)).rgb;
|
||||
vec3 bottom = texture(source[0], tex + vec2(0.0, 1 * data_one)).rgb;
|
||||
|
||||
float dist0 = phase;
|
||||
float dist1 = 1.0 - phase;
|
||||
|
||||
vec3 scanline = vec3(0.0);
|
||||
|
||||
scanline += beam(top, dist0);
|
||||
scanline += beam(bottom, dist1);
|
||||
|
||||
FragColor = vec4(BOOST * scanline * 0.869565217391304, 1.0);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
vec2 data_pix_no;
|
||||
float data_one;
|
||||
};
|
||||
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
|
||||
data_pix_no = vTexCoord.xy * sourceSize[0].xy - vec2(0.0, 0.5);
|
||||
data_one = sourceSize[0].w;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = texture(source[0], vTexCoord);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#define INPUT_GAMMA 2.2
|
||||
|
||||
uniform sampler2D source[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = pow(texture(source[0], vTexCoord), vec4(INPUT_GAMMA));
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
input
|
||||
filter: nearest
|
||||
|
||||
program
|
||||
format: srgb8
|
||||
filter: nearest
|
||||
vertex: linearize.vs
|
||||
fragment: linearize.fs
|
||||
|
||||
program
|
||||
format: srgb8
|
||||
filter: nearest
|
||||
height: 25%
|
||||
width: 100%
|
||||
vertex: gauss_horiz.vs
|
||||
fragment: gauss_horiz.fs
|
||||
|
||||
program
|
||||
format: srgb8
|
||||
filter: nearest
|
||||
vertex: gauss_vert.vs
|
||||
fragment: gauss_vert.fs
|
||||
|
||||
program
|
||||
format: srgb8
|
||||
filter: nearest
|
||||
height: 100%
|
||||
width: 100%
|
||||
vertex: threshold.vs
|
||||
fragment: threshold.fs
|
||||
|
||||
program
|
||||
format: srgb8
|
||||
filter: linear
|
||||
height: 25%
|
||||
width: 25%
|
||||
vertex: blur_horiz.vs
|
||||
fragment: blur_horiz.fs
|
||||
|
||||
program
|
||||
format: srgb8
|
||||
filter: linear
|
||||
height: 100%
|
||||
width: 100%
|
||||
vertex: blur_vert.vs
|
||||
fragment: blur_vert.fs
|
||||
|
||||
program
|
||||
filter: linear
|
||||
vertex: resolve.vs
|
||||
fragment: resolve.fs
|
||||
|
||||
output
|
||||
filter: linear
|
|
@ -1,28 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#define BLOOM_STRENGTH 0.25
|
||||
#define OUTPUT_GAMMA 2.2
|
||||
|
||||
uniform sampler2D source[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
// For debugging
|
||||
#define BLOOM_ONLY 0
|
||||
|
||||
#define CRT_PASS source[3]
|
||||
|
||||
void main() {
|
||||
#if BLOOM_ONLY
|
||||
vec3 source = BLOOM_STRENGTH * texture(source[0], vTexCoord).rgb;
|
||||
#else
|
||||
vec3 source_ = 1.15 * texture(CRT_PASS, vTexCoord).rgb;
|
||||
vec3 bloom = texture(source[0], vTexCoord).rgb;
|
||||
source_ += BLOOM_STRENGTH * bloom;
|
||||
#endif
|
||||
FragColor = vec4(pow(clamp(source_, 0.0, 1.0), vec3(1.0 / OUTPUT_GAMMA)), 1.0);
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#define GLOW_WHITEPOINT 1.0
|
||||
#define GLOW_ROLLOFF 3.0
|
||||
|
||||
uniform sampler2D source[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec3 color = 1.15 * texture(source[0], vTexCoord).rgb;
|
||||
vec3 factor = clamp(color / GLOW_WHITEPOINT, 0.0, 1.0);
|
||||
|
||||
FragColor = vec4(pow(factor, vec3(GLOW_ROLLOFF)), 1.0);
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,306 +0,0 @@
|
|||
#version 150
|
||||
|
||||
// PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER
|
||||
//
|
||||
// by Timothy Lottes
|
||||
//
|
||||
// This is more along the style of a really good CGA arcade monitor.
|
||||
// With RGB inputs instead of NTSC.
|
||||
// The shadow mask example has the mask rotated 90 degrees for less chromatic aberration.
|
||||
//
|
||||
// Left it unoptimized to show the theory behind the algorithm.
|
||||
//
|
||||
// It is an example what I personally would want as a display option for pixel art games.
|
||||
// Please take and use, change, or whatever.
|
||||
|
||||
#define hardScan -8.0
|
||||
#define hardPix -3.0
|
||||
#define warpX 0.031
|
||||
#define warpY 0.041
|
||||
#define maskDark 0.5
|
||||
#define maskLight 1.5
|
||||
#define scaleInLinearGamma 1.0
|
||||
#define shadowMask 3.0
|
||||
#define brightBoost 1.0
|
||||
#define hardBloomPix -1.5
|
||||
#define hardBloomScan -2.0
|
||||
#define bloomAmount 0.4
|
||||
#define shape 2.0
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
//Uncomment to reduce instructions with simpler linearization
|
||||
//(fixes HD3000 Sandy Bridge IGP)
|
||||
//#define SIMPLE_LINEAR_GAMMA
|
||||
#define DO_BLOOM 1
|
||||
|
||||
// ------------- //
|
||||
|
||||
// sRGB to Linear.
|
||||
// Assuming using sRGB typed textures this should not be needed.
|
||||
#ifdef SIMPLE_LINEAR_GAMMA
|
||||
float ToLinear1(float c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
vec3 ToLinear(vec3 c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
vec3 ToSrgb(vec3 c)
|
||||
{
|
||||
return pow(c, vec3(1.0 / 2.2));
|
||||
}
|
||||
#else
|
||||
float ToLinear1(float c)
|
||||
{
|
||||
if (scaleInLinearGamma == 0)
|
||||
return c;
|
||||
|
||||
return(c<=0.04045) ? c/12.92 : pow((c + 0.055)/1.055, 2.4);
|
||||
}
|
||||
|
||||
vec3 ToLinear(vec3 c)
|
||||
{
|
||||
if (scaleInLinearGamma==0)
|
||||
return c;
|
||||
|
||||
return vec3(ToLinear1(c.r), ToLinear1(c.g), ToLinear1(c.b));
|
||||
}
|
||||
|
||||
// Linear to sRGB.
|
||||
// Assuming using sRGB typed textures this should not be needed.
|
||||
float ToSrgb1(float c)
|
||||
{
|
||||
if (scaleInLinearGamma == 0)
|
||||
return c;
|
||||
|
||||
return(c<0.0031308 ? c*12.92 : 1.055*pow(c, 0.41666) - 0.055);
|
||||
}
|
||||
|
||||
vec3 ToSrgb(vec3 c)
|
||||
{
|
||||
if (scaleInLinearGamma == 0)
|
||||
return c;
|
||||
|
||||
return vec3(ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Nearest emulated sample given floating point position and texel offset.
|
||||
// Also zero's off screen.
|
||||
vec3 Fetch(vec2 pos,vec2 off){
|
||||
pos=(floor(pos*sourceSize[0].xy+off)+vec2(0.5,0.5))/sourceSize[0].xy;
|
||||
#ifdef SIMPLE_LINEAR_GAMMA
|
||||
return ToLinear(brightBoost * pow(texture(source[0],pos.xy).rgb, vec3(2.2)));
|
||||
#else
|
||||
return ToLinear(brightBoost * texture(source[0],pos.xy).rgb);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Distance in emulated pixels to nearest texel.
|
||||
vec2 Dist(vec2 pos)
|
||||
{
|
||||
pos = pos*sourceSize[0].xy;
|
||||
|
||||
return -((pos - floor(pos)) - vec2(0.5));
|
||||
}
|
||||
|
||||
// 1D Gaussian.
|
||||
float Gaus(float pos, float scale)
|
||||
{
|
||||
return exp2(scale*pow(abs(pos), shape));
|
||||
}
|
||||
|
||||
// 3-tap Gaussian filter along horz line.
|
||||
vec3 Horz3(vec2 pos, float off)
|
||||
{
|
||||
vec3 b = Fetch(pos, vec2(-1.0, off));
|
||||
vec3 c = Fetch(pos, vec2( 0.0, off));
|
||||
vec3 d = Fetch(pos, vec2( 1.0, off));
|
||||
float dst = Dist(pos).x;
|
||||
|
||||
// Convert distance to weight.
|
||||
float scale = hardPix;
|
||||
float wb = Gaus(dst-1.0,scale);
|
||||
float wc = Gaus(dst+0.0,scale);
|
||||
float wd = Gaus(dst+1.0,scale);
|
||||
|
||||
// Return filtered sample.
|
||||
return (b*wb+c*wc+d*wd)/(wb+wc+wd);
|
||||
}
|
||||
|
||||
// 5-tap Gaussian filter along horz line.
|
||||
vec3 Horz5(vec2 pos,float off){
|
||||
vec3 a = Fetch(pos,vec2(-2.0, off));
|
||||
vec3 b = Fetch(pos,vec2(-1.0, off));
|
||||
vec3 c = Fetch(pos,vec2( 0.0, off));
|
||||
vec3 d = Fetch(pos,vec2( 1.0, off));
|
||||
vec3 e = Fetch(pos,vec2( 2.0, off));
|
||||
|
||||
float dst = Dist(pos).x;
|
||||
// Convert distance to weight.
|
||||
float scale = hardPix;
|
||||
float wa = Gaus(dst - 2.0, scale);
|
||||
float wb = Gaus(dst - 1.0, scale);
|
||||
float wc = Gaus(dst + 0.0, scale);
|
||||
float wd = Gaus(dst + 1.0, scale);
|
||||
float we = Gaus(dst + 2.0, scale);
|
||||
|
||||
// Return filtered sample.
|
||||
return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);
|
||||
}
|
||||
|
||||
// 7-tap Gaussian filter along horz line.
|
||||
vec3 Horz7(vec2 pos,float off)
|
||||
{
|
||||
vec3 a = Fetch(pos, vec2(-3.0, off));
|
||||
vec3 b = Fetch(pos, vec2(-2.0, off));
|
||||
vec3 c = Fetch(pos, vec2(-1.0, off));
|
||||
vec3 d = Fetch(pos, vec2( 0.0, off));
|
||||
vec3 e = Fetch(pos, vec2( 1.0, off));
|
||||
vec3 f = Fetch(pos, vec2( 2.0, off));
|
||||
vec3 g = Fetch(pos, vec2( 3.0, off));
|
||||
|
||||
float dst = Dist(pos).x;
|
||||
// Convert distance to weight.
|
||||
float scale = hardBloomPix;
|
||||
float wa = Gaus(dst - 3.0, scale);
|
||||
float wb = Gaus(dst - 2.0, scale);
|
||||
float wc = Gaus(dst - 1.0, scale);
|
||||
float wd = Gaus(dst + 0.0, scale);
|
||||
float we = Gaus(dst + 1.0, scale);
|
||||
float wf = Gaus(dst + 2.0, scale);
|
||||
float wg = Gaus(dst + 3.0, scale);
|
||||
|
||||
// Return filtered sample.
|
||||
return (a*wa+b*wb+c*wc+d*wd+e*we+f*wf+g*wg)/(wa+wb+wc+wd+we+wf+wg);
|
||||
}
|
||||
|
||||
// Return scanline weight.
|
||||
float Scan(vec2 pos, float off)
|
||||
{
|
||||
float dst = Dist(pos).y;
|
||||
|
||||
return Gaus(dst + off, hardScan);
|
||||
}
|
||||
|
||||
// Return scanline weight for bloom.
|
||||
float BloomScan(vec2 pos, float off)
|
||||
{
|
||||
float dst = Dist(pos).y;
|
||||
|
||||
return Gaus(dst + off, hardBloomScan);
|
||||
}
|
||||
|
||||
// Allow nearest three lines to effect pixel.
|
||||
vec3 Tri(vec2 pos)
|
||||
{
|
||||
vec3 a = Horz3(pos,-1.0);
|
||||
vec3 b = Horz5(pos, 0.0);
|
||||
vec3 c = Horz3(pos, 1.0);
|
||||
|
||||
float wa = Scan(pos,-1.0);
|
||||
float wb = Scan(pos, 0.0);
|
||||
float wc = Scan(pos, 1.0);
|
||||
|
||||
return a*wa + b*wb + c*wc;
|
||||
}
|
||||
|
||||
// Small bloom.
|
||||
vec3 Bloom(vec2 pos)
|
||||
{
|
||||
vec3 a = Horz5(pos,-2.0);
|
||||
vec3 b = Horz7(pos,-1.0);
|
||||
vec3 c = Horz7(pos, 0.0);
|
||||
vec3 d = Horz7(pos, 1.0);
|
||||
vec3 e = Horz5(pos, 2.0);
|
||||
|
||||
float wa = BloomScan(pos,-2.0);
|
||||
float wb = BloomScan(pos,-1.0);
|
||||
float wc = BloomScan(pos, 0.0);
|
||||
float wd = BloomScan(pos, 1.0);
|
||||
float we = BloomScan(pos, 2.0);
|
||||
|
||||
return a*wa+b*wb+c*wc+d*wd+e*we;
|
||||
}
|
||||
|
||||
// Distortion of scanlines, and end of screen alpha.
|
||||
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;
|
||||
}
|
||||
|
||||
// Shadow mask.
|
||||
vec3 Mask(vec2 pos)
|
||||
{
|
||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
||||
|
||||
// Very compressed TV style shadow mask.
|
||||
if (shadowMask == 1.0)
|
||||
{
|
||||
float line = maskLight;
|
||||
float odd = 0.0;
|
||||
|
||||
if (fract(pos.x*0.166666666) < 0.5) odd = 1.0;
|
||||
if (fract((pos.y + odd) * 0.5) < 0.5) line = maskDark;
|
||||
|
||||
pos.x = fract(pos.x*0.333333333);
|
||||
|
||||
if (pos.x < 0.333) mask.r = maskLight;
|
||||
else if (pos.x < 0.666) mask.g = maskLight;
|
||||
else mask.b = maskLight;
|
||||
mask*=line;
|
||||
}
|
||||
|
||||
// Aperture-grille.
|
||||
else if (shadowMask == 2.0)
|
||||
{
|
||||
pos.x = fract(pos.x*0.333333333);
|
||||
|
||||
if (pos.x < 0.333) mask.r = maskLight;
|
||||
else if (pos.x < 0.666) mask.g = maskLight;
|
||||
else mask.b = maskLight;
|
||||
}
|
||||
|
||||
// Stretched VGA style shadow mask (same as prior shaders).
|
||||
else if (shadowMask == 3.0)
|
||||
{
|
||||
pos.x += pos.y*3.0;
|
||||
pos.x = fract(pos.x*0.166666666);
|
||||
|
||||
if (pos.x < 0.333) mask.r = maskLight;
|
||||
else if (pos.x < 0.666) mask.g = maskLight;
|
||||
else mask.b = maskLight;
|
||||
}
|
||||
|
||||
// VGA style shadow mask.
|
||||
else if (shadowMask == 4.0)
|
||||
{
|
||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
||||
pos.x += pos.y*3.0;
|
||||
pos.x = fract(pos.x*0.166666666);
|
||||
|
||||
if (pos.x < 0.333) mask.r = maskLight;
|
||||
else if (pos.x < 0.666) mask.g = maskLight;
|
||||
else mask.b = maskLight;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(Bloom(vTexCoord)*bloomAmount, 1.0);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
input
|
||||
filter: nearest
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
format: srgb8
|
||||
height: 100%
|
||||
width: 100%
|
||||
vertex: bloompass.vs
|
||||
fragment: bloompass.fs
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
vertex: scanpass.vs
|
||||
fragment: scanpass.fs
|
||||
|
||||
output
|
||||
filter: linear
|
|
@ -1,317 +0,0 @@
|
|||
#version 150
|
||||
|
||||
// PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER
|
||||
//
|
||||
// by Timothy Lottes
|
||||
//
|
||||
// This is more along the style of a really good CGA arcade monitor.
|
||||
// With RGB inputs instead of NTSC.
|
||||
// The shadow mask example has the mask rotated 90 degrees for less chromatic aberration.
|
||||
//
|
||||
// Left it unoptimized to show the theory behind the algorithm.
|
||||
//
|
||||
// It is an example what I personally would want as a display option for pixel art games.
|
||||
// Please take and use, change, or whatever.
|
||||
|
||||
#define hardScan -8.0
|
||||
#define hardPix -3.0
|
||||
#define warpX 0.031
|
||||
#define warpY 0.041
|
||||
#define maskDark 0.5
|
||||
#define maskLight 1.5
|
||||
#define scaleInLinearGamma 1.0
|
||||
#define shadowMask 3.0
|
||||
#define brightBoost 1.0
|
||||
#define hardBloomPix -1.5
|
||||
#define hardBloomScan -2.0
|
||||
#define bloomAmount 0.4
|
||||
#define shape 2.0
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 outputSize;
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
//Uncomment to reduce instructions with simpler linearization
|
||||
//(fixes HD3000 Sandy Bridge IGP)
|
||||
//#define SIMPLE_LINEAR_GAMMA
|
||||
#define DO_BLOOM 1
|
||||
|
||||
// ------------- //
|
||||
|
||||
// sRGB to Linear.
|
||||
// Assuming using sRGB typed textures this should not be needed.
|
||||
#ifdef SIMPLE_LINEAR_GAMMA
|
||||
float ToLinear1(float c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
vec3 ToLinear(vec3 c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
vec3 ToSrgb(vec3 c)
|
||||
{
|
||||
return pow(c, vec3(1.0 / 2.2));
|
||||
}
|
||||
#else
|
||||
float ToLinear1(float c)
|
||||
{
|
||||
if (scaleInLinearGamma == 0)
|
||||
return c;
|
||||
|
||||
return(c<=0.04045) ? c/12.92 : pow((c + 0.055)/1.055, 2.4);
|
||||
}
|
||||
|
||||
vec3 ToLinear(vec3 c)
|
||||
{
|
||||
if (scaleInLinearGamma==0)
|
||||
return c;
|
||||
|
||||
return vec3(ToLinear1(c.r), ToLinear1(c.g), ToLinear1(c.b));
|
||||
}
|
||||
|
||||
// Linear to sRGB.
|
||||
// Assuming using sRGB typed textures this should not be needed.
|
||||
float ToSrgb1(float c)
|
||||
{
|
||||
if (scaleInLinearGamma == 0)
|
||||
return c;
|
||||
|
||||
return(c<0.0031308 ? c*12.92 : 1.055*pow(c, 0.41666) - 0.055);
|
||||
}
|
||||
|
||||
vec3 ToSrgb(vec3 c)
|
||||
{
|
||||
if (scaleInLinearGamma == 0)
|
||||
return c;
|
||||
|
||||
return vec3(ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Nearest emulated sample given floating point position and texel offset.
|
||||
// Also zero's off screen.
|
||||
vec3 Fetch(vec2 pos,vec2 off){
|
||||
pos=(floor(pos*sourceSize[0].xy+off)+vec2(0.5,0.5))/sourceSize[0].xy;
|
||||
#ifdef SIMPLE_LINEAR_GAMMA
|
||||
return ToLinear(brightBoost * pow(texture(source[1],pos.xy).rgb, vec3(2.2)));
|
||||
#else
|
||||
return ToLinear(brightBoost * texture(source[1],pos.xy).rgb);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Distance in emulated pixels to nearest texel.
|
||||
vec2 Dist(vec2 pos)
|
||||
{
|
||||
pos = pos*sourceSize[0].xy;
|
||||
|
||||
return -((pos - floor(pos)) - vec2(0.5));
|
||||
}
|
||||
|
||||
// 1D Gaussian.
|
||||
float Gaus(float pos, float scale)
|
||||
{
|
||||
return exp2(scale*pow(abs(pos), shape));
|
||||
}
|
||||
|
||||
// 3-tap Gaussian filter along horz line.
|
||||
vec3 Horz3(vec2 pos, float off)
|
||||
{
|
||||
vec3 b = Fetch(pos, vec2(-1.0, off));
|
||||
vec3 c = Fetch(pos, vec2( 0.0, off));
|
||||
vec3 d = Fetch(pos, vec2( 1.0, off));
|
||||
float dst = Dist(pos).x;
|
||||
|
||||
// Convert distance to weight.
|
||||
float scale = hardPix;
|
||||
float wb = Gaus(dst-1.0,scale);
|
||||
float wc = Gaus(dst+0.0,scale);
|
||||
float wd = Gaus(dst+1.0,scale);
|
||||
|
||||
// Return filtered sample.
|
||||
return (b*wb+c*wc+d*wd)/(wb+wc+wd);
|
||||
}
|
||||
|
||||
// 5-tap Gaussian filter along horz line.
|
||||
vec3 Horz5(vec2 pos,float off){
|
||||
vec3 a = Fetch(pos,vec2(-2.0, off));
|
||||
vec3 b = Fetch(pos,vec2(-1.0, off));
|
||||
vec3 c = Fetch(pos,vec2( 0.0, off));
|
||||
vec3 d = Fetch(pos,vec2( 1.0, off));
|
||||
vec3 e = Fetch(pos,vec2( 2.0, off));
|
||||
|
||||
float dst = Dist(pos).x;
|
||||
// Convert distance to weight.
|
||||
float scale = hardPix;
|
||||
float wa = Gaus(dst - 2.0, scale);
|
||||
float wb = Gaus(dst - 1.0, scale);
|
||||
float wc = Gaus(dst + 0.0, scale);
|
||||
float wd = Gaus(dst + 1.0, scale);
|
||||
float we = Gaus(dst + 2.0, scale);
|
||||
|
||||
// Return filtered sample.
|
||||
return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);
|
||||
}
|
||||
|
||||
// 7-tap Gaussian filter along horz line.
|
||||
vec3 Horz7(vec2 pos,float off)
|
||||
{
|
||||
vec3 a = Fetch(pos, vec2(-3.0, off));
|
||||
vec3 b = Fetch(pos, vec2(-2.0, off));
|
||||
vec3 c = Fetch(pos, vec2(-1.0, off));
|
||||
vec3 d = Fetch(pos, vec2( 0.0, off));
|
||||
vec3 e = Fetch(pos, vec2( 1.0, off));
|
||||
vec3 f = Fetch(pos, vec2( 2.0, off));
|
||||
vec3 g = Fetch(pos, vec2( 3.0, off));
|
||||
|
||||
float dst = Dist(pos).x;
|
||||
// Convert distance to weight.
|
||||
float scale = hardBloomPix;
|
||||
float wa = Gaus(dst - 3.0, scale);
|
||||
float wb = Gaus(dst - 2.0, scale);
|
||||
float wc = Gaus(dst - 1.0, scale);
|
||||
float wd = Gaus(dst + 0.0, scale);
|
||||
float we = Gaus(dst + 1.0, scale);
|
||||
float wf = Gaus(dst + 2.0, scale);
|
||||
float wg = Gaus(dst + 3.0, scale);
|
||||
|
||||
// Return filtered sample.
|
||||
return (a*wa+b*wb+c*wc+d*wd+e*we+f*wf+g*wg)/(wa+wb+wc+wd+we+wf+wg);
|
||||
}
|
||||
|
||||
// Return scanline weight.
|
||||
float Scan(vec2 pos, float off)
|
||||
{
|
||||
float dst = Dist(pos).y;
|
||||
|
||||
return Gaus(dst + off, hardScan);
|
||||
}
|
||||
|
||||
// Return scanline weight for bloom.
|
||||
float BloomScan(vec2 pos, float off)
|
||||
{
|
||||
float dst = Dist(pos).y;
|
||||
|
||||
return Gaus(dst + off, hardBloomScan);
|
||||
}
|
||||
|
||||
// Allow nearest three lines to effect pixel.
|
||||
vec3 Tri(vec2 pos)
|
||||
{
|
||||
vec3 a = Horz3(pos,-1.0);
|
||||
vec3 b = Horz5(pos, 0.0);
|
||||
vec3 c = Horz3(pos, 1.0);
|
||||
|
||||
float wa = Scan(pos,-1.0);
|
||||
float wb = Scan(pos, 0.0);
|
||||
float wc = Scan(pos, 1.0);
|
||||
|
||||
return a*wa + b*wb + c*wc;
|
||||
}
|
||||
|
||||
// Small bloom.
|
||||
vec3 Bloom(vec2 pos)
|
||||
{
|
||||
vec3 a = Horz5(pos,-2.0);
|
||||
vec3 b = Horz7(pos,-1.0);
|
||||
vec3 c = Horz7(pos, 0.0);
|
||||
vec3 d = Horz7(pos, 1.0);
|
||||
vec3 e = Horz5(pos, 2.0);
|
||||
|
||||
float wa = BloomScan(pos,-2.0);
|
||||
float wb = BloomScan(pos,-1.0);
|
||||
float wc = BloomScan(pos, 0.0);
|
||||
float wd = BloomScan(pos, 1.0);
|
||||
float we = BloomScan(pos, 2.0);
|
||||
|
||||
return a*wa+b*wb+c*wc+d*wd+e*we;
|
||||
}
|
||||
|
||||
// Distortion of scanlines, and end of screen alpha.
|
||||
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;
|
||||
}
|
||||
|
||||
// Shadow mask.
|
||||
vec3 Mask(vec2 pos)
|
||||
{
|
||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
||||
|
||||
// Very compressed TV style shadow mask.
|
||||
if (shadowMask == 1.0)
|
||||
{
|
||||
float line = maskLight;
|
||||
float odd = 0.0;
|
||||
|
||||
if (fract(pos.x*0.166666666) < 0.5) odd = 1.0;
|
||||
if (fract((pos.y + odd) * 0.5) < 0.5) line = maskDark;
|
||||
|
||||
pos.x = fract(pos.x*0.333333333);
|
||||
|
||||
if (pos.x < 0.333) mask.r = maskLight;
|
||||
else if (pos.x < 0.666) mask.g = maskLight;
|
||||
else mask.b = maskLight;
|
||||
mask*=line;
|
||||
}
|
||||
|
||||
// Aperture-grille.
|
||||
else if (shadowMask == 2.0)
|
||||
{
|
||||
pos.x = fract(pos.x*0.333333333);
|
||||
|
||||
if (pos.x < 0.333) mask.r = maskLight;
|
||||
else if (pos.x < 0.666) mask.g = maskLight;
|
||||
else mask.b = maskLight;
|
||||
}
|
||||
|
||||
// Stretched VGA style shadow mask (same as prior shaders).
|
||||
else if (shadowMask == 3.0)
|
||||
{
|
||||
pos.x += pos.y*3.0;
|
||||
pos.x = fract(pos.x*0.166666666);
|
||||
|
||||
if (pos.x < 0.333) mask.r = maskLight;
|
||||
else if (pos.x < 0.666) mask.g = maskLight;
|
||||
else mask.b = maskLight;
|
||||
}
|
||||
|
||||
// VGA style shadow mask.
|
||||
else if (shadowMask == 4.0)
|
||||
{
|
||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
||||
pos.x += pos.y*3.0;
|
||||
pos.x = fract(pos.x*0.166666666);
|
||||
|
||||
if (pos.x < 0.333) mask.r = maskLight;
|
||||
else if (pos.x < 0.666) mask.g = maskLight;
|
||||
else mask.b = maskLight;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 pos = Warp(vTexCoord);
|
||||
vec3 outColor = Tri(pos).rgb;
|
||||
|
||||
if (shadowMask > 0.0)
|
||||
outColor.rgb *= Mask(vTexCoord.xy * outputSize.xy * 1.000001);
|
||||
#ifdef DO_BLOOM
|
||||
//Add Bloom
|
||||
outColor.rgb += mix( vec3(0.0), texture(source[0], pos).rgb, bloomAmount);
|
||||
#endif
|
||||
|
||||
FragColor = vec4(ToSrgb(outColor.rgb), 1.0);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
input
|
||||
filter: nearest
|
||||
|
||||
// IMPORTANT:
|
||||
// Shader passes need to know details about the image in the mask_texture LUT
|
||||
// files, so set the following constants in user-preset-constants.h accordingly:
|
||||
// 1.) mask_triads_per_tile = (number of horizontal triads in mask texture LUT's)
|
||||
// 2.) mask_texture_small_size = (texture size of mask*texture_small LUT's)
|
||||
// 3.) mask_texture_large_size = (texture size of mask*texture_large LUT's)
|
||||
// 4.) mask_grille_avg_color = (avg. brightness of mask_grille_texture* LUT's, in [0, 1])
|
||||
// 5.) mask_slot_avg_color = (avg. brightness of mask_slot_texture* LUT's, in [0, 1])
|
||||
// 6.) mask_shadow_avg_color = (avg. brightness of mask_shadow_texture* LUT's, in [0, 1])
|
||||
// Shader passes also need to know certain scales set in this preset, but their
|
||||
// compilation model doesn't currently allow the preset file to tell them. Make
|
||||
// sure to set the following constants in user-preset-constants.h accordingly too:
|
||||
// 1.) bloom_approx_scale_x = scale_x2
|
||||
// 2.) mask_resize_viewport_scale = vec2(scale_x6, scale_y5)
|
||||
// Finally, shader passes need to know the value of geom_max_aspect_ratio used to
|
||||
// calculate scale_y5 (among other values):
|
||||
// 1.) geom_max_aspect_ratio = (geom_max_aspect_ratio used to calculate scale_y5)
|
||||
|
||||
// Pass0: Linearize the input based on CRT gamma and bob interlaced fields.
|
||||
// (Bobbing ensures we can immediately blur without getting artifacts.)
|
||||
program
|
||||
filter: nearest
|
||||
vertex: first-pass-linearize-crt-gamma-bob-fields.vs
|
||||
fragment: first-pass-linearize-crt-gamma-bob-fields.fs
|
||||
format: rgba16f
|
||||
height: 100%
|
||||
width: 100%
|
||||
|
||||
// Pass1: Resample interlaced (and misconverged) scanlines vertically.
|
||||
// Separating vertical/horizontal scanline sampling is faster: It lets us
|
||||
// consider more scanlines while calculating weights for fewer pixels, and
|
||||
// it reduces our samples from vertical*horizontal to vertical+horizontal.
|
||||
// This has to come right after ORIG_LINEARIZED, because there's no
|
||||
// "original_source" scale_type we can use later.
|
||||
program
|
||||
filter: linear
|
||||
vertex: scanlines-vertical-interlacing.vs
|
||||
fragment: scanlines-vertical-interlacing.fs
|
||||
height: 400%
|
||||
width: 100%
|
||||
format: rgba16f
|
||||
|
||||
// Pass2: Do a small resize blur of ORIG_LINEARIZED at an absolute size, and
|
||||
// account for convergence offsets. We want to blur a predictable portion of the
|
||||
// screen to match the phosphor bloom, and absolute scale works best for
|
||||
// reliable results with a fixed-size bloom. Picking a scale is tricky:
|
||||
// a.) 400x300 is a good compromise for the "fake-bloom" version: It's low enough
|
||||
// to blur high-res/interlaced sources but high enough that resampling
|
||||
// doesn't smear low-res sources too much.
|
||||
// b.) 320x240 works well for the "real bloom" version: It's 1-1.5% faster, and
|
||||
// the only noticeable visual difference is a larger halation spread (which
|
||||
// may be a good thing for people who like to crank it up).
|
||||
// Note the 4:3 aspect ratio assumes the input has cropped geom_overscan (so it's
|
||||
// *intended* for an ~4:3 aspect ratio).
|
||||
program
|
||||
filter: linear
|
||||
vertex: bloom-approx.vs
|
||||
fragment: bloom-approx.fs
|
||||
format: rgba16f
|
||||
width: 320 px
|
||||
height: 240 px
|
||||
|
||||
// Pass3: Vertically blur the input for halation and refractive diffusion.
|
||||
// Base this on BLOOM_APPROX: This blur should be small and fast, and blurring
|
||||
// a constant portion of the screen is probably physically correct if the
|
||||
// viewport resolution is proportional to the simulated CRT size.
|
||||
program
|
||||
filter: linear
|
||||
vertex: blur9fast-vertical.vs
|
||||
fragment: blur9fast-vertical.fs
|
||||
format: rgba16f
|
||||
height: 100%
|
||||
width: 100%
|
||||
|
||||
// Pass4: Horizontally blur the input for halation and refractive diffusion.
|
||||
// Note: Using a one-pass 9x9 blur is about 1% slower.
|
||||
program
|
||||
filter: linear
|
||||
vertex: blur9fast-horizontal.vs
|
||||
fragment: blur9fast-horizontal.fs
|
||||
format: rgba16f
|
||||
height: 100%
|
||||
width: 100%
|
||||
|
||||
// Pass5: Lanczos-resize the phosphor mask vertically. Set the absolute
|
||||
// scale_x5 == mask_texture_small_size.x (see IMPORTANT above). Larger scales
|
||||
// will blur, and smaller scales could get nasty. The vertical size must be
|
||||
// based on the viewport size and calculated carefully to avoid artifacts later.
|
||||
// First calculate the minimum number of mask tiles we need to draw.
|
||||
// Since curvature is computed after the scanline masking pass:
|
||||
// num_resized_mask_tiles = 2.0;
|
||||
// If curvature were computed in the scanline masking pass (it's not):
|
||||
// max_mask_texel_border = ~3.0 * (1/3.0 + 4.0*sqrt(2.0) + 0.5 + 1.0);
|
||||
// max_mask_tile_border = max_mask_texel_border/
|
||||
// (min_resized_phosphor_triad_size * mask_triads_per_tile);
|
||||
// num_resized_mask_tiles = max(2.0, 1.0 + max_mask_tile_border * 2.0);
|
||||
// At typical values (triad_size >= 2.0, mask_triads_per_tile == 8):
|
||||
// num_resized_mask_tiles = ~3.8
|
||||
// Triad sizes are given in horizontal terms, so we need geom_max_aspect_ratio
|
||||
// to relate them to vertical resolution. The widest we expect is:
|
||||
// geom_max_aspect_ratio = 4.0/3.0 // Note: Shader passes need to know this!
|
||||
// The fewer triads we tile across the screen, the larger each triad will be as a
|
||||
// fraction of the viewport size, and the larger scale_y5 must be to draw a full
|
||||
// num_resized_mask_tiles. Therefore, we must decide the smallest number of
|
||||
// triads we'll guarantee can be displayed on screen. We'll set this according
|
||||
// to 3-pixel triads at 768p resolution (the lowest anyone's likely to use):
|
||||
// min_allowed_viewport_triads = 768.0*geom_max_aspect_ratio / 3.0 = 341.333333
|
||||
// Now calculate the viewport scale that ensures we can draw resized_mask_tiles:
|
||||
// min_scale_x = resized_mask_tiles * mask_triads_per_tile /
|
||||
// min_allowed_viewport_triads
|
||||
// scale_y5 = geom_max_aspect_ratio * min_scale_x
|
||||
// # Some code might depend on equal scales:
|
||||
// scale_x6 = scale_y5
|
||||
// Given our default geom_max_aspect_ratio and min_allowed_viewport_triads:
|
||||
// scale_y5 = 4.0/3.0 * 2.0/(341.33333 / 8.0) = 0.0625
|
||||
// IMPORTANT: The scales MUST be calculated in this way. If you wish to change
|
||||
// geom_max_aspect_ratio, update that constant in user-preset-constants.h!
|
||||
program
|
||||
filter: linear
|
||||
format: rgba16f
|
||||
width: 64 px
|
||||
height: 6.25%
|
||||
vertex: mask-resize-vertical.vs
|
||||
fragment: mask-resize-vertical.fs
|
||||
pixmap: textures/TileableLinearApertureGrille15Wide8And5d5SpacingResizeTo64.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearApertureGrille15Wide8And5d5Spacing.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacingResizeTo64.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacing.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearShadowMaskEDPResizeTo64.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearShadowMaskEDP.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
|
||||
// Pass6: Lanczos-resize the phosphor mask horizontally. scale_x6 = scale_y5.
|
||||
// TODO: Check again if the shaders actually require equal scales.
|
||||
program
|
||||
filter: nearest
|
||||
vertex: mask-resize-horizontal.vs
|
||||
fragment: mask-resize-horizontal.fs
|
||||
format: rgba16f
|
||||
|
||||
// Pass7: Resample (misconverged) scanlines horizontally, apply halation, and
|
||||
// apply the phosphor mask.
|
||||
program
|
||||
filter: linear
|
||||
format: rgba16f
|
||||
height: 100%
|
||||
width: 100%
|
||||
vertex: scanlines-horizontal-apply-mask.vs
|
||||
fragment: scanlines-horizontal-apply-mask.fs
|
||||
pixmap: textures/TileableLinearApertureGrille15Wide8And5d5SpacingResizeTo64.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearApertureGrille15Wide8And5d5Spacing.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacingResizeTo64.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearSlotMaskTall15Wide9And4d5Horizontal9d14VerticalSpacing.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearShadowMaskEDPResizeTo64.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
pixmap: textures/TileableLinearShadowMaskEDP.png
|
||||
filter: linear
|
||||
wrap: repeat
|
||||
|
||||
// Pass 8: Compute a brightpass. This will require reading the final mask.
|
||||
program
|
||||
filter: linear
|
||||
format: rgba16f
|
||||
vertex: brightpass.vs
|
||||
fragment: brightpass.fs
|
||||
|
||||
// Pass 9: Blur the brightpass vertically
|
||||
program
|
||||
filter: linear
|
||||
format: rgba16f
|
||||
vertex: bloom-vertical.vs
|
||||
fragment: bloom-vertical.fs
|
||||
|
||||
// Pass 10: Blur the brightpass horizontally and combine it with the dimpass:
|
||||
program
|
||||
filter: linear
|
||||
format: rgba16f
|
||||
height: 100%
|
||||
width: 100%
|
||||
vertex: bloom-horizontal-reconstitute.vs
|
||||
fragment: bloom-horizontal-reconstitute.fs
|
||||
|
||||
// Pass 11: Compute curvature/AA:
|
||||
program
|
||||
filter: linear
|
||||
format: rgba16f
|
||||
vertex: geometry-aa-last-pass.vs
|
||||
fragment: geometry-aa-last-pass.fs
|
||||
|
||||
output
|
||||
filter: nearest
|
Before Width: | Height: | Size: 194 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 214 KiB |
Before Width: | Height: | Size: 202 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 200 KiB |
Before Width: | Height: | Size: 6.8 KiB |
|
@ -1,52 +0,0 @@
|
|||
#version 150
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// GTU version 0.40
|
||||
// Author: aliaspider - aliaspider@gmail.com
|
||||
// License: GPLv3
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// SETTINGS
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
//#define CROP_OVERSCAN
|
||||
#define TV_COLOR_LEVELS
|
||||
//#define COMPOSITE_CONNECTION
|
||||
//#define NO_SCANLINES
|
||||
#define TV_HORIZONTAL_RESOLUTION 400.0
|
||||
#define TV_VERTICAL_RESOLUTION 300.0
|
||||
#define SIGNAL_RESOLUTION 280.0
|
||||
#define SIGNAL_RESOLUTION_I 83.0
|
||||
#define SIGNAL_RESOLUTION_Q 25.0
|
||||
#define TV_DISPLAY_GAMMA 2.4
|
||||
#define OUTPUT_DISPLAY_GAMMA 2.2
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#define RGB_to_YIQ mat3x3( 0.299 , 0.595716 , 0.211456 , 0.587 , -0.274453 , -0.522591 , 0.114 , -0.321263 , 0.311135 )
|
||||
#define YIQ_to_RGB mat3x3( 1.0 , 1.0 , 1.0 , 0.9563 , -0.2721 , -1.1070 , 0.6210 , -0.6474 , 1.7046 )
|
||||
#define LEVELS(C) clamp((C -16/ 255.0)*255.0/(235.0-16.0),0.0,1.0)
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
out vec4 fragColor;
|
||||
|
||||
|
||||
void main() {
|
||||
vec3 c=texture2D(source[0], texCoord.xy).xyz;
|
||||
#ifdef TV_COLOR_LEVELS
|
||||
c=LEVELS(c);
|
||||
#endif
|
||||
#ifdef COMPOSITE_CONNECTION
|
||||
c=RGB_to_YIQ*c;
|
||||
#endif
|
||||
fragColor = vec4(c, 1.0);
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
#version 150
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// GTU version 0.40
|
||||
// Author: aliaspider - aliaspider@gmail.com
|
||||
// License: GPLv3
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// SETTINGS
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
//#define CROP_OVERSCAN
|
||||
#define TV_COLOR_LEVELS
|
||||
//#define COMPOSITE_CONNECTION
|
||||
//#define NO_SCANLINES
|
||||
#define TV_HORIZONTAL_RESOLUTION 400.0
|
||||
#define TV_VERTICAL_RESOLUTION 300.0
|
||||
#define SIGNAL_RESOLUTION 280.0
|
||||
#define SIGNAL_RESOLUTION_I 83.0
|
||||
#define SIGNAL_RESOLUTION_Q 25.0
|
||||
#define TV_DISPLAY_GAMMA 2.4
|
||||
#define OUTPUT_DISPLAY_GAMMA 2.2
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#define YIQ_to_RGB mat3x3( 1.0 , 1.0 , 1.0 , 0.9563 , -0.2721 , -1.1070 , 0.6210 , -0.6474 , 1.7046 )
|
||||
|
||||
|
||||
|
||||
|
||||
#define pi 3.14159265358
|
||||
#define a(x) abs(x)
|
||||
#define d(x,b) (pi*b*min(a(x)+0.5,1.0/b))
|
||||
#define e(x,b) (pi*b*min(max(a(x)-0.5,-1.0/b),1.0/b))
|
||||
#define STU(x,b) ((d(x,b)+sin(d(x,b))-e(x,b)-sin(e(x,b)))/(2.0*pi))
|
||||
#define X(i) (offset-(i))
|
||||
|
||||
#define GETC (texture(source[0], vec2(texCoord.x - X*sourceSize[0].z,texCoord.y)).xyz)
|
||||
|
||||
#ifdef COMPOSITE_CONNECTION
|
||||
#define VAL vec3((c.x*STU(X,(SIGNAL_RESOLUTION*sourceSize[0].z))),(c.y*STU(X,(SIGNAL_RESOLUTION_I*sourceSize[0].z))),(c.z*STU(X,(SIGNAL_RESOLUTION_Q*sourceSize[0].z))))
|
||||
#else
|
||||
#define VAL (c*STU(X,(SIGNAL_RESOLUTION*sourceSize[0].z)))
|
||||
#endif //COMPOSITE_CONNECTION
|
||||
|
||||
#define PROCESS(i) X=X(i);c=GETC;tempColor+=VAL;
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
out vec4 fragColor;
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
float offset = fract((texCoord.x * sourceSize[0].x) - 0.5);
|
||||
vec3 tempColor = vec3(0.0);
|
||||
float X;
|
||||
vec3 c;
|
||||
PROCESS(-6)PROCESS(-5)PROCESS(-4)PROCESS(-3)PROCESS(-2)PROCESS(-1)PROCESS( 0)
|
||||
PROCESS( 7)PROCESS( 6)PROCESS( 5)PROCESS( 4)PROCESS( 3)PROCESS( 2)PROCESS( 1)
|
||||
|
||||
|
||||
#ifdef COMPOSITE_CONNECTION
|
||||
tempColor=clamp(YIQ_to_RGB*tempColor,0.0,1.0);
|
||||
#endif
|
||||
tempColor=clamp(pow(tempColor,vec3(TV_DISPLAY_GAMMA)),0.0,1.0);
|
||||
fragColor = vec4(tempColor,1.0);
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
#version 150
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// GTU version 0.40
|
||||
// Author: aliaspider - aliaspider@gmail.com
|
||||
// License: GPLv3
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// SETTINGS
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
//#define CROP_OVERSCAN
|
||||
#define TV_COLOR_LEVELS
|
||||
//#define COMPOSITE_CONNECTION
|
||||
//#define NO_SCANLINES
|
||||
#define TV_HORIZONTAL_RESOLUTION 400.0
|
||||
#define TV_VERTICAL_RESOLUTION 300.0
|
||||
#define SIGNAL_RESOLUTION 280.0
|
||||
#define SIGNAL_RESOLUTION_I 83.0
|
||||
#define SIGNAL_RESOLUTION_Q 25.0
|
||||
#define TV_DISPLAY_GAMMA 2.4
|
||||
#define OUTPUT_DISPLAY_GAMMA 2.2
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex{
|
||||
vec2 texCoord;
|
||||
}vertexOut;
|
||||
|
||||
void main(void){
|
||||
|
||||
#ifdef CROP_OVERSCAN
|
||||
gl_Position=position;
|
||||
gl_Position.x/=(224.0/240.0);
|
||||
#else
|
||||
gl_Position=position;
|
||||
#endif
|
||||
|
||||
vertexOut.texCoord=texCoord;
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
#version 150
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// GTU version 0.40
|
||||
// Author: aliaspider - aliaspider@gmail.com
|
||||
// License: GPLv3
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// SETTINGS
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
//#define CROP_OVERSCAN
|
||||
#define TV_COLOR_LEVELS
|
||||
//#define COMPOSITE_CONNECTION
|
||||
//#define NO_SCANLINES
|
||||
#define TV_HORIZONTAL_RESOLUTION 400.0
|
||||
#define TV_VERTICAL_RESOLUTION 300.0
|
||||
#define SIGNAL_RESOLUTION 280.0
|
||||
#define SIGNAL_RESOLUTION_I 83.0
|
||||
#define SIGNAL_RESOLUTION_Q 25.0
|
||||
#define TV_DISPLAY_GAMMA 2.4
|
||||
#define OUTPUT_DISPLAY_GAMMA 2.2
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#define pi 3.14159265358
|
||||
#define a(x) abs(x)
|
||||
#define d(x,b) (pi*b*min(a(x)+0.5,1.0/b))
|
||||
#define e(x,b) (pi*b*min(max(a(x)-0.5,-1.0/b),1.0/b))
|
||||
#define STU(x,b) ((d(x,b)+sin(d(x,b))-e(x,b)-sin(e(x,b)))/(2.0*pi))
|
||||
#define X(i) (offset-(i))
|
||||
|
||||
#define GETC (texture(source[0], vec2(texCoord.x - X*sourceSize[0].z,texCoord.y)).xyz)
|
||||
#define VAL (c*STU(X,(TV_HORIZONTAL_RESOLUTION*sourceSize[0].z)))
|
||||
|
||||
#define PROCESS(i) X=X(i);c=GETC;tempColor+=VAL;
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
out vec4 fragColor;
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
float offset = fract((texCoord.x * sourceSize[0].x) - 0.5);
|
||||
vec3 tempColor = vec3(0.0);
|
||||
float X;
|
||||
vec3 c;
|
||||
PROCESS(-6)PROCESS(-5)PROCESS(-4)PROCESS(-3)PROCESS(-2)PROCESS(-1)PROCESS( 0)
|
||||
PROCESS( 7)PROCESS( 6)PROCESS( 5)PROCESS( 4)PROCESS( 3)PROCESS( 2)PROCESS( 1)
|
||||
|
||||
// tempColor=pow(tempColor,vec3(1.0/2.2));
|
||||
fragColor = vec4(tempColor,1.0);
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
#version 150
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// GTU version 0.40
|
||||
// Author: aliaspider - aliaspider@gmail.com
|
||||
// License: GPLv3
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// SETTINGS
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
//#define CROP_OVERSCAN
|
||||
#define TV_COLOR_LEVELS
|
||||
//#define COMPOSITE_CONNECTION
|
||||
//#define NO_SCANLINES
|
||||
#define TV_HORIZONTAL_RESOLUTION 400.0
|
||||
#define TV_VERTICAL_RESOLUTION 300.0
|
||||
#define SIGNAL_RESOLUTION 280.0
|
||||
#define SIGNAL_RESOLUTION_I 83.0
|
||||
#define SIGNAL_RESOLUTION_Q 25.0
|
||||
#define TV_DISPLAY_GAMMA 2.4
|
||||
#define OUTPUT_DISPLAY_GAMMA 2.2
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#define SCANLINE_WIDTH (1.5*sourceSize[0].y/TV_VERTICAL_RESOLUTION)
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform sampler2D texture[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
out vec4 fragColor;
|
||||
|
||||
|
||||
#define GAMMAOUT(c0) (pow(c0, vec3(1.0/OUTPUTG2)))
|
||||
#define pi 3.14159265358
|
||||
#define GAUSS(x,w) ((sqrt(2.0) / (w)) * (exp((-2.0 * pi * (x) * (x)) / ((w) * (w)))))
|
||||
#define Y(j) (offset.y-(j))
|
||||
#define a(x) abs(x)
|
||||
#define d(x,b) (pi*b*min(a(x)+0.5,1.0/b))
|
||||
#define e(x,b) (pi*b*min(max(a(x)-0.5,-1.0/b),1.0/b))
|
||||
#define STU(x,b) ((d(x,b)+sin(d(x,b))-e(x,b)-sin(e(x,b)))/(2.0*pi))
|
||||
|
||||
#define SOURCE(j) vec2(texCoord.x,texCoord.y - Y(j)*sourceSize[0].w)
|
||||
#define C(j) (texture2D(source[0], SOURCE(j)).xyz)
|
||||
|
||||
#ifdef NO_SCANLINES
|
||||
#define VAL(j) (C(j)*STU(Y(j),(TV_VERTICAL_RESOLUTION*sourceSize[0].w)))
|
||||
#else
|
||||
#define VAL(j) (C(j)*GAUSS(Y(j),SCANLINE_WIDTH))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 offset = fract((texCoord.xy * sourceSize[0].xy) - 0.5);
|
||||
vec3 tempColor = vec3(0.0);
|
||||
|
||||
tempColor+=VAL(-3.0);
|
||||
tempColor+=VAL(-2.0);
|
||||
tempColor+=VAL(-1.0);
|
||||
tempColor+=VAL(0.0);
|
||||
tempColor+=VAL(1.0);
|
||||
tempColor+=VAL(2.0);
|
||||
tempColor+=VAL(3.0);
|
||||
tempColor+=VAL(4.0);
|
||||
|
||||
fragColor = vec4(pow(tempColor,vec3(1.0/OUTPUT_DISPLAY_GAMMA)), 1.0);
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
#version 150
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// GTU version 0.40
|
||||
// Author: aliaspider - aliaspider@gmail.com
|
||||
// License: GPLv3
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// SETTINGS
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
//#define CROP_OVERSCAN
|
||||
#define TV_COLOR_LEVELS
|
||||
//#define COMPOSITE_CONNECTION
|
||||
//#define NO_SCANLINES
|
||||
#define TV_HORIZONTAL_RESOLUTION 400.0
|
||||
#define TV_VERTICAL_RESOLUTION 300.0
|
||||
#define SIGNAL_RESOLUTION 280.0
|
||||
#define SIGNAL_RESOLUTION_I 83.0
|
||||
#define SIGNAL_RESOLUTION_Q 25.0
|
||||
#define TV_DISPLAY_GAMMA 2.4
|
||||
#define OUTPUT_DISPLAY_GAMMA 2.2
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex{
|
||||
vec2 texCoord;
|
||||
}vertexOut;
|
||||
|
||||
void main(void){
|
||||
|
||||
#ifdef CROP_OVERSCAN
|
||||
gl_Position=position;
|
||||
gl_Position.y/=(224.0/240.0);
|
||||
#else
|
||||
gl_Position=position;
|
||||
#endif
|
||||
|
||||
vertexOut.texCoord=texCoord;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
program
|
||||
width: 100%
|
||||
height: 100%
|
||||
format: rgba32f
|
||||
filter: nearest
|
||||
wrap: edge
|
||||
fragment: GTU-pass1.fs
|
||||
program
|
||||
height: 100%
|
||||
format: rgba32f
|
||||
filter: nearest
|
||||
wrap: edge
|
||||
vertex: GTU-pass2.vs
|
||||
fragment: GTU-pass2.fs
|
||||
program
|
||||
height: 100%
|
||||
format: rgba32f
|
||||
filter: nearest
|
||||
wrap: edge
|
||||
fragment: GTU-pass3.fs
|
||||
program
|
||||
format: rgba8
|
||||
filter: nearest
|
||||
wrap: edge
|
||||
vertex: GTU-pass4.vs
|
||||
fragment: GTU-pass4.fs
|
||||
output
|
||||
filter: nearest
|
|
@ -1,88 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#in red
|
||||
#in green
|
||||
#in blue
|
||||
#in gain
|
||||
#in gamma
|
||||
#in blacklevel
|
||||
#in ambient
|
||||
#in BGR
|
||||
|
||||
#define outgamma 2.2
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
#define fetch_offset(coord,offset) (pow(vec3(gain) * texelFetchOffset(source[0], (coord), 0, (offset)).rgb + vec3(blacklevel), vec3(gamma)) + vec3(ambient))
|
||||
|
||||
// integral of (1 - x^2 - x^4 + x^6)^2
|
||||
const float coeffs_x[] = float[](1.0, -2.0/3.0, -1.0/5.0, 4.0/7.0, -1.0/9.0, -2.0/11.0, 1.0/13.0);
|
||||
// integral of (1 - 2x^4 + x^6)^2
|
||||
const float coeffs_y[] = float[](1.0, 0.0, -4.0/5.0, 2.0/7.0, 4.0/9.0, -4.0/11.0, 1.0/13.0);
|
||||
float intsmear_func(float z, float coeffs[7])
|
||||
{
|
||||
float z2 = z*z;
|
||||
float zn = z;
|
||||
float ret = 0.0;
|
||||
for (int i = 0; i < 7; i++) {
|
||||
ret += zn*coeffs[i];
|
||||
zn *= z2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
float intsmear(float x, float dx, float d, float coeffs[7])
|
||||
{
|
||||
float zl = clamp((x-dx*0.5)/d,-1.0,1.0);
|
||||
float zh = clamp((x+dx*0.5)/d,-1.0,1.0);
|
||||
return d * ( intsmear_func(zh,coeffs) - intsmear_func(zl,coeffs) )/dx;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texelSize = 1.0 / sourceSize[0].xy;
|
||||
vec2 range = sourceSize[0].xy / (targetSize.xy * sourceSize[0].xy);
|
||||
|
||||
vec3 cred = pow(red, vec3(outgamma));
|
||||
vec3 cgreen = pow(green, vec3(outgamma));
|
||||
vec3 cblue = pow(blue, vec3(outgamma));
|
||||
|
||||
ivec2 tli = ivec2(floor(texCoord/texelSize-vec2(0.4999)));
|
||||
|
||||
vec3 lcol, rcol;
|
||||
float subpix = (texCoord.x/texelSize.x - 0.4999 - float(tli.x))*3.0;
|
||||
float rsubpix = range.x/texelSize.x * 3.0;
|
||||
lcol = vec3(intsmear(subpix+1.0,rsubpix, 1.5, coeffs_x),
|
||||
intsmear(subpix ,rsubpix, 1.5, coeffs_x),
|
||||
intsmear(subpix-1.0,rsubpix, 1.5, coeffs_x));
|
||||
rcol = vec3(intsmear(subpix-2.0,rsubpix, 1.5, coeffs_x),
|
||||
intsmear(subpix-3.0,rsubpix, 1.5, coeffs_x),
|
||||
intsmear(subpix-4.0,rsubpix, 1.5, coeffs_x));
|
||||
#ifdef BGR
|
||||
lcol.rgb = lcol.bgr;
|
||||
rcol.rgb = rcol.bgr;
|
||||
#endif
|
||||
float tcol, bcol;
|
||||
subpix = texCoord.y/texelSize.y - 0.4999 - float(tli.y);
|
||||
rsubpix = range.y/texelSize.y;
|
||||
tcol = intsmear(subpix ,rsubpix, 0.63, coeffs_y);
|
||||
bcol = intsmear(subpix-1.0,rsubpix, 0.63, coeffs_y);
|
||||
|
||||
vec3 topLeftColor = fetch_offset(tli, ivec2(0,0)) * lcol * vec3(tcol);
|
||||
vec3 bottomRightColor = fetch_offset(tli, ivec2(1,1)) * rcol * vec3(bcol);
|
||||
vec3 bottomLeftColor = fetch_offset(tli, ivec2(0,1)) * lcol * vec3(bcol);
|
||||
vec3 topRightColor = fetch_offset(tli, ivec2(1,0)) * rcol * vec3(tcol);
|
||||
|
||||
vec3 averageColor = topLeftColor + bottomRightColor + bottomLeftColor + topRightColor;
|
||||
|
||||
averageColor = mat3x3(cred, cgreen, cblue) * averageColor;
|
||||
|
||||
fragColor = vec4(pow(averageColor,vec3(1.0/outgamma)),0.0);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
settings
|
||||
persistence: 0.5
|
||||
red: vec3(1,0,0)
|
||||
green: vec3(0,1,0)
|
||||
blue: vec3(0,0,1)
|
||||
gain: 1.0
|
||||
gamma: 3.0
|
||||
blacklevel: 0.05
|
||||
ambient: 0.0
|
||||
BGR
|
||||
|
||||
input
|
||||
history: 8
|
||||
filter: nearest
|
||||
|
||||
program
|
||||
fragment: motion-blur.fs
|
||||
filter: nearest
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
program
|
||||
fragment: lcd-grid.fs
|
|
@ -1,23 +0,0 @@
|
|||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform sampler2D history[];
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec4 color = pow(texture(history[7], texCoord).rgba, vec4(2.2));
|
||||
color = (color + pow(texture(history[6], texCoord).rgba, vec4(2.2))) / 2.0;
|
||||
color = (color + pow(texture(history[5], texCoord).rgba, vec4(2.2))) / 2.0;
|
||||
color = (color + pow(texture(history[4], texCoord).rgba, vec4(2.2))) / 2.0;
|
||||
color = (color + pow(texture(history[3], texCoord).rgba, vec4(2.2))) / 2.0;
|
||||
color = (color + pow(texture(history[2], texCoord).rgba, vec4(2.2))) / 2.0;
|
||||
color = (color + pow(texture(history[1], texCoord).rgba, vec4(2.2))) / 2.0;
|
||||
color = (color + pow(texture(history[0], texCoord).rgba, vec4(2.2))) / 2.0;
|
||||
color = (color + pow(texture(source[0], texCoord).rgba, vec4(2.2))) / 2.0;
|
||||
fragColor = pow(color, vec4(1.0 / 2.2));
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
program
|
||||
width: 100%
|
||||
height: 100%
|
||||
filter: nearest
|
||||
fragment: mdapt-pass1.fs
|
||||
wrap: edge
|
||||
program
|
||||
width: 100%
|
||||
height: 100%
|
||||
filter: nearest
|
||||
fragment: mdapt-pass2.fs
|
||||
wrap: edge
|
||||
program
|
||||
width: 100%
|
||||
height: 100%
|
||||
filter: nearest
|
||||
fragment: mdapt-pass3.fs
|
||||
wrap: edge
|
||||
program
|
||||
width: 100%
|
||||
height: 100%
|
||||
filter: nearest
|
||||
fragment: mdapt-pass4.fs
|
||||
wrap: edge
|
|
@ -1,200 +0,0 @@
|
|||
// This is a port of the original CG shader to the quark format
|
||||
// the original shader can be found here :
|
||||
// https://github.com/libretro/common-shaders/tree/master/dithering/mdapt-4p
|
||||
|
||||
/*
|
||||
Merge Dithering and Pseudo Transparency Shader v1.5 - Pass 1
|
||||
by Sp00kyFox, 2013
|
||||
|
||||
Finds specific patterns and tags their central pixel.
|
||||
|
||||
*/
|
||||
#version 150
|
||||
//#define HORI
|
||||
//#define VERT
|
||||
#define dtt vec3(65536,255,1)
|
||||
#define eq_threshold 5.0
|
||||
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
in Vertex{
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
float reduce(vec3 color)
|
||||
{
|
||||
return dot(color, dtt);
|
||||
}
|
||||
|
||||
float df(float A, float B)
|
||||
{
|
||||
return abs(A-B);
|
||||
}
|
||||
|
||||
bool eq(float A, float B)
|
||||
{
|
||||
return (A == B);
|
||||
}
|
||||
|
||||
float remapTo01(float v, float low, float high)
|
||||
{
|
||||
return clamp((v - low)/(high-low),0.0,1.0);
|
||||
}
|
||||
|
||||
|
||||
void main(void) {
|
||||
vec2 pos = texCoord*sourceSize[0].xy; // pos = pixel position
|
||||
vec2 dir = sign(pos); // dir = pixel direction
|
||||
|
||||
vec2 g1 = dir*vec2(sourceSize[0].z,0.0);
|
||||
vec2 g2 = dir*vec2(0.0,sourceSize[0].w);;
|
||||
|
||||
/*
|
||||
U3
|
||||
UUL U2 UUR
|
||||
ULL UL U1 UR URR
|
||||
L3 L2 L1 C R1 R2 R3
|
||||
DLL DL D1 DR DRR
|
||||
DDL D2 DDR
|
||||
D3
|
||||
*/
|
||||
|
||||
vec3 c = texture(source[0], texCoord).xyz;
|
||||
vec3 l1 = texture(source[0], texCoord - g1).xyz;
|
||||
vec3 l2 = texture(source[0], texCoord - 2*g1).xyz;
|
||||
vec3 r1 = texture(source[0], texCoord + g1).xyz;
|
||||
vec3 r2 = texture(source[0], texCoord + 2*g1).xyz;
|
||||
vec3 u1 = texture(source[0], texCoord - g2).xyz;
|
||||
vec3 u2 = texture(source[0], texCoord - 2*g2).xyz;
|
||||
vec3 d1 = texture(source[0], texCoord + g2).xyz;
|
||||
vec3 d2 = texture(source[0], texCoord + 2*g2).xyz;
|
||||
vec3 ul = texture(source[0], texCoord - g1 - g2).xyz;
|
||||
vec3 ur = texture(source[0], texCoord + g1 - g2).xyz;
|
||||
vec3 dl = texture(source[0], texCoord - g1 + g2).xyz;
|
||||
vec3 dr = texture(source[0], texCoord + g1 + g2).xyz;
|
||||
|
||||
vec3 ull = texture(source[0], texCoord - 2*g1 - g2).xyz;
|
||||
vec3 uul = texture(source[0], texCoord - g1 - 2*g2).xyz;
|
||||
vec3 uur = texture(source[0], texCoord + g1 - 2*g2).xyz;
|
||||
vec3 urr = texture(source[0], texCoord + 2*g1 - g2).xyz;
|
||||
vec3 drr = texture(source[0], texCoord + 2*g1 + g2).xyz;
|
||||
vec3 ddr = texture(source[0], texCoord + g1 + 2*g2).xyz;
|
||||
vec3 ddl = texture(source[0], texCoord - g1 + 2*g2).xyz;
|
||||
vec3 dll = texture(source[0], texCoord - 2*g1 + g2).xyz;
|
||||
|
||||
vec3 l3 = texture(source[0], texCoord - 3*g1).xyz;
|
||||
vec3 r3 = texture(source[0], texCoord + 3*g1).xyz;
|
||||
vec3 u3 = texture(source[0], texCoord - 3*g2).xyz;
|
||||
vec3 d3 = texture(source[0], texCoord + 3*g2).xyz;
|
||||
|
||||
float C = reduce( c );
|
||||
|
||||
float L1 = reduce( l1 ); float U1 = reduce( u1 );
|
||||
float L2 = reduce( l2 ); float U2 = reduce( u2 );
|
||||
float R1 = reduce( r1 ); float D1 = reduce( d1 );
|
||||
float R2 = reduce( r2 ); float D2 = reduce( d2 );
|
||||
|
||||
float UL = reduce( ul ); float L3 = reduce( l3 );
|
||||
float UR = reduce( ur ); float R3 = reduce( r3 );
|
||||
float DL = reduce( dl ); float U3 = reduce( u3 );
|
||||
float DR = reduce( dr ); float D3 = reduce( d3 );
|
||||
|
||||
float ULL = reduce( ull ); float DRR = reduce( drr );
|
||||
float UUL = reduce( uul ); float DDR = reduce( ddr );
|
||||
float UUR = reduce( uur ); float DDL = reduce( ddl );
|
||||
float URR = reduce( urr ); float DLL = reduce( dll );
|
||||
|
||||
/*
|
||||
tag values:
|
||||
0 nothing
|
||||
|
||||
checkerboard pattern
|
||||
9 DL
|
||||
8 DR
|
||||
7 UR
|
||||
6 UL
|
||||
5 full
|
||||
|
||||
horizontal two-line checkerboard
|
||||
4 bottom line
|
||||
3 upper line
|
||||
|
||||
vertical two-line checkerboard
|
||||
2 left line
|
||||
1 right line
|
||||
|
||||
one line dither
|
||||
-1 horizontal
|
||||
-2 vertical
|
||||
*/
|
||||
|
||||
float type=0;
|
||||
|
||||
// checkerboard pattern
|
||||
if(!eq(C,D1) && !eq(C,U1) && !eq(C,L1) && !eq(C,R1))
|
||||
{
|
||||
if(eq(C,UL))
|
||||
{
|
||||
if(eq(C,UR))
|
||||
{
|
||||
if(eq(C,DR))
|
||||
{
|
||||
if(eq(C,DL))
|
||||
type = 5;
|
||||
else if(!eq(D1,L1) || eq(D1,DL))
|
||||
type = 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(eq(C,DL) && (!eq(D1,R1) || eq(D1,DR)))
|
||||
type = 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(eq(C,DR) && eq(C,DL) && (!eq(U1,R1) || eq(U1,UR)))
|
||||
type = 7;
|
||||
}
|
||||
}
|
||||
else if(eq(C,UR) && eq(C,DR) && eq(C,DL) && (!eq(U1,L1) || eq(U1,UL)))
|
||||
type = 6;
|
||||
}
|
||||
// horizontal two-line checkerboard
|
||||
else if(eq(C,L2) && eq(C,R2) && eq(C,UL) && eq(C,UR) && !eq(C,L1) && !eq(C,R1) && !eq(C,ULL) && !eq(C,U1) && !eq(C,URR))
|
||||
{
|
||||
type = 4;
|
||||
}
|
||||
else if(eq(C,L2) && eq(C,R2) && eq(C,DL) && eq(C,DR) && !eq(C,L1) && !eq(C,R1) && !eq(C,DLL) && !eq(C,D1) && !eq(C,DRR))
|
||||
{
|
||||
type = 3;
|
||||
}
|
||||
// vertical two-line checkerboard
|
||||
else if(eq(C,U2) && eq(C,D2) && eq(C,UR) && eq(C,DR) && !eq(C,U1) && !eq(C,D1) && !eq(C,R1) && !eq(C,UUR) && !eq(C,DDR))
|
||||
{
|
||||
type = 2;
|
||||
}
|
||||
else if(eq(C,U2) && eq(C,D2) && eq(C,UL) && eq(C,DL) && !eq(C,U1) && !eq(C,D1) && !eq(C,L1) && !eq(C,UUL) && !eq(C,DDL))
|
||||
{
|
||||
type = 1;
|
||||
}
|
||||
#ifdef HORI
|
||||
// horizontal one line dither
|
||||
else if(eq(C,L2) && eq(C,R2) && eq(L1,R1) && !eq(C,L1) && !eq(C,L3) && !eq(C,R3))
|
||||
type = -1;
|
||||
#endif
|
||||
#ifdef VERT
|
||||
// vertical one line dither
|
||||
else if(eq(C,U2) && eq(C,D2) && eq(U1,D1) && !eq(C,U1) && !eq(C,U3) && !eq(C,D3))
|
||||
type = -2;
|
||||
#endif
|
||||
|
||||
fragColor=vec4(c, remapTo01(type+2, 0, 15));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
// This is a port of the original CG shader to the quark format
|
||||
// the original shader can be found here :
|
||||
// https://github.com/libretro/common-shaders/tree/master/dithering/mdapt-4p
|
||||
|
||||
/*
|
||||
Merge Dithering and Pseudo Transparency Shader v1.5 - Pass 1
|
||||
by Sp00kyFox, 2013
|
||||
|
||||
Finds specific patterns and tags their central pixel.
|
||||
|
||||
*/
|
||||
|
||||
#version 150
|
||||
// Radius of the area where the algorithm looks for other detected pixels.
|
||||
#define rad 2
|
||||
|
||||
// Minimal count of detection pixels in search area to be rated as valid.
|
||||
#define minimum 3
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
in Vertex{
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
float remapTo01(float v, float low, float high)
|
||||
{
|
||||
return clamp((v - low)/(high-low),0.0,1.0);
|
||||
}
|
||||
|
||||
float remapFrom01(float v, float low, float high)
|
||||
{
|
||||
return round(mix(low, high, v));
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec2 pos = texCoord*sourceSize[0].xy; // pos = pixel position
|
||||
vec2 dir = sign(pos); // dir = pixel direction
|
||||
|
||||
vec2 g1 = dir*vec2(sourceSize[0].z,0.0);
|
||||
vec2 g2 = dir*vec2(0.0,sourceSize[0].w);
|
||||
|
||||
vec4 CC = texture(source[0], texCoord).xyzw;
|
||||
|
||||
float C = remapFrom01(CC.w, 0, 15) - 2;
|
||||
|
||||
if(C == 0){
|
||||
fragColor=CC;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
tag values:
|
||||
0 nothing
|
||||
|
||||
checkerboard pattern
|
||||
9 DL
|
||||
8 DR
|
||||
7 UR
|
||||
6 UL
|
||||
5 full
|
||||
|
||||
horizontal two-line checkerboard
|
||||
4 bottom line
|
||||
3 upper line
|
||||
|
||||
vertical two-line checkerboard
|
||||
2 left line
|
||||
1 right line
|
||||
|
||||
one line dither
|
||||
-1 horizontal
|
||||
-2 vertical
|
||||
*/
|
||||
|
||||
int hits = 0;
|
||||
|
||||
if(C > 0)
|
||||
{
|
||||
// for(int x=-rad; x<=rad; x++)
|
||||
// {
|
||||
// for(int y=-rad; y<=rad; y++)
|
||||
// {
|
||||
// hits += ((remapFrom01(texture(source[0], texCoord + (x*g1) + (y*g2)).x, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
// }
|
||||
// }
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + (-2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + (-1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + ( 0*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + ( 1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + ( 2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + (-2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + (-1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + ( 0*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + ( 1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + ( 2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + (-2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + (-1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + ( 0*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + ( 1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + ( 2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + (-2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + (-1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + ( 0*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + ( 1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + ( 2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + (-2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + (-1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + ( 0*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + ( 1*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + ( 2*g2)).w, 0, 15) - 2) > 0) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// for(int x=-rad; x<=rad; x++)
|
||||
// {
|
||||
// for(int y=-rad; y<=rad; y++)
|
||||
// {
|
||||
// hits += ((remapFrom01(texture(source[0], texCoord + (x*g1) + (y*g2)).x, 0, 15) - 2) == C) ? 1 : 0;
|
||||
// }
|
||||
// }
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + (-2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + (-1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + ( 0*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + ( 1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-2*g1) + ( 2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + (-2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + (-1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + ( 0*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + ( 1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + (-1*g1) + ( 2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + (-2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + (-1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + ( 0*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + ( 1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 0*g1) + ( 2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + (-2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + (-1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + ( 0*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + ( 1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 1*g1) + ( 2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + (-2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + (-1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + ( 0*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + ( 1*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
hits += ((remapFrom01(texture(source[0], texCoord + ( 2*g1) + ( 2*g2)).w, 0, 15) - 2) == C) ? 1 : 0;
|
||||
fragColor=CC;
|
||||
return;
|
||||
}
|
||||
|
||||
if(hits < minimum)
|
||||
fragColor=vec4(CC.xyz, remapTo01(2, 0, 15));
|
||||
else
|
||||
fragColor=CC;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
// This is a port of the original CG shader to the quark format
|
||||
// the original shader can be found here :
|
||||
// https://github.com/libretro/common-shaders/tree/master/dithering/mdapt-4p
|
||||
|
||||
/*
|
||||
Merge Dithering and Pseudo Transparency Shader v1.5 - Pass 3
|
||||
by Sp00kyFox, 2013
|
||||
|
||||
Tags the rest of the detected pattern from pass 1.
|
||||
|
||||
*/
|
||||
|
||||
#version 150
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
in Vertex{
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
float remapTo01(float v, float low, float high)
|
||||
{
|
||||
return clamp((v - low)/(high-low),0.0,1.0);
|
||||
}
|
||||
|
||||
float remapFrom01(float v, float low, float high)
|
||||
{
|
||||
return round(mix(low, high, v));
|
||||
}
|
||||
void main(void) {
|
||||
vec2 pos = texCoord*sourceSize[0].xy; // pos = pixel position
|
||||
vec2 dir = sign(pos); // dir = pixel direction
|
||||
|
||||
vec2 g1 = dir*vec2(sourceSize[0].z,0.0);
|
||||
vec2 g2 = dir*vec2(0.0,sourceSize[0].w);
|
||||
/*
|
||||
U2
|
||||
UL U1 UR
|
||||
L2 L1 xC R1 R2
|
||||
DL D1 DR
|
||||
D2
|
||||
*/
|
||||
|
||||
vec4 xC = texture(source[0], texCoord).xyzw;
|
||||
vec4 xL1 = texture(source[0], texCoord - g1).xyzw;
|
||||
vec4 xL2 = texture(source[0], texCoord - 2*g1).xyzw;
|
||||
vec4 xR1 = texture(source[0], texCoord + g1).xyzw;
|
||||
vec4 xR2 = texture(source[0], texCoord + 2*g1).xyzw;
|
||||
vec4 xU1 = texture(source[0], texCoord - g2).xyzw;
|
||||
vec4 xU2 = texture(source[0], texCoord - 2*g2).xyzw;
|
||||
vec4 xD1 = texture(source[0], texCoord + g2).xyzw;
|
||||
vec4 xD2 = texture(source[0], texCoord + 2*g2).xyzw;
|
||||
vec4 xUL = texture(source[0], texCoord - g1 - g2).xyzw;
|
||||
vec4 xUR = texture(source[0], texCoord + g1 - g2).xyzw;
|
||||
vec4 xDL = texture(source[0], texCoord - g1 + g2).xyzw;
|
||||
vec4 xDR = texture(source[0], texCoord + g1 + g2).xyzw;
|
||||
|
||||
float C = remapFrom01(xC.w, 0, 15) - 2;
|
||||
float L1 = remapFrom01(xL1.w, 0, 15) - 2;
|
||||
float L2 = remapFrom01(xL2.w, 0, 15) - 2;
|
||||
float R1 = remapFrom01(xR1.w, 0, 15) - 2;
|
||||
float R2 = remapFrom01(xR2.w, 0, 15) - 2;
|
||||
float U1 = remapFrom01(xU1.w, 0, 15) - 2;
|
||||
float U2 = remapFrom01(xU2.w, 0, 15) - 2;
|
||||
float D1 = remapFrom01(xD1.w, 0, 15) - 2;
|
||||
float D2 = remapFrom01(xD2.w, 0, 15) - 2;
|
||||
float UL = remapFrom01(xUL.w, 0, 15) - 2;
|
||||
float UR = remapFrom01(xUR.w, 0, 15) - 2;
|
||||
float DL = remapFrom01(xDL.w, 0, 15) - 2;
|
||||
float DR = remapFrom01(xDR.w, 0, 15) - 2;
|
||||
|
||||
/*
|
||||
tag values:
|
||||
0 nothing
|
||||
|
||||
checkerboard pattern
|
||||
9 DL
|
||||
8 DR
|
||||
7 UR
|
||||
6 UL
|
||||
5 full
|
||||
|
||||
horizontal two-line checkerboard
|
||||
4 bottom line
|
||||
3 upper line
|
||||
|
||||
vertical two-line checkerboard
|
||||
2 left line
|
||||
1 right line
|
||||
|
||||
one line dither
|
||||
-1 horizontal
|
||||
-2 vertical
|
||||
*/
|
||||
|
||||
// checkerboard pattern
|
||||
if(U1 == 5 || D1 == 5 || L1 == 5 || R1 == 5 || UL == 5 || UR == 5 || DR == 5 || DL == 5)
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(5+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
if(U1 == 6 || L1 == 6 || UL == 6 || UR == 6 || DL == 6) // UL
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(6+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
|
||||
if(U1 == 7 || R1 == 7 || UL == 7 || UR == 7 || DR == 7) // UR
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(7+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
|
||||
if(D1 == 8 || R1 == 8 || UR == 8 || DR == 8 || DL == 8) // DR
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(8+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
|
||||
if(D1 == 9 || L1 == 9 || UL == 9 || DR == 9 || DL == 9) // DL
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(9+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
|
||||
// horizontal two-line checkerboard
|
||||
if (L2 == 4 || L1 == 4 || R1 == 4 || R2 == 4 || DL == 4 || D1 == 4 || DR == 4)
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(4+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
if (L2 == 3 || L1 == 3 || R1 == 3 || R2 == 3 || UL == 3 || U1 == 3 || UR == 3)
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(3+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
|
||||
// vertical two-line checkerboard
|
||||
if (U2 == 2 || U1 == 2 || D1 == 2 || D2 == 2 || UL == 2 || L1 == 2 || DL == 2)
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(2+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
if (U2 == 1 || U1 == 1 || D1 == 1 || D2 == 1 || UR == 1 || R1 == 1 || DR == 1)
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(1+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
|
||||
if(C > 0){
|
||||
fragColor=xC;
|
||||
return ;
|
||||
}
|
||||
|
||||
// horizontal one line dither
|
||||
if (L2 == -1 || L1 == -1 || R1 == -1 || R2 == -1)
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(-1+2, 0, 15));
|
||||
return ;
|
||||
}
|
||||
|
||||
// vertical one line dither
|
||||
if (U2 == -2 || U1 == -2 || D1 == -2 || D2 == -2)
|
||||
{
|
||||
fragColor=vec4(xC.xyz, remapTo01(-2+2, 0, 15));
|
||||
return;
|
||||
}
|
||||
|
||||
fragColor=xC;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
// This is a port of the original CG shader to the quark format
|
||||
// the original shader can be found here :
|
||||
// https://github.com/libretro/common-shaders/tree/master/dithering/mdapt-4p
|
||||
|
||||
/*
|
||||
Merge Dithering and Pseudo Transparency Shader v1.5 - Pass 4
|
||||
by Sp00kyFox, 2013
|
||||
|
||||
Blends tagged pixels with tagged neighbors.
|
||||
|
||||
*/
|
||||
|
||||
#version 150
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
in Vertex{
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
bool eq(vec4 A, vec4 B)
|
||||
{
|
||||
return (A.x == B.x && A.y == B.y && A.z == B.z);
|
||||
}
|
||||
|
||||
float remapFrom01(float v, float low, float high)
|
||||
{
|
||||
return round(mix(low, high, v));
|
||||
}
|
||||
|
||||
|
||||
vec3 merge3(vec4 C, vec4 A, vec4 B, float tag)
|
||||
{
|
||||
if(A.w == tag)
|
||||
{
|
||||
if(B.w == tag)
|
||||
return 0.5*C.xyz + 0.25*(A.xyz + B.xyz);
|
||||
else
|
||||
return 0.5*(C.xyz + A.xyz);
|
||||
}
|
||||
else if(B.w == tag)
|
||||
return 0.5*(C.xyz + B.xyz);
|
||||
else
|
||||
return C.xyz;
|
||||
}
|
||||
|
||||
vec3 merge9(vec4 C, vec4 UL, vec4 UR, vec4 DL, vec4 DR, vec4 U1, vec4 D1, vec4 L1, vec4 R1)
|
||||
{
|
||||
//return 0.25*C.xyz + 0.0625*(UL.xyz + UR.xyz + DR.xyz + DL.xyz) + 0.125*(L1.xyz + R1.xyz + D1.xyz + U1.xyz);
|
||||
|
||||
vec3 B = vec3(0.0);
|
||||
vec3 W = vec3(0.0);
|
||||
float cntB = 0;
|
||||
float cntW = 0;
|
||||
|
||||
if(UL.w > 0 || eq(UL,C) || (D1.w > 0 && eq(UL,D1)) || (R1.w > 0 && eq(UL,R1)) )
|
||||
{
|
||||
B = B+UL.xyz;
|
||||
cntB++;
|
||||
}
|
||||
if(UR.w > 0 || eq(UR,C) || (D1.w > 0 && eq(UR,D1)) || (L1.w > 0 && eq(UR,L1)) )
|
||||
{
|
||||
B = B+UR.xyz;
|
||||
cntB++;
|
||||
}
|
||||
if(DL.w > 0 || eq(DL,C) || (U1.w > 0 && eq(DL,U1)) || (R1.w > 0 && eq(DL,R1)) )
|
||||
{
|
||||
B = B+DL.xyz;
|
||||
cntB++;
|
||||
}
|
||||
if(DR.w > 0 || eq(DR,C) || (U1.w > 0 && eq(DR,U1)) || (L1.w > 0 && eq(DR,L1)) )
|
||||
{
|
||||
B = B+DR.xyz;
|
||||
cntB++;
|
||||
}
|
||||
if(U1.w > 0 || eq(U1,C) || (D1.w > 0 && eq(U1,D1)) )
|
||||
{
|
||||
W = W+U1.xyz;
|
||||
cntW++;
|
||||
}
|
||||
if(D1.w > 0 || eq(D1,C) || (U1.w > 0 && eq(D1,U1)) )
|
||||
{
|
||||
W = W+D1.xyz;
|
||||
cntW++;
|
||||
}
|
||||
if(L1.w > 0 || eq(L1,C) || (R1.w > 0 && eq(L1,R1)) )
|
||||
{
|
||||
W = W+L1.xyz;
|
||||
cntW++;
|
||||
}
|
||||
if(R1.w > 0 || eq(R1,C) || (L1.w > 0 && eq(R1,L1)) )
|
||||
{
|
||||
W = W+R1.xyz;
|
||||
cntW++;
|
||||
}
|
||||
|
||||
if(cntB == 0)
|
||||
{
|
||||
if(cntW == 0)
|
||||
return C.xyz;
|
||||
else
|
||||
return 0.5*C.xyz + (1/(cntW*2))*W;
|
||||
}
|
||||
if(cntW == 0)
|
||||
return 0.5*C.xyz + (1/(cntB*2))*B;
|
||||
else
|
||||
return 0.25*C.xyz + (1/(cntB*4))*B + (1/(cntW*2))*W;
|
||||
}
|
||||
void main(void) {
|
||||
vec2 pos = texCoord*sourceSize[0].xy; // pos = pixel position
|
||||
vec2 dir = sign(pos); // dir = pixel direction
|
||||
|
||||
vec2 g1 = dir*vec2(sourceSize[0].z,0.0);
|
||||
vec2 g2 = dir*vec2(0.0,sourceSize[0].w);
|
||||
|
||||
/*
|
||||
UL U1 UR
|
||||
L1 C R1
|
||||
DL D1 DR
|
||||
*/
|
||||
|
||||
vec4 C = texture(source[0], texCoord).xyzw;
|
||||
vec4 L1 = texture(source[0], texCoord - g1).xyzw;
|
||||
vec4 R1 = texture(source[0], texCoord + g1).xyzw;
|
||||
vec4 U1 = texture(source[0], texCoord - g2).xyzw;
|
||||
vec4 D1 = texture(source[0], texCoord + g2).xyzw;
|
||||
vec4 UL = texture(source[0], texCoord - g1 - g2).xyzw;
|
||||
vec4 UR = texture(source[0], texCoord + g1 - g2).xyzw;
|
||||
vec4 DL = texture(source[0], texCoord - g1 + g2).xyzw;
|
||||
vec4 DR = texture(source[0], texCoord + g1 + g2).xyzw;
|
||||
|
||||
|
||||
C.w = remapFrom01(C.w, 0, 15) - 2;
|
||||
L1.w = remapFrom01(L1.w, 0, 15) - 2;
|
||||
R1.w = remapFrom01(R1.w, 0, 15) - 2;
|
||||
U1.w = remapFrom01(U1.w, 0, 15) - 2;
|
||||
D1.w = remapFrom01(D1.w, 0, 15) - 2;
|
||||
UL.w = remapFrom01(UL.w, 0, 15) - 2;
|
||||
UR.w = remapFrom01(UR.w, 0, 15) - 2;
|
||||
DL.w = remapFrom01(DL.w, 0, 15) - 2;
|
||||
DR.w = remapFrom01(DR.w, 0, 15) - 2;
|
||||
|
||||
/*
|
||||
tag values:
|
||||
0 nothing
|
||||
|
||||
checkerboard pattern
|
||||
9 DL
|
||||
8 DR
|
||||
7 UR
|
||||
6 UL
|
||||
5 full
|
||||
|
||||
horizontal two-line checkerboard
|
||||
4 bottom line
|
||||
3 upper line
|
||||
|
||||
vertical two-line checkerboard
|
||||
2 left line
|
||||
1 right line
|
||||
|
||||
one line dither
|
||||
-1 horizontal
|
||||
-2 vertical
|
||||
*/
|
||||
|
||||
|
||||
// checkerboard pattern
|
||||
if(C.w > 0){
|
||||
fragColor=vec4(merge9(C,UL,UR,DL,DR,U1,D1,L1,R1),0);
|
||||
return;
|
||||
}
|
||||
// horizontal one line dither
|
||||
if(C.w == -1){
|
||||
fragColor=vec4(merge3(C,L1,R1,-1),0);
|
||||
return;
|
||||
}
|
||||
|
||||
// vertical one line dither
|
||||
if(C.w == -2){
|
||||
fragColor=vec4(merge3(C,U1,D1,-2),0);
|
||||
return;
|
||||
}
|
||||
|
||||
fragColor=vec4(C.xyz, 1.0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,229 +0,0 @@
|
|||
#version 150
|
||||
|
||||
// This is a port of the NTSC encode/decode shader pair in MAME and MESS, modified to use only
|
||||
// one pass rather than an encode pass and a decode pass. It accurately emulates the sort of
|
||||
// signal decimation one would see when viewing a composite signal, though it could benefit from a
|
||||
// pre-pass to re-size the input content to more accurately reflect the actual size that would
|
||||
// be incoming from a composite signal source.
|
||||
//
|
||||
// To encode the composite signal, I convert the RGB value to YIQ, then subsequently evaluate
|
||||
// the standard NTSC composite equation. Four composite samples per RGB pixel are generated from
|
||||
// the incoming linearly-interpolated texels.
|
||||
//
|
||||
// The decode pass implements a Fixed Impulse Response (FIR) filter designed by MAME/MESS contributor
|
||||
// "austere" in matlab (if memory serves correctly) to mimic the behavior of a standard television set
|
||||
// as closely as possible. The filter window is 83 composite samples wide, and there is an additional
|
||||
// notch filter pass on the luminance (Y) values in order to strip the color signal from the luminance
|
||||
// signal prior to processing.
|
||||
//
|
||||
// Yes, this code could greatly use some cleaning up.
|
||||
|
||||
// ported from UltraMoogleMan's "Full MAME/MESS Shader Pipe" shadertoy: https://www.shadertoy.com/view/ldf3Rf
|
||||
// license: presumably MAME's license at the time, which was noncommercial
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
// Useful Constants
|
||||
const vec4 Zero = vec4(0.0);
|
||||
const vec4 Half = vec4(0.5);
|
||||
const vec4 One = vec4(1.0);
|
||||
const vec4 Two = vec4(2.0);
|
||||
const vec3 Gray = vec3(0.3, 0.59, 0.11);
|
||||
const float Pi = 3.1415926535;
|
||||
const float Pi2 = 6.283185307;
|
||||
|
||||
// NTSC Constants
|
||||
const vec4 A = vec4(0.5);
|
||||
const vec4 A2 = vec4(1.0);
|
||||
const vec4 B = vec4(0.5);
|
||||
const float P = 1.0;
|
||||
const float CCFrequency = 3.59754545;
|
||||
const float NotchUpperFrequency = 5.59754545; //3.59754545 + 2.0;
|
||||
const float NotchLowerFrequency = 1.59754545; //3.59754545 - 2.0;
|
||||
const float YFrequency = 6.0;
|
||||
const float IFrequency = 1.2;
|
||||
const float QFrequency = 0.6;
|
||||
const float NotchHalfWidth = 2.0;
|
||||
const float ScanTime = 52.6;
|
||||
const float Pi2ScanTime = 330.4955471482;// 6.283185307 * 52.6;
|
||||
const float MaxC = 2.1183;
|
||||
const vec4 YTransform = vec4(0.299, 0.587, 0.114, 0.0);
|
||||
const vec4 ITransform = vec4(0.595716, -0.274453, -0.321263, 0.0);
|
||||
const vec4 QTransform = vec4(0.211456, -0.522591, 0.311135, 0.0);
|
||||
const vec3 YIQ2R = vec3(1.0, 0.956, 0.621);
|
||||
const vec3 YIQ2G = vec3(1.0, -0.272, -0.647);
|
||||
const vec3 YIQ2B = vec3(1.0, -1.106, 1.703);
|
||||
const vec4 MinC = vec4(-1.1183);
|
||||
const vec4 CRange = vec4(3.2366);
|
||||
const vec4 InvCRange = vec4(1.0/3.2366);
|
||||
const float Pi2Length = Pi2 / 63.0;
|
||||
const vec4 NotchOffset = vec4(0.0, 1.0, 2.0, 3.0);
|
||||
vec4 W = vec4(Pi2 * CCFrequency * ScanTime);
|
||||
|
||||
// Color Convolution Constants
|
||||
const vec3 RedMatrix = vec3(1.0, 0.0, 0.0);
|
||||
const vec3 GrnMatrix = vec3(0.0, 1.0, 0.0);
|
||||
const vec3 BluMatrix = vec3(0.0, 0.0, 1.0);
|
||||
const vec3 DCOffset = vec3(0.0, 0.0, 0.0);
|
||||
const vec3 ColorScale = vec3(0.95, 0.95, 0.95);
|
||||
const float Saturation = 1.4;
|
||||
|
||||
// Deconverge Constants
|
||||
const vec3 ConvergeX = vec3(-0.4, 0.0, 0.2);
|
||||
const vec3 ConvergeY = vec3( 0.0, -0.4, 0.2);
|
||||
const vec3 RadialConvergeX = vec3(1.0, 1.0, 1.0);
|
||||
const vec3 RadialConvergeY = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
// Scanline/Pincushion Constants
|
||||
const float PincushionAmount = 0.015;
|
||||
const float CurvatureAmount = 0.015;
|
||||
//const float ScanlineAmount = 0.175; <- move to parameter
|
||||
const float ScanlineScale = 1.0;
|
||||
const float ScanlineHeight = 1.0;
|
||||
const float ScanlineBrightScale = 1.0;
|
||||
const float ScanlineBrightOffset = 0.0;
|
||||
const float ScanlineOffset = 0.0;
|
||||
const vec3 Floor = vec3(0.05, 0.05, 0.05);
|
||||
|
||||
// 60Hz Bar Constants
|
||||
const float SixtyHertzRate = (60.0 / 59.97 - 1.0); // Difference between NTSC and line frequency
|
||||
const float SixtyHertzScale = 0.1;
|
||||
|
||||
vec4 CompositeSample(vec2 UV, vec2 InverseRes) {
|
||||
vec2 InverseP = vec2(P, 0.0) * InverseRes;
|
||||
|
||||
// UVs for four linearly-interpolated samples spaced 0.25 texels apart
|
||||
vec2 C0 = UV;
|
||||
vec2 C1 = UV + InverseP * 0.25;
|
||||
vec2 C2 = UV + InverseP * 0.50;
|
||||
vec2 C3 = UV + InverseP * 0.75;
|
||||
vec4 Cx = vec4(C0.x, C1.x, C2.x, C3.x);
|
||||
vec4 Cy = vec4(C0.y, C1.y, C2.y, C3.y);
|
||||
|
||||
vec4 Texel0 = texture(source[0], C0);
|
||||
vec4 Texel1 = texture(source[0], C1);
|
||||
vec4 Texel2 = texture(source[0], C2);
|
||||
vec4 Texel3 = texture(source[0], C3);
|
||||
|
||||
float Frequency = CCFrequency;
|
||||
//Frequency = Frequency;// Uncomment for bad color sync + (sin(UV.y * 2.0 - 1.0) / CCFrequency) * 0.001;
|
||||
|
||||
// Calculated the expected time of the sample.
|
||||
vec4 T = A2 * Cy * vec4(sourceSize[0].y) + B + Cx;
|
||||
vec4 W = vec4(Pi2ScanTime * Frequency);
|
||||
vec4 TW = T * W;
|
||||
vec4 Y = vec4(dot(Texel0, YTransform), dot(Texel1, YTransform), dot(Texel2, YTransform), dot(Texel3, YTransform));
|
||||
vec4 I = vec4(dot(Texel0, ITransform), dot(Texel1, ITransform), dot(Texel2, ITransform), dot(Texel3, ITransform));
|
||||
vec4 Q = vec4(dot(Texel0, QTransform), dot(Texel1, QTransform), dot(Texel2, QTransform), dot(Texel3, QTransform));
|
||||
|
||||
vec4 Encoded = Y + I * cos(TW) + Q * sin(TW);
|
||||
return (Encoded - MinC) * InvCRange;
|
||||
}
|
||||
|
||||
vec4 NTSCCodec(vec2 UV, vec2 InverseRes)
|
||||
{
|
||||
vec4 YAccum = Zero;
|
||||
vec4 IAccum = Zero;
|
||||
vec4 QAccum = Zero;
|
||||
float QuadXSize = sourceSize[0].x * 4.0;
|
||||
float TimePerSample = ScanTime / QuadXSize;
|
||||
|
||||
// Frequency cutoffs for the individual portions of the signal that we extract.
|
||||
// Y1 and Y2 are the positive and negative frequency limits of the notch filter on Y.
|
||||
// Y3 is the center of the frequency response of the Y filter.
|
||||
// I is the center of the frequency response of the I filter.
|
||||
// Q is the center of the frequency response of the Q filter.
|
||||
float Fc_y1 = NotchLowerFrequency * TimePerSample;
|
||||
float Fc_y2 = NotchUpperFrequency * TimePerSample;
|
||||
float Fc_y3 = YFrequency * TimePerSample;
|
||||
float Fc_i = IFrequency * TimePerSample;
|
||||
float Fc_q = QFrequency * TimePerSample;
|
||||
float Pi2Fc_y1 = Fc_y1 * Pi2;
|
||||
float Pi2Fc_y2 = Fc_y2 * Pi2;
|
||||
float Pi2Fc_y3 = Fc_y3 * Pi2;
|
||||
float Pi2Fc_i = Fc_i * Pi2;
|
||||
float Pi2Fc_q = Fc_q * Pi2;
|
||||
float Fc_y1_2 = Fc_y1 * 2.0;
|
||||
float Fc_y2_2 = Fc_y2 * 2.0;
|
||||
float Fc_y3_2 = Fc_y3 * 2.0;
|
||||
float Fc_i_2 = Fc_i * 2.0;
|
||||
float Fc_q_2 = Fc_q * 2.0;
|
||||
vec4 CoordY = vec4(UV.y);
|
||||
|
||||
// 83 composite samples wide, 4 composite pixels per texel
|
||||
for(float n = -31.0; n < 32.0; n += 4.0)
|
||||
{
|
||||
vec4 n4 = n + NotchOffset;
|
||||
vec4 CoordX = UV.x + InverseRes.x * n4 * 0.25;
|
||||
vec2 TexCoord = vec2(CoordX.x, CoordY.x);
|
||||
vec4 C = CompositeSample(TexCoord, InverseRes) * CRange + MinC;
|
||||
vec4 WT = W * (CoordX + A2 * CoordY * sourceSize[0].y + B);
|
||||
vec4 Cosine = 0.54 + 0.46 * cos(Pi2Length * n4);
|
||||
|
||||
vec4 SincYIn1 = Pi2Fc_y1 * n4;
|
||||
vec4 SincYIn2 = Pi2Fc_y2 * n4;
|
||||
vec4 SincYIn3 = Pi2Fc_y3 * n4;
|
||||
vec4 SincY1 = sin(SincYIn1) / SincYIn1;
|
||||
vec4 SincY2 = sin(SincYIn2) / SincYIn2;
|
||||
vec4 SincY3 = sin(SincYIn3) / SincYIn3;
|
||||
|
||||
// These zero-checks could be made more efficient if WebGL supported mix(vec4, vec4, bvec4)
|
||||
// Unfortunately, the universe hates us
|
||||
if(SincYIn1.x == 0.0) SincY1.x = 1.0;
|
||||
if(SincYIn1.y == 0.0) SincY1.y = 1.0;
|
||||
if(SincYIn1.z == 0.0) SincY1.z = 1.0;
|
||||
if(SincYIn1.w == 0.0) SincY1.w = 1.0;
|
||||
if(SincYIn2.x == 0.0) SincY2.x = 1.0;
|
||||
if(SincYIn2.y == 0.0) SincY2.y = 1.0;
|
||||
if(SincYIn2.z == 0.0) SincY2.z = 1.0;
|
||||
if(SincYIn2.w == 0.0) SincY2.w = 1.0;
|
||||
if(SincYIn3.x == 0.0) SincY3.x = 1.0;
|
||||
if(SincYIn3.y == 0.0) SincY3.y = 1.0;
|
||||
if(SincYIn3.z == 0.0) SincY3.z = 1.0;
|
||||
if(SincYIn3.w == 0.0) SincY3.w = 1.0;
|
||||
vec4 IdealY = (Fc_y1_2 * SincY1 - Fc_y2_2 * SincY2) + Fc_y3_2 * SincY3;
|
||||
vec4 FilterY = Cosine * IdealY;
|
||||
|
||||
vec4 SincIIn = Pi2Fc_i * n4;
|
||||
vec4 SincI = sin(SincIIn) / SincIIn;
|
||||
if (SincIIn.x == 0.0) SincI.x = 1.0;
|
||||
if (SincIIn.y == 0.0) SincI.y = 1.0;
|
||||
if (SincIIn.z == 0.0) SincI.z = 1.0;
|
||||
if (SincIIn.w == 0.0) SincI.w = 1.0;
|
||||
vec4 IdealI = Fc_i_2 * SincI;
|
||||
vec4 FilterI = Cosine * IdealI;
|
||||
|
||||
vec4 SincQIn = Pi2Fc_q * n4;
|
||||
vec4 SincQ = sin(SincQIn) / SincQIn;
|
||||
if (SincQIn.x == 0.0) SincQ.x = 1.0;
|
||||
if (SincQIn.y == 0.0) SincQ.y = 1.0;
|
||||
if (SincQIn.z == 0.0) SincQ.z = 1.0;
|
||||
if (SincQIn.w == 0.0) SincQ.w = 1.0;
|
||||
vec4 IdealQ = Fc_q_2 * SincQ;
|
||||
vec4 FilterQ = Cosine * IdealQ;
|
||||
|
||||
YAccum += C * FilterY;
|
||||
IAccum += C * cos(WT) * FilterI;
|
||||
QAccum += C * sin(WT) * FilterQ;
|
||||
}
|
||||
|
||||
float Y = dot(YAccum, One);
|
||||
float I = dot(IAccum, One) * 2.0;
|
||||
float Q = dot(QAccum, One) * 2.0;
|
||||
|
||||
vec3 YIQ = vec3(Y, I, Q);
|
||||
vec3 OutRGB = vec3(dot(YIQ, YIQ2R), dot(YIQ, YIQ2G), dot(YIQ, YIQ2B));
|
||||
|
||||
return vec4(OutRGB, 1.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(NTSCCodec(vTexCoord, sourceSize[0].zw));
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
#version 150
|
||||
|
||||
// This is a port of the NTSC encode/decode shader pair in MAME and MESS, modified to use only
|
||||
// one pass rather than an encode pass and a decode pass. It accurately emulates the sort of
|
||||
// signal decimation one would see when viewing a composite signal, though it could benefit from a
|
||||
// pre-pass to re-size the input content to more accurately reflect the actual size that would
|
||||
// be incoming from a composite signal source.
|
||||
//
|
||||
// To encode the composite signal, I convert the RGB value to YIQ, then subsequently evaluate
|
||||
// the standard NTSC composite equation. Four composite samples per RGB pixel are generated from
|
||||
// the incoming linearly-interpolated texels.
|
||||
//
|
||||
// The decode pass implements a Fixed Impulse Response (FIR) filter designed by MAME/MESS contributor
|
||||
// "austere" in matlab (if memory serves correctly) to mimic the behavior of a standard television set
|
||||
// as closely as possible. The filter window is 83 composite samples wide, and there is an additional
|
||||
// notch filter pass on the luminance (Y) values in order to strip the color signal from the luminance
|
||||
// signal prior to processing.
|
||||
//
|
||||
// Yes, this code could greatly use some cleaning up.
|
||||
|
||||
// ported from UltraMoogleMan's "Full MAME/MESS Shader Pipe" shadertoy: https://www.shadertoy.com/view/ldf3Rf
|
||||
// license: presumably MAME's license at the time, which was noncommercial
|
||||
|
||||
#define scanlines 0.0
|
||||
#define scandark 0.175
|
||||
#define deconverge 0.0
|
||||
#define pincushion 0.0
|
||||
#define hertzroll 0.0
|
||||
|
||||
// Useful Constants
|
||||
const vec4 Zero = vec4(0.0);
|
||||
const vec4 Half = vec4(0.5);
|
||||
const vec4 One = vec4(1.0);
|
||||
const vec4 Two = vec4(2.0);
|
||||
const vec3 Gray = vec3(0.3, 0.59, 0.11);
|
||||
const float Pi = 3.1415926535;
|
||||
const float Pi2 = 6.283185307;
|
||||
|
||||
// NTSC Constants
|
||||
const vec4 A = vec4(0.5);
|
||||
const vec4 A2 = vec4(1.0);
|
||||
const vec4 B = vec4(0.5);
|
||||
const float P = 1.0;
|
||||
const float CCFrequency = 3.59754545;
|
||||
const float NotchUpperFrequency = 5.59754545; //3.59754545 + 2.0;
|
||||
const float NotchLowerFrequency = 1.59754545; //3.59754545 - 2.0;
|
||||
const float YFrequency = 6.0;
|
||||
const float IFrequency = 1.2;
|
||||
const float QFrequency = 0.6;
|
||||
const float NotchHalfWidth = 2.0;
|
||||
const float ScanTime = 52.6;
|
||||
const float Pi2ScanTime = 330.4955471482;// 6.283185307 * 52.6;
|
||||
const float MaxC = 2.1183;
|
||||
const vec4 YTransform = vec4(0.299, 0.587, 0.114, 0.0);
|
||||
const vec4 ITransform = vec4(0.595716, -0.274453, -0.321263, 0.0);
|
||||
const vec4 QTransform = vec4(0.211456, -0.522591, 0.311135, 0.0);
|
||||
const vec3 YIQ2R = vec3(1.0, 0.956, 0.621);
|
||||
const vec3 YIQ2G = vec3(1.0, -0.272, -0.647);
|
||||
const vec3 YIQ2B = vec3(1.0, -1.106, 1.703);
|
||||
const vec4 MinC = vec4(-1.1183);
|
||||
const vec4 CRange = vec4(3.2366);
|
||||
const vec4 InvCRange = vec4(1.0/3.2366);
|
||||
const float Pi2Length = Pi2 / 63.0;
|
||||
const vec4 NotchOffset = vec4(0.0, 1.0, 2.0, 3.0);
|
||||
vec4 W = vec4(Pi2 * CCFrequency * ScanTime);
|
||||
|
||||
// Color Convolution Constants
|
||||
const vec3 RedMatrix = vec3(1.0, 0.0, 0.0);
|
||||
const vec3 GrnMatrix = vec3(0.0, 1.0, 0.0);
|
||||
const vec3 BluMatrix = vec3(0.0, 0.0, 1.0);
|
||||
const vec3 DCOffset = vec3(0.0, 0.0, 0.0);
|
||||
const vec3 ColorScale = vec3(0.95, 0.95, 0.95);
|
||||
const float Saturation = 1.4;
|
||||
|
||||
// Deconverge Constants
|
||||
const vec3 ConvergeX = vec3(-0.4, 0.0, 0.2);
|
||||
const vec3 ConvergeY = vec3( 0.0, -0.4, 0.2);
|
||||
const vec3 RadialConvergeX = vec3(1.0, 1.0, 1.0);
|
||||
const vec3 RadialConvergeY = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
// Scanline/Pincushion Constants
|
||||
const float PincushionAmount = 0.015;
|
||||
const float CurvatureAmount = 0.015;
|
||||
//const float ScanlineAmount = 0.175; <- move to parameter
|
||||
const float ScanlineScale = 1.0;
|
||||
const float ScanlineHeight = 1.0;
|
||||
const float ScanlineBrightScale = 1.0;
|
||||
const float ScanlineBrightOffset = 0.0;
|
||||
const float ScanlineOffset = 0.0;
|
||||
const vec3 Floor = vec3(0.05, 0.05, 0.05);
|
||||
|
||||
// 60Hz Bar Constants
|
||||
const float SixtyHertzRate = (60.0 / 59.97 - 1.0); // Difference between NTSC and line frequency
|
||||
const float SixtyHertzScale = 0.1;
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
uniform int phase;
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
vec4 ColorConvolution(vec2 UV, vec2 InverseRes)
|
||||
{
|
||||
vec3 InPixel = texture(source[0], UV).rgb;
|
||||
|
||||
// Color Matrix
|
||||
float RedValue = dot(InPixel, RedMatrix);
|
||||
float GrnValue = dot(InPixel, GrnMatrix);
|
||||
float BluValue = dot(InPixel, BluMatrix);
|
||||
vec3 OutColor = vec3(RedValue, GrnValue, BluValue);
|
||||
|
||||
// DC Offset & Scale
|
||||
OutColor = (OutColor * ColorScale) + DCOffset;
|
||||
|
||||
// Saturation
|
||||
float Luma = dot(OutColor, Gray);
|
||||
vec3 Chroma = OutColor - Luma;
|
||||
OutColor = (Chroma * Saturation) + Luma;
|
||||
|
||||
return vec4(OutColor, 1.0);
|
||||
}
|
||||
|
||||
vec4 Deconverge(vec2 UV)
|
||||
{
|
||||
vec2 InverseRes = 1.0 / sourceSize[0].xy;
|
||||
vec2 InverseSrcRes = 1.0 / sourceSize[0].xy;
|
||||
|
||||
vec3 CoordX = UV.x * RadialConvergeX;
|
||||
vec3 CoordY = UV.y * RadialConvergeY;
|
||||
|
||||
CoordX += ConvergeX * InverseRes.x - (RadialConvergeX - 1.0) * 0.5;
|
||||
CoordY += ConvergeY * InverseRes.y - (RadialConvergeY - 1.0) * 0.5;
|
||||
|
||||
float RedValue = ColorConvolution(vec2(CoordX.x, CoordY.x), InverseSrcRes).r;
|
||||
float GrnValue = ColorConvolution(vec2(CoordX.y, CoordY.y), InverseSrcRes).g;
|
||||
float BluValue = ColorConvolution(vec2(CoordX.z, CoordY.z), InverseSrcRes).b;
|
||||
|
||||
if (deconverge > 0.5) return vec4(RedValue, GrnValue, BluValue, 1.0);
|
||||
else return vec4(texture(source[0], UV));
|
||||
}
|
||||
|
||||
vec4 ScanlinePincushion(vec2 UV)
|
||||
{
|
||||
vec4 InTexel = Deconverge(UV);
|
||||
|
||||
vec2 PinUnitCoord = UV * Two.xy - One.xy;
|
||||
float PincushionR2 = pow(length(PinUnitCoord), 2.0);
|
||||
vec2 PincushionCurve = PinUnitCoord * PincushionAmount * PincushionR2;
|
||||
vec2 BaseCoord = UV;
|
||||
vec2 ScanCoord = UV;
|
||||
|
||||
BaseCoord *= One.xy - PincushionAmount * 0.2; // Warning: Magic constant
|
||||
BaseCoord += PincushionAmount * 0.1;
|
||||
BaseCoord += PincushionCurve;
|
||||
|
||||
ScanCoord *= One.xy - PincushionAmount * 0.2; // Warning: Magic constant
|
||||
ScanCoord += PincushionAmount * 0.1;
|
||||
ScanCoord += PincushionCurve;
|
||||
|
||||
vec2 CurveClipUnitCoord = UV * Two.xy - One.xy;
|
||||
float CurvatureClipR2 = pow(length(CurveClipUnitCoord), 2.0);
|
||||
vec2 CurvatureClipCurve = CurveClipUnitCoord * CurvatureAmount * CurvatureClipR2;
|
||||
vec2 ScreenClipCoord = UV;
|
||||
ScreenClipCoord -= Half.xy;
|
||||
ScreenClipCoord *= One.xy - CurvatureAmount * 0.2; // Warning: Magic constant
|
||||
ScreenClipCoord += Half.xy;
|
||||
ScreenClipCoord += CurvatureClipCurve;
|
||||
|
||||
if (pincushion > 0.5){
|
||||
// -- Alpha Clipping --
|
||||
if (BaseCoord.x < 0.0) return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
if (BaseCoord.y < 0.0) return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
if (BaseCoord.x > 1.0) return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
if (BaseCoord.y > 1.0) return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// -- Scanline Simulation --
|
||||
float InnerSine = ScanCoord.y * sourceSize[0].y * ScanlineScale;
|
||||
float ScanBrightMod = sin(InnerSine * Pi + ScanlineOffset * sourceSize[0].y);
|
||||
float ScanBrightness = mix(1.0, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0) * 0.5, scandark);
|
||||
vec3 ScanlineTexel = InTexel.rgb * ScanBrightness;
|
||||
|
||||
// -- Color Compression (increasing the floor of the signal without affecting the ceiling) --
|
||||
ScanlineTexel = Floor + (One.xyz - Floor) * ScanlineTexel;
|
||||
if (scanlines > 0.5) return vec4(ScanlineTexel, 1.0);
|
||||
else return vec4(InTexel);
|
||||
}
|
||||
|
||||
vec4 SixtyHertz(vec2 UV)
|
||||
{
|
||||
vec4 InPixel = ScanlinePincushion(UV);
|
||||
float Milliseconds = float(phase) * 15.0;
|
||||
float TimeStep = fract(Milliseconds * SixtyHertzRate);
|
||||
float BarPosition = 1.0 - fract(-UV.y + TimeStep) * SixtyHertzScale;
|
||||
vec4 OutPixel = InPixel * BarPosition;
|
||||
if (hertzroll > 0.5) return OutPixel;
|
||||
else return InPixel;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 OutPixel = SixtyHertz(vTexCoord.xy);
|
||||
FragColor = OutPixel;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
uniform vec4 targetSize;
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
input
|
||||
filter: linear
|
||||
|
||||
program
|
||||
filter: linear
|
||||
height: 100%
|
||||
width: 100%
|
||||
vertex: mame-ntsc.vs
|
||||
fragment: mame-ntsc.fs
|
||||
|
||||
program
|
||||
filter: linear
|
||||
modulo: 270.0
|
||||
vertex: mame-postproc.vs
|
||||
fragment: mame-postproc.fs
|
||||
|
||||
output
|
||||
height: 0
|
||||
width: 0
|
||||
filter: linear
|
|
@ -1,48 +0,0 @@
|
|||
// Gaussian Scanlines
|
||||
//
|
||||
// adapted from NTSC Shader - written by Hans-Kristian Arntzen
|
||||
// License: GPLv3
|
||||
// pulled from git://github.com/libretro/common-shaders.git on 08/05/2013
|
||||
|
||||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
uniform int phase;
|
||||
|
||||
#define DISPLAY_GAMMA 2.1
|
||||
#define CRT_GAMMA 2.5
|
||||
#define one (sourceSize[0]) //this is set to 1.0 / sourceSize[0] in the original version, but I think this looks better
|
||||
#define pix_no texCoord.y * sourceSize[0]
|
||||
#define TEX(off) pow(texture(source[0], texCoord - vec2(0.0, (off) * one.y)).rgb, vec3(CRT_GAMMA))
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 frame0 = TEX(-2.0);
|
||||
vec3 frame1 = TEX(-1.0);
|
||||
vec3 frame2 = TEX(0.0);
|
||||
vec3 frame3 = TEX(1.0);
|
||||
vec3 frame4 = TEX(2.0);
|
||||
|
||||
float offset_dist = fract(pix_no.y) - 0.5;
|
||||
float dist0 = 2.0 + offset_dist;
|
||||
float dist1 = 1.0 + offset_dist;
|
||||
float dist2 = 0.0 + offset_dist;
|
||||
float dist3 = -1.0 + offset_dist;
|
||||
float dist4 = -2.0 + offset_dist;
|
||||
|
||||
vec3 scanline = frame0 * exp(-5.0 * dist0 * dist0);
|
||||
scanline += frame1 * exp(-5.0 * dist1 * dist1);
|
||||
scanline += frame2 * exp(-5.0 * dist2 * dist2);
|
||||
scanline += frame3 * exp(-5.0 * dist3 * dist3);
|
||||
scanline += frame4 * exp(-5.0 * dist4 * dist4);
|
||||
|
||||
fragColor = vec4(pow(1.15 * scanline, vec3(1.0 / DISPLAY_GAMMA)), 1.0);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
input
|
||||
filter: nearest
|
||||
format: rgba16f
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
format: rgba16f
|
||||
width: 400%
|
||||
height: 100%
|
||||
modulo: 2
|
||||
fragment: ntsc-pass1.fs
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
format: rgba16f
|
||||
width: 50%
|
||||
height: 100%
|
||||
fragment: ntsc-pass2.fs
|
||||
|
||||
program
|
||||
filter: linear
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
output
|
||||
filter: nearest
|
|
@ -1,103 +0,0 @@
|
|||
// NTSC Shader - written by Hans-Kristian Arntzen
|
||||
// License: GPLv3
|
||||
// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014
|
||||
|
||||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
uniform int phase;
|
||||
|
||||
// uniforms added for compatibility
|
||||
out vec3 col;
|
||||
out float mod_phase;
|
||||
out float chroma_phase;
|
||||
|
||||
#define THREE_PHASE
|
||||
#define COMPOSITE
|
||||
|
||||
// #include "ntsc-param.inc" //
|
||||
#define PI 3.14159265
|
||||
|
||||
#if defined(TWO_PHASE)
|
||||
#define CHROMA_MOD_FREQ (4.0 * PI / 15.0)
|
||||
#elif defined(THREE_PHASE)
|
||||
#define CHROMA_MOD_FREQ (PI / 3.0)
|
||||
#endif
|
||||
|
||||
#if defined(COMPOSITE)
|
||||
#define SATURATION 1.0
|
||||
#define BRIGHTNESS 1.0
|
||||
#define ARTIFACTING 1.0
|
||||
#define FRINGING 1.0
|
||||
#elif defined(SVIDEO)
|
||||
#define SATURATION 1.0
|
||||
#define BRIGHTNESS 1.0
|
||||
#define ARTIFACTING 0.0
|
||||
#define FRINGING 0.0
|
||||
#endif
|
||||
|
||||
#if defined(COMPOSITE) || defined(SVIDEO)
|
||||
mat3 mix_mat = mat3(
|
||||
BRIGHTNESS, FRINGING, FRINGING,
|
||||
ARTIFACTING, 2.0 * SATURATION, 0.0,
|
||||
ARTIFACTING, 0.0, 2.0 * SATURATION
|
||||
);
|
||||
#endif
|
||||
// END "ntsc-param.inc" //
|
||||
|
||||
// moved from vertex
|
||||
#define pix_no (texCoord.xy * sourceSize[0].xy * (targetSize.xy / sourceSize[0].xy))
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
mat3 yiq2rgb_mat = mat3(
|
||||
1.0, 1.0, 1.0,
|
||||
0.956, -0.2720, -1.1060,
|
||||
0.6210, -0.6474, 1.7046
|
||||
);
|
||||
|
||||
vec3 yiq2rgb(vec3 yiq)
|
||||
{
|
||||
return (yiq * yiq2rgb_mat);
|
||||
}
|
||||
|
||||
mat3 yiq_mat = mat3(
|
||||
0.2989, 0.5959, 0.2115,
|
||||
0.5870, -0.2744, -0.5229,
|
||||
0.1140, -0.3216, 0.3114
|
||||
);
|
||||
|
||||
vec3 rgb2yiq(vec3 col)
|
||||
{
|
||||
return (col * yiq_mat);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// #include "ntsc-pass1-encode-demodulate.inc" //
|
||||
vec3 col = texture(source[0], texCoord).rgb;
|
||||
vec3 yiq = rgb2yiq(col);
|
||||
|
||||
#if defined(TWO_PHASE)
|
||||
float chroma_phase = PI * (mod(pix_no.y, 2.0) + phase);
|
||||
#elif defined(THREE_PHASE)
|
||||
float chroma_phase = 0.6667 * PI * (mod(pix_no.y, 3.0) + phase);
|
||||
#endif
|
||||
|
||||
float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ;
|
||||
|
||||
float i_mod = cos(mod_phase);
|
||||
float q_mod = sin(mod_phase);
|
||||
|
||||
yiq.yz *= vec2(i_mod, q_mod); // Modulate
|
||||
yiq *= mix_mat; // Cross-talk
|
||||
yiq.yz *= vec2(i_mod, q_mod); // Demodulate
|
||||
|
||||
fragColor = vec4(yiq, 1.0);
|
||||
// END "ntsc-pass1-encode-demodulate.inc" //
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
// NTSC Shader - written by Hans-Kristian Arntzen
|
||||
// License: GPLv3
|
||||
// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014
|
||||
|
||||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
|
||||
#define THREE_PHASE //options here include THREE_PHASE, TWO_PHASE or OLD_THREE_PHASE
|
||||
#define GAMMA_CORRECTION //comment to disable gamma correction, usually because higan's gamma correction is enabled or you have another shader already doing it
|
||||
#define CRT_GAMMA 2.5
|
||||
#define DISPLAY_GAMMA 2.1
|
||||
|
||||
#if defined OLD_THREE_PHASE
|
||||
#define TAPS 24
|
||||
const float luma_filter[TAPS + 1] = float[TAPS + 1](
|
||||
-0.000071070,
|
||||
-0.000032816,
|
||||
0.000128784,
|
||||
0.000134711,
|
||||
-0.000226705,
|
||||
-0.000777988,
|
||||
-0.000997809,
|
||||
-0.000522802,
|
||||
0.000344691,
|
||||
0.000768930,
|
||||
0.000275591,
|
||||
-0.000373434,
|
||||
0.000522796,
|
||||
0.003813817,
|
||||
0.007502825,
|
||||
0.006786001,
|
||||
-0.002636726,
|
||||
-0.019461182,
|
||||
-0.033792479,
|
||||
-0.029921972,
|
||||
0.005032552,
|
||||
0.071226466,
|
||||
0.151755921,
|
||||
0.218166470,
|
||||
0.243902439);
|
||||
|
||||
const float chroma_filter[TAPS + 1] = float[TAPS + 1](
|
||||
0.001845562,
|
||||
0.002381606,
|
||||
0.003040177,
|
||||
0.003838976,
|
||||
0.004795341,
|
||||
0.005925312,
|
||||
0.007242534,
|
||||
0.008757043,
|
||||
0.010473987,
|
||||
0.012392365,
|
||||
0.014503872,
|
||||
0.016791957,
|
||||
0.019231195,
|
||||
0.021787070,
|
||||
0.024416251,
|
||||
0.027067414,
|
||||
0.029682613,
|
||||
0.032199202,
|
||||
0.034552198,
|
||||
0.036677005,
|
||||
0.038512317,
|
||||
0.040003044,
|
||||
0.041103048,
|
||||
0.041777517,
|
||||
0.042004791);
|
||||
#endif
|
||||
|
||||
#if defined(THREE_PHASE)
|
||||
// #include "ntsc-decode-filter-3phase.inc" //
|
||||
#define TAPS 24
|
||||
const float luma_filter[TAPS + 1] = float[TAPS + 1](
|
||||
-0.000012020,
|
||||
-0.000022146,
|
||||
-0.000013155,
|
||||
-0.000012020,
|
||||
-0.000049979,
|
||||
-0.000113940,
|
||||
-0.000122150,
|
||||
-0.000005612,
|
||||
0.000170516,
|
||||
0.000237199,
|
||||
0.000169640,
|
||||
0.000285688,
|
||||
0.000984574,
|
||||
0.002018683,
|
||||
0.002002275,
|
||||
-0.000909882,
|
||||
-0.007049081,
|
||||
-0.013222860,
|
||||
-0.012606931,
|
||||
0.002460860,
|
||||
0.035868225,
|
||||
0.084016453,
|
||||
0.135563500,
|
||||
0.175261268,
|
||||
0.190176552);
|
||||
|
||||
const float chroma_filter[TAPS + 1] = float[TAPS + 1](
|
||||
-0.000118847,
|
||||
-0.000271306,
|
||||
-0.000502642,
|
||||
-0.000930833,
|
||||
-0.001451013,
|
||||
-0.002064744,
|
||||
-0.002700432,
|
||||
-0.003241276,
|
||||
-0.003524948,
|
||||
-0.003350284,
|
||||
-0.002491729,
|
||||
-0.000721149,
|
||||
0.002164659,
|
||||
0.006313635,
|
||||
0.011789103,
|
||||
0.018545660,
|
||||
0.026414396,
|
||||
0.035100710,
|
||||
0.044196567,
|
||||
0.053207202,
|
||||
0.061590275,
|
||||
0.068803602,
|
||||
0.074356193,
|
||||
0.077856564,
|
||||
0.079052396);
|
||||
// END "ntsc-decode-filter-3phase.inc" //
|
||||
|
||||
#elif defined(TWO_PHASE)
|
||||
// #include "ntsc-decode-filter-3phase.inc" //
|
||||
#define TAPS 24
|
||||
const float luma_filter[TAPS + 1] = float[TAPS + 1](
|
||||
-0.000012020,
|
||||
-0.000022146,
|
||||
-0.000013155,
|
||||
-0.000012020,
|
||||
-0.000049979,
|
||||
-0.000113940,
|
||||
-0.000122150,
|
||||
-0.000005612,
|
||||
0.000170516,
|
||||
0.000237199,
|
||||
0.000169640,
|
||||
0.000285688,
|
||||
0.000984574,
|
||||
0.002018683,
|
||||
0.002002275,
|
||||
-0.000909882,
|
||||
-0.007049081,
|
||||
-0.013222860,
|
||||
-0.012606931,
|
||||
0.002460860,
|
||||
0.035868225,
|
||||
0.084016453,
|
||||
0.135563500,
|
||||
0.175261268,
|
||||
0.190176552);
|
||||
|
||||
const float chroma_filter[TAPS + 1] = float[TAPS + 1](
|
||||
-0.000118847,
|
||||
-0.000271306,
|
||||
-0.000502642,
|
||||
-0.000930833,
|
||||
-0.001451013,
|
||||
-0.002064744,
|
||||
-0.002700432,
|
||||
-0.003241276,
|
||||
-0.003524948,
|
||||
-0.003350284,
|
||||
-0.002491729,
|
||||
-0.000721149,
|
||||
0.002164659,
|
||||
0.006313635,
|
||||
0.011789103,
|
||||
0.018545660,
|
||||
0.026414396,
|
||||
0.035100710,
|
||||
0.044196567,
|
||||
0.053207202,
|
||||
0.061590275,
|
||||
0.068803602,
|
||||
0.074356193,
|
||||
0.077856564,
|
||||
0.079052396);
|
||||
// END "ntsc-decode-filter-3phase.inc" //
|
||||
#endif
|
||||
|
||||
// #include ntsc-rgbyuv.inc //
|
||||
mat3 yiq2rgb_mat = mat3(
|
||||
1.0, 1.0, 1.0,
|
||||
0.956, -0.2720, -1.1060,
|
||||
0.6210, -0.6474, 1.7046
|
||||
);
|
||||
|
||||
vec3 yiq2rgb(vec3 yiq)
|
||||
{
|
||||
return (yiq * yiq2rgb_mat);
|
||||
}
|
||||
|
||||
mat3 yiq_mat = mat3(
|
||||
0.2989, 0.5959, 0.2115,
|
||||
0.5870, -0.2744, -0.5229,
|
||||
0.1140, -0.3216, 0.3114
|
||||
);
|
||||
|
||||
vec3 rgb2yiq(vec3 col)
|
||||
{
|
||||
return (col * yiq_mat);
|
||||
}
|
||||
// END ntsc-rgbyuv.inc //
|
||||
|
||||
// fixCoord moved from vertex
|
||||
#define fixCoord (texCoord - vec2(0.5 / sourceSize[0].x, 0.0)) // Compensate for decimate-by-2.
|
||||
|
||||
#define fetch_offset(offset, one_x) \
|
||||
texture(source[0], fixCoord + vec2((offset) * (one_x), 0.0)).xyz
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
// #include "ntsc-pass2-decode.inc" //
|
||||
float one_x = 1.0 / sourceSize[0].x;
|
||||
vec3 signal = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < TAPS; i++)
|
||||
{
|
||||
float offset = float(i);
|
||||
vec3 sums = fetch_offset(offset - float(TAPS), one_x) +
|
||||
fetch_offset(float(TAPS) - offset, one_x);
|
||||
|
||||
signal += sums * vec3(luma_filter[i], chroma_filter[i], chroma_filter[i]);
|
||||
}
|
||||
|
||||
signal += texture(source[0], fixCoord).xyz * vec3(luma_filter[TAPS], chroma_filter[TAPS], chroma_filter[TAPS]);
|
||||
|
||||
// END "ntsc-pass2-decode.inc" //
|
||||
|
||||
vec3 rgb = yiq2rgb(signal);
|
||||
|
||||
#ifdef GAMMA_CORRECTION
|
||||
vec3 gamma = vec3(CRT_GAMMA / DISPLAY_GAMMA);
|
||||
rgb = pow(rgb, gamma.rgb);
|
||||
#endif
|
||||
|
||||
fragColor = vec4(rgb, 1.0);
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
input
|
||||
filter: nearest
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
height: 100%
|
||||
fragment: pal-r57shell.fs
|
||||
|
||||
output
|
||||
height: 0
|
||||
filter: linear
|
|
@ -1,368 +0,0 @@
|
|||
#version 150
|
||||
|
||||
// NES PAL composite signal simulation for RetroArch
|
||||
// shader by r57shell
|
||||
// thanks to feos & HardWareMan & NewRisingSun
|
||||
|
||||
// also TV subpixels and scanlines
|
||||
|
||||
// LICENSE: PUBLIC DOMAIN
|
||||
|
||||
// NOTE: for nice TV subpixels and scanlines I recommend to
|
||||
// disable this features here and apply CRT-specialized shader.
|
||||
|
||||
// Quality considerations
|
||||
|
||||
// there are three main options:
|
||||
// USE_RAW (R), USE_DELAY_LINE (D), USE_COLORIMETRY (C)
|
||||
// here is table of quality in decreasing order:
|
||||
// RDC, RD, RC, DC, D, C
|
||||
|
||||
// compatibility macros
|
||||
#define float2 vec2
|
||||
#define float3 vec3
|
||||
#define float4 vec4
|
||||
#define frac(c) fract(c)
|
||||
#define saturate(c) clamp(c, 0.0, 1.0)
|
||||
#define fmod(x,y) mod(x,y)
|
||||
#define mul(x,y) (y*x)
|
||||
#define float2x2 mat2
|
||||
#define float3x3 mat3
|
||||
#define float4x4 mat4
|
||||
#define bool2 bvec2
|
||||
#define bool3 bvec3
|
||||
#define bool4 bvec4
|
||||
#define static
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 outputSize;
|
||||
uniform int phase;
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// TWEAKS start
|
||||
|
||||
// use delay line technique
|
||||
// without delay line technique, color would interleave
|
||||
// to avoid this, set HueRotation to zero.
|
||||
#define USE_DELAY_LINE
|
||||
|
||||
// use this if you need to swap even/odd V sign.
|
||||
// sign of V changes each scanline
|
||||
// so if some scanline is positive, then next is negative
|
||||
// and if you want to match picture
|
||||
// to actual running PAL NES on TV
|
||||
// you may want to have this option, to change signs
|
||||
// if they don't match
|
||||
//#define SWAP_VSIGN
|
||||
|
||||
// rough simulation of scanlines
|
||||
// better if you use additional shader instead
|
||||
// if you still use it, make sure that SizeY
|
||||
// is at least twice lower than output height
|
||||
#define USE_SCANLINES // FIXME: scanlines are broken and I'm too lazy to fix it right now
|
||||
|
||||
// to change gamma of virtual TV from 2.2 to something else
|
||||
#define USE_GAMMA
|
||||
|
||||
// use sampled version. it's much more slower version of shader.
|
||||
// because it is computing x4 more values. NOT RECOMMENDED.
|
||||
//#define USE_SAMPLED
|
||||
|
||||
#ifndef PARAMETER_UNIFORM
|
||||
// NTSC standard gamma = 2.2
|
||||
// PAL standard gamma = 2.8
|
||||
// according to many sources, very unlikely gamma of TV is 2.8
|
||||
// most likely gamma of PAL TV is in range 2.4-2.5
|
||||
const float Gamma_static = 2.8; // gamma of virtual TV
|
||||
|
||||
const float Brightness_static = 0.25;
|
||||
const float Contrast_static = 1.1;
|
||||
const float Saturation_static = 1.1;
|
||||
|
||||
const int
|
||||
Ywidth_static = 12,
|
||||
Uwidth_static = 23,
|
||||
Vwidth_static = 23;
|
||||
|
||||
#define Brightness Brightness_static
|
||||
#define Gamma Gamma_static
|
||||
|
||||
#define Ywidth Ywidth_static
|
||||
#define Uwidth Uwidth_static
|
||||
#define Vwidth Vwidth_static
|
||||
|
||||
#define SCANLINE_MUL (sw.x*dark_scanline+sw.y)
|
||||
|
||||
int Mwidth = int(max(float(Ywidth), max(float(Uwidth), float(Vwidth))));
|
||||
|
||||
// correct one is -2.5
|
||||
// works only with USE_RAW
|
||||
const float HueShift = -2.5;
|
||||
|
||||
// rotation of hue due to luma level.
|
||||
const float HueRotation = 2.;
|
||||
|
||||
// touch this only if you know what you doing
|
||||
const float Phase_Y = 2.; // fmod(341*10,12)
|
||||
const float Phase_One = 0.; // alternating phases.
|
||||
const float Phase_Two = 8.;
|
||||
|
||||
// screen size, scanlines = y*2; y one field, and y other field.
|
||||
const int SizeX = 256;
|
||||
const int SizeY = 240;
|
||||
|
||||
// count of pixels of virtual TV.
|
||||
// value close to 1000 produce small artifacts
|
||||
const int TV_Pixels = 400;
|
||||
|
||||
const float dark_scanline = 0.5; // half
|
||||
#endif
|
||||
|
||||
// this is using following matrixes.
|
||||
// it provides more scientific approach
|
||||
// by conversion into linear XYZ space
|
||||
// and back to sRGB.
|
||||
// it's using Gamma setting too.
|
||||
// define USE_GAMMA is not required.
|
||||
#define USE_COLORIMETRY
|
||||
|
||||
const float3x3 RGB_to_XYZ =
|
||||
mat3(
|
||||
0.4306190, 0.3415419, 0.1783091,
|
||||
0.2220379, 0.7066384, 0.0713236,
|
||||
0.0201853, 0.1295504, 0.9390944
|
||||
);
|
||||
|
||||
const float3x3 XYZ_to_sRGB =
|
||||
mat3(
|
||||
3.2406, -1.5372, -0.4986,
|
||||
-0.9689, 1.8758, 0.0415,
|
||||
0.0557, -0.2040, 1.0570
|
||||
);
|
||||
|
||||
// TWEAKS end
|
||||
|
||||
const float YUV_u = 0.492;
|
||||
const float YUV_v = 0.877;
|
||||
|
||||
const mat3 RGB_to_YUV =
|
||||
mat3(
|
||||
float3( 0.299, 0.587, 0.114), //Y
|
||||
float3(-0.299,-0.587, 0.886)*YUV_u, //B-Y
|
||||
float3( 0.701,-0.587,-0.114)*YUV_v //R-Y
|
||||
);
|
||||
|
||||
#ifdef USE_DELAY_LINE
|
||||
const float comb_line = 1.;
|
||||
#else
|
||||
const float comb_line = 2.;
|
||||
#endif
|
||||
|
||||
static const float Voltage_0 = 0.518;
|
||||
static const float Voltage_1 = 1.962;
|
||||
static const float DeltaV = (Voltage_1-Voltage_0);
|
||||
|
||||
float RGB_y = Contrast_static/Ywidth_static/DeltaV;
|
||||
float RGB_u = comb_line*Contrast_static*Saturation_static/YUV_u/Uwidth_static/DeltaV;
|
||||
float RGB_v = comb_line*Contrast_static*Saturation_static/YUV_v/Vwidth_static/DeltaV;
|
||||
|
||||
mat3 YUV_to_RGB =
|
||||
mat3(
|
||||
float3(1., 1., 1.)*RGB_y,
|
||||
float3(0., -0.114/0.587, 1.)*RGB_u,
|
||||
float3(1., -0.299/0.587, 0.)*RGB_v
|
||||
);
|
||||
|
||||
const float pi = 3.1415926535897932384626433832795;
|
||||
|
||||
float sinn(float x)
|
||||
{
|
||||
return sin(/*fmod(x,24)*/x*(pi*2./24.));
|
||||
}
|
||||
|
||||
float coss(float x)
|
||||
{
|
||||
return cos(/*fmod(x,24)*/x*(pi*2./24.));
|
||||
}
|
||||
|
||||
float3 monitor(sampler2D tex, float2 p)
|
||||
{
|
||||
float2 size = sourceSize[0].xy;//float2(SizeX,SizeY);
|
||||
// align vertical coord to center of texel
|
||||
float2 uv = float2(
|
||||
|
||||
p.x,
|
||||
|
||||
(floor(p.y*sourceSize[0].y)+0.5)/sourceSize[0].y);
|
||||
#ifdef USE_DELAY_LINE
|
||||
float2 sh = (sourceSize[0].xy/sourceSize[0].xy/size)*float2(14./10.,-1.0);
|
||||
#endif
|
||||
float2 pc = uv*sourceSize[0].xy/sourceSize[0].xy*size*float2(10.,1.);
|
||||
float alpha = dot(floor(float2(pc.x,pc.y)),float2(2.,Phase_Y*2.));
|
||||
alpha += Phase_One*2.;
|
||||
|
||||
// 1/size.x of screen in uv coords = sourceSize[0].x/sourceSize[0].x/size.x;
|
||||
// then 1/10*size.x of screen:
|
||||
float ustep = sourceSize[0].x/sourceSize[0].x/size.x/10.;
|
||||
|
||||
float border = sourceSize[0].x/sourceSize[0].x;
|
||||
float ss = 2.0;
|
||||
#ifdef SWAP_VSIGN
|
||||
#define PAL_SWITCH(A) A < 1.
|
||||
#else
|
||||
#define PAL_SWITCH(A) A > 1.
|
||||
#endif
|
||||
if (PAL_SWITCH(fmod(uv.y*sourceSize[0].y/sourceSize[0].y*size.y,2.0)))
|
||||
{
|
||||
// cos(pi-alpha) = -cos(alpha)
|
||||
// sin(pi-alpha) = sin(alpha)
|
||||
// pi - alpha
|
||||
alpha = -alpha+12012.0;
|
||||
ss = -2.0;
|
||||
}
|
||||
|
||||
float ysum = 0., usum = 0., vsum = 0.;
|
||||
for (int i=0; i<Mwidth; ++i)
|
||||
{
|
||||
float4 res = texture(tex, uv);
|
||||
float3 yuv = mul(RGB_to_YUV, res.xyz);
|
||||
float a1 = alpha+(HueShift+2.5)*2.-yuv.x*ss*HueRotation;
|
||||
float sig = yuv.x+dot(yuv.yz,sign(float2(sinn(a1),coss(a1))));
|
||||
#ifdef USE_DELAY_LINE
|
||||
float4 res1 = texture(tex, uv+sh);
|
||||
float3 yuv1 = mul(RGB_to_YUV, res1.xyz);
|
||||
float a2 = (HueShift+2.5)*2.+12012.0-alpha+yuv.x*ss*HueRotation;
|
||||
float sig1 = yuv1.x+dot(yuv1.yz,sign(float2(sinn(a2),coss(a2))));
|
||||
#endif
|
||||
if (i < Ywidth)
|
||||
ysum += sig;
|
||||
|
||||
#ifdef USE_DELAY_LINE
|
||||
if (i < Uwidth)
|
||||
usum += (sig+sig1)*sinn(alpha);
|
||||
if (i < Vwidth)
|
||||
vsum += (sig-sig1)*coss(alpha);
|
||||
#else
|
||||
if (i < Uwidth)
|
||||
usum += sig*sinn(alpha);
|
||||
if (i < Vwidth)
|
||||
vsum += sig*coss(alpha);
|
||||
#endif
|
||||
alpha -= ss;
|
||||
uv.x -= ustep;
|
||||
}
|
||||
|
||||
float3 rgb = mul(float3(ysum+Brightness*Ywidth_static,usum,vsum), YUV_to_RGB);
|
||||
#if defined(USE_GAMMA) && !defined(USE_COLORIMETRY)
|
||||
float3 rgb1 = saturate(rgb);
|
||||
rgb = pow(rgb1, Gamma/2.2);
|
||||
#endif
|
||||
|
||||
#ifdef USE_COLORIMETRY
|
||||
float3 rgb1 = saturate(rgb);
|
||||
rgb = pow(rgb1, float3(Gamma, Gamma, Gamma));
|
||||
#endif
|
||||
|
||||
#if (defined(USE_SCANLINES))
|
||||
float2 q = (p*sourceSize[0].xy/sourceSize[0].xy)*float2(TV_Pixels*3.,size.y*2.);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SCANLINES
|
||||
float scanlines = size.y * outputSize.z;
|
||||
float top = fmod(q.y-0.5*scanlines*2.,2.);
|
||||
float bottom = top+frac(scanlines)*2.;
|
||||
float2 sw = saturate(min(float2(1.,2.),float2(bottom, bottom))
|
||||
-max(float2(0.,1.),float2(top)))
|
||||
+saturate(min(float2(3.,4.),float2(bottom, bottom))
|
||||
-max(float2(2.,3.),float2(top)))
|
||||
+floor(scanlines);
|
||||
|
||||
rgb = rgb*SCANLINE_MUL/(sw.x+sw.y);
|
||||
|
||||
/*
|
||||
//old stupid method
|
||||
float z =
|
||||
#ifdef ANIMATE_SCANLINE
|
||||
fmod(phase,2.0)+
|
||||
#endif
|
||||
0.5;
|
||||
|
||||
if (abs(fmod(q.y+0.5,2)-z)<0.5)
|
||||
rgb *= dark_scanline;
|
||||
*/
|
||||
#endif
|
||||
|
||||
// size of pixel screen in texture coords:
|
||||
//float output_pixel_size = sourceSize[0].x/(outputSize.x*sourceSize[0].x);
|
||||
|
||||
// correctness check
|
||||
//if (fmod(p.x*output_pixel_size,2.0) < 1.0)
|
||||
// rgb = float3(0.,0.,0.);
|
||||
|
||||
#ifdef USE_COLORIMETRY
|
||||
float3 xyz1 = mul(RGB_to_XYZ,rgb);
|
||||
float3 srgb = saturate(mul(XYZ_to_sRGB,xyz1));
|
||||
float3 a1 = 12.92*srgb;
|
||||
float3 a2 = 1.055*pow(srgb,float3(1./2.4))-0.055;
|
||||
float3 ssrgb;
|
||||
ssrgb.x = (srgb.x<0.0031308?a1.x:a2.x);
|
||||
ssrgb.y = (srgb.y<0.0031308?a1.y:a2.y);
|
||||
ssrgb.z = (srgb.z<0.0031308?a1.z:a2.z);
|
||||
return ssrgb;
|
||||
#else
|
||||
return rgb;
|
||||
#endif
|
||||
}
|
||||
|
||||
// pos (left corner, sample size)
|
||||
float4 monitor_sample(sampler2D tex, float2 p, float2 sample_)
|
||||
{
|
||||
// linear interpolation was...
|
||||
// now other thing.
|
||||
// http://imgur.com/m8Z8trV
|
||||
// AT LAST IT WORKS!!!!
|
||||
// going to check in retroarch...
|
||||
float2 size = sourceSize[0].xy;
|
||||
float2 next = float2(.25,1.)/size;
|
||||
float2 f = frac(float2(4.,1.)*size*p);
|
||||
sample_ *= float2(4.,1.)*size;
|
||||
float2 l;
|
||||
float2 r;
|
||||
if (f.x+sample_.x < 1.)
|
||||
{
|
||||
l.x = f.x+sample_.x;
|
||||
r.x = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
l.x = 1.-f.x;
|
||||
r.x = min(1.,f.x+sample_.x-1.);
|
||||
}
|
||||
if (f.y+sample_.y < 1.)
|
||||
{
|
||||
l.y = f.y+sample_.y;
|
||||
r.y = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
l.y = 1.-f.y;
|
||||
r.y = min(1.,f.y+sample_.y-1.);
|
||||
}
|
||||
float3 top = mix(monitor(tex, p), monitor(tex, p+float2(next.x,0.)), r.x/(l.x+r.x));
|
||||
float3 bottom = mix(monitor(tex, p+float2(0.,next.y)), monitor(tex, p+next), r.x/(l.x+r.x));
|
||||
return float4(mix(top,bottom, r.y/(l.y+r.y)),1.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
#ifdef USE_SAMPLED
|
||||
fragColor = vec4(monitor_sample(source[0], texCoord, outputSize.zw).rgb, 1.0);
|
||||
#else
|
||||
fragColor = float4(monitor(source[0], texCoord), 1.);
|
||||
#endif
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
program
|
||||
filter: nearest
|
||||
wrap: edge
|
||||
fragment: pixellate.fs
|
||||
|
||||
output
|
||||
filter: nearest
|
|
@ -1,40 +0,0 @@
|
|||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec2 texelSize = 1.0 * sourceSize[0].zw;
|
||||
|
||||
vec2 range = vec2(abs(dFdx(texCoord.x)), abs(dFdy(texCoord.y)));
|
||||
range = range / 2.0 * 0.999;
|
||||
|
||||
float left = texCoord.x - range.x;
|
||||
float top = texCoord.y + range.y;
|
||||
float right = texCoord.x + range.x;
|
||||
float bottom = texCoord.y - range.y;
|
||||
|
||||
vec4 topLeftColor = pow(texture(source[0], vec2(left, top)), vec4(2.2));
|
||||
vec4 bottomRightColor = pow(texture(source[0], vec2(right, bottom)), vec4(2.2));
|
||||
vec4 bottomLeftColor = pow(texture(source[0], vec2(left, bottom)), vec4(2.2));
|
||||
vec4 topRightColor = pow(texture(source[0], vec2(right, top)), vec4(2.2));
|
||||
|
||||
vec2 border = clamp(round(texCoord / texelSize) * texelSize, vec2(left, bottom), vec2(right, top));
|
||||
|
||||
float totalArea = 4.0 * range.x * range.y;
|
||||
|
||||
vec4 averageColor;
|
||||
averageColor = ((border.x - left) * (top - border.y) / totalArea) * topLeftColor;
|
||||
averageColor += ((right - border.x) * (border.y - bottom) / totalArea) * bottomRightColor;
|
||||
averageColor += ((border.x - left) * (border.y - bottom) / totalArea) * bottomLeftColor;
|
||||
averageColor += ((right - border.x) * (top - border.y) / totalArea) * topRightColor;
|
||||
|
||||
fragColor = pow(averageColor, vec4(1.0/2.2));
|
||||
}
|
1
shaders/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
See the [bsnes-shaders](https://github.com/Marat-Tanalin/bsnes-shaders) repo.
|
|
@ -1,31 +0,0 @@
|
|||
// Gamma Adjustment Shader
|
||||
// Written by Themaister - based on byuu's bsnes gamma ramp code
|
||||
|
||||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
const float saturation = 1.0;
|
||||
const float gamma = 1.0;
|
||||
const float luminance = 1.2;
|
||||
|
||||
vec3 grayscale(vec3 col)
|
||||
{
|
||||
// Non-conventional way to do grayscale,
|
||||
// but bSNES uses this as grayscale value.
|
||||
return vec3(dot(col, vec3(0.3333)));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 res = texture(source[0], texCoord).xyz;
|
||||
res = mix(grayscale(res), res, saturation); // Apply saturation
|
||||
res = pow(res, vec3(gamma)); // Apply gamma
|
||||
|
||||
fragColor = vec4(clamp(res * luminance, 0.0, 1.0), 1.0);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
program
|
||||
filter: nearest
|
||||
fragment: retro.fs
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
fragment: gamma.fs
|
||||
|
||||
output
|
||||
filter: nearest
|
||||
width: 0
|
||||
height: 0
|
|
@ -1,38 +0,0 @@
|
|||
// Retro v2 Shader
|
||||
// Written by Hyllian / Jararaca
|
||||
|
||||
#version 150
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
|
||||
// This value must be between 0.0 (totally black) and 1.0 (nearest neighbor)
|
||||
#define PIXEL_SIZE 0.64
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
out vec3 E;
|
||||
out vec2 fp;
|
||||
out vec2 ps;
|
||||
out vec2 f;
|
||||
out vec3 res;
|
||||
|
||||
void main() {
|
||||
// Reading the texel
|
||||
vec3 E = pow(texture(source[0], texCoord).xyz, vec3(2.4));
|
||||
|
||||
vec2 fp = fract(texCoord.xy * sourceSize[0].xy);
|
||||
vec2 ps = sourceSize[0].xy / targetSize.xy;
|
||||
|
||||
vec2 f = clamp(clamp(fp + 0.5*ps, 0.0, 1.0) - PIXEL_SIZE, vec2(0.0, 0.0), ps)/ps;
|
||||
|
||||
float max_coord = max(f.x, f.y);
|
||||
|
||||
vec3 res = mix(E*(1.04+fp.x*fp.y), E*0.36, max_coord);
|
||||
|
||||
fragColor = vec4(clamp( pow(res, vec3(1.0 / 2.2)), 0.0, 1.0 ), 1.0);
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#define dt vec3(1.0, 1.0, 1.0)
|
||||
|
||||
uniform sampler2D source[];
|
||||
|
||||
in vec3 c00;
|
||||
in vec3 c10;
|
||||
in vec3 c20;
|
||||
in vec3 c01;
|
||||
in vec3 c11;
|
||||
in vec3 c21;
|
||||
in vec3 c02;
|
||||
in vec3 c12;
|
||||
in vec3 c22;
|
||||
|
||||
in float d1;
|
||||
in float d2;
|
||||
in float hl;
|
||||
in float vl;
|
||||
|
||||
in float k1;
|
||||
in float k2;
|
||||
|
||||
in Vertex {
|
||||
vec2 texCoord;
|
||||
vec4 t1;
|
||||
vec4 t2;
|
||||
vec4 t3;
|
||||
vec4 t4;
|
||||
};
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec3 c00 = texture(source[0], t1.zw).xyz;
|
||||
vec3 c10 = texture(source[0], t3.xy).xyz;
|
||||
vec3 c20 = texture(source[0], t3.zw).xyz;
|
||||
vec3 c01 = texture(source[0], t1.xy).xyz;
|
||||
vec3 c11 = texture(source[0], texCoord).xyz;
|
||||
vec3 c21 = texture(source[0], t2.xy).xyz;
|
||||
vec3 c02 = texture(source[0], t2.zw).xyz;
|
||||
vec3 c12 = texture(source[0], t4.xy).xyz;
|
||||
vec3 c22 = texture(source[0], t4.zw).xyz;
|
||||
|
||||
float d1=dot(abs(c00 - c22), dt) + 0.0001;
|
||||
float d2=dot(abs(c20 - c02), dt) + 0.0001;
|
||||
float hl=dot(abs(c01 - c21), dt) + 0.0001;
|
||||
float vl=dot(abs(c10 - c12), dt) + 0.0001;
|
||||
|
||||
float k1 = 0.5 * (hl + vl);
|
||||
float k2 = 0.5 * (d1 + d2);
|
||||
|
||||
vec3 t1 = (hl * (c10 + c12) + vl * (c01 + c21) + k1 * c11) / (2.5 * (hl + vl));
|
||||
vec3 t2 = (d1 * (c20 + c02) + d2 * (c00 + c22) + k2 * c11) / (2.5 * (d1 + d2));
|
||||
|
||||
k1 = dot(abs(t1 - c11), dt) + 0.0001;
|
||||
k2 = dot(abs(t2 - c11), dt) + 0.0001;
|
||||
|
||||
fragColor = vec4((k1 * t2 + k2 * t1) / (k1 + k2), 1.0);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
in vec2 ps;
|
||||
in float dx;
|
||||
in float dy;
|
||||
|
||||
out Vertex {
|
||||
vec2 texCoord;
|
||||
vec4 t1;
|
||||
vec4 t2;
|
||||
vec4 t3;
|
||||
vec4 t4;
|
||||
} vertexOut;
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 ps = vec2(1.0/sourceSize[0].x, 1.0/sourceSize[0].y);
|
||||
float dx = ps.x * 0.5;
|
||||
float dy = ps.y * 0.5;
|
||||
|
||||
gl_Position = position;
|
||||
vertexOut.texCoord = texCoord;
|
||||
vertexOut.t1.xy = texCoord + vec2(-dx, 0);
|
||||
vertexOut.t2.xy = texCoord + vec2( dx, 0);
|
||||
vertexOut.t3.xy = texCoord + vec2( 0, -dy);
|
||||
vertexOut.t4.xy = texCoord + vec2( 0, dy);
|
||||
vertexOut.t1.zw = texCoord + vec2(-dx, -dy);
|
||||
vertexOut.t2.zw = texCoord + vec2(-dx, dy);
|
||||
vertexOut.t3.zw = texCoord + vec2( dx, -dy);
|
||||
vertexOut.t4.zw = texCoord + vec2( dx, dy);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
input
|
||||
filter: nearest
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
format: rgba16f
|
||||
width: 100%
|
||||
height: 100%
|
||||
vertex: scalefx-pass0.vs
|
||||
fragment: scalefx-pass0.fs
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
format: rgba16f
|
||||
width: 100%
|
||||
height: 100%
|
||||
vertex: scalefx-pass1.vs
|
||||
fragment: scalefx-pass1.fs
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
width: 100%
|
||||
height: 100%
|
||||
vertex: scalefx-pass2.vs
|
||||
fragment: scalefx-pass2.fs
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
width: 100%
|
||||
height: 100%
|
||||
vertex: scalefx-pass3.vs
|
||||
fragment: scalefx-pass3.fs
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
width: 300%
|
||||
height: 300%
|
||||
vertex: scalefx-pass4.vs
|
||||
fragment: scalefx-pass4.fs
|
||||
|
||||
program
|
||||
filter: nearest
|
||||
height: 200%
|
||||
width: 200%
|
||||
vertex: advanced-aa.vs
|
||||
fragment: advanced-aa.fs
|
||||
|
||||
output
|
||||
height: 0
|
||||
width: 0
|
||||
filter: linear
|
|
@ -1,83 +0,0 @@
|
|||
#version 150
|
||||
|
||||
/*
|
||||
ScaleFX - Pass 0
|
||||
by Sp00kyFox, 2017-03-01
|
||||
|
||||
Filter: Nearest
|
||||
Scale: 1x
|
||||
|
||||
ScaleFX is an edge interpolation algorithm specialized in pixel art. It was
|
||||
originally intended as an improvement upon Scale3x but became a new filter in
|
||||
its own right.
|
||||
ScaleFX interpolates edges up to level 6 and makes smooth transitions between
|
||||
different slopes. The filtered picture will only consist of colours present
|
||||
in the original.
|
||||
|
||||
Pass 0 prepares metric data for the next pass.
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2016 Sp00kyFox - ScaleFX@web.de
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
// Reference: http://www.compuphase.com/cmetric.htm
|
||||
float dist(vec3 A, vec3 B)
|
||||
{
|
||||
float r = 0.5 * (A.r + B.r);
|
||||
vec3 d = A - B;
|
||||
vec3 c = vec3(2 + r, 4, 3 - r);
|
||||
|
||||
return sqrt(dot(c*d, d)) / 3;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
/* grid metric
|
||||
|
||||
A B C x y z
|
||||
E F o w
|
||||
*/
|
||||
|
||||
|
||||
#define TEX(x, y) textureOffset(source[0], vTexCoord, ivec2(x, y)).rgb
|
||||
|
||||
// read texels
|
||||
vec3 A = TEX(-1,-1);
|
||||
vec3 B = TEX( 0,-1);
|
||||
vec3 C = TEX( 1,-1);
|
||||
vec3 E = TEX( 0, 0);
|
||||
vec3 F = TEX( 1, 0);
|
||||
|
||||
// output
|
||||
FragColor = vec4(dist(E,A), dist(E,B), dist(E,C), dist(E,F));
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
#version 150
|
||||
|
||||
/*
|
||||
ScaleFX - Pass 1
|
||||
by Sp00kyFox, 2017-03-01
|
||||
|
||||
Filter: Nearest
|
||||
Scale: 1x
|
||||
|
||||
ScaleFX is an edge interpolation algorithm specialized in pixel art. It was
|
||||
originally intended as an improvement upon Scale3x but became a new filter in
|
||||
its own right.
|
||||
ScaleFX interpolates edges up to level 6 and makes smooth transitions between
|
||||
different slopes. The filtered picture will only consist of colours present
|
||||
in the original.
|
||||
|
||||
Pass 1 calculates the strength of interpolation candidates.
|
||||
|
||||
|
||||
|
||||
Copyright (c) 2016 Sp00kyFox - ScaleFX@web.de
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#define SFX_CLR 0.5
|
||||
#define SFX_SAA 1.0
|
||||
|
||||
uniform sampler2D source[];
|
||||
uniform vec4 sourceSize[];
|
||||
uniform vec4 targetSize;
|
||||
|
||||
in Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
// corner strength
|
||||
float str(float d, vec2 a, vec2 b){
|
||||
float diff = a.x - a.y;
|
||||
float wght1 = max(SFX_CLR - d, 0) / SFX_CLR;
|
||||
float wght2 = clamp((1-d) + (min(a.x, b.x) + a.x > min(a.y, b.y) + a.y ? diff : -diff), 0, 1);
|
||||
return (SFX_SAA == 1 || 2*d < a.x + a.y) ? (wght1 * wght2) * (a.x * a.y) : 0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
/* grid metric pattern
|
||||
|
||||
A B x y z x y
|
||||
D E F o w w z
|
||||
G H I
|
||||
*/
|
||||
|
||||
|
||||
#define TEX(x, y) textureOffset(source[0], vTexCoord, ivec2(x, y))
|
||||
|
||||
// metric data
|
||||
vec4 A = TEX(-1,-1), B = TEX( 0,-1);
|
||||
vec4 D = TEX(-1, 0), E = TEX( 0, 0), F = TEX( 1, 0);
|
||||
vec4 G = TEX(-1, 1), H = TEX( 0, 1), I = TEX( 1, 1);
|
||||
|
||||
// corner strength
|
||||
vec4 res;
|
||||
res.x = str(D.z, vec2(D.w, E.y), vec2(A.w, D.y));
|
||||
res.y = str(F.x, vec2(E.w, E.y), vec2(B.w, F.y));
|
||||
res.z = str(H.z, vec2(E.w, H.y), vec2(H.w, I.y));
|
||||
res.w = str(H.x, vec2(D.w, H.y), vec2(G.w, G.y));
|
||||
|
||||
FragColor = res;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#version 150
|
||||
|
||||
in vec4 position;
|
||||
in vec2 texCoord;
|
||||
|
||||
out Vertex {
|
||||
vec2 vTexCoord;
|
||||
};
|
||||
|
||||
uniform vec4 targetSize;
|
||||
uniform vec4 sourceSize[];
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
vTexCoord = texCoord;
|
||||
}
|