mirror of
https://github.com/libretro/glsl-shaders.git
synced 2024-11-23 07:40:29 +00:00
Update NTSC-Adaptive (#184)
* remove float framebuffer flag from ntsc-adaptive * pack float framebuffer values * unpack float values * fix typo * reduce packing range * reduce packing range * bring ntsc-adaptive up-to-date with slang version
This commit is contained in:
parent
72ed75d0d5
commit
799aa9e4d5
@ -12,3 +12,4 @@ scale_type1 = source
|
||||
scale_x1 = 0.5
|
||||
scale_y1 = 1.0
|
||||
filter_linear1 = false
|
||||
wrap_mode1 = mirrored_repeat
|
||||
|
@ -3,8 +3,16 @@
|
||||
// NTSC-Adaptive
|
||||
// based on Themaister's NTSC shader
|
||||
|
||||
#pragma parameter quality "Quality (Composite = 0, Svideo = 1)" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter bw "Black and White" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter quality "NTSC Preset (Svideo=0 Composite=1 RF=2 Custom=-1)" 1.0 -1.0 2.0 1.0
|
||||
#pragma parameter ntsc_fields "NTSC Merge Fields" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter ntsc_phase "NTSC Phase: Auto | 2 phase | 3 phase" 1.0 1.0 3.0 1.0
|
||||
#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 3.0 0.05
|
||||
#pragma parameter ntsc_sat "NTSC Color Saturation" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter ntsc_bright "NTSC Brightness" 1.0 0.0 1.5 0.01
|
||||
#pragma parameter cust_fringing "NTSC Custom Fringing Value" 0.0 0.0 5.0 0.1
|
||||
#pragma parameter cust_artifacting "NTSC Custom Artifacting Value" 0.0 0.0 5.0 0.1
|
||||
|
||||
#define PI 3.14159265
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
@ -28,6 +36,13 @@ COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
COMPAT_VARYING vec2 pix_no;
|
||||
COMPAT_VARYING float phase;
|
||||
COMPAT_VARYING float BRIGHTNESS;
|
||||
COMPAT_VARYING float SATURATION;
|
||||
COMPAT_VARYING float FRINGING;
|
||||
COMPAT_VARYING float ARTIFACTING;
|
||||
COMPAT_VARYING float CHROMA_MOD_FREQ;
|
||||
COMPAT_VARYING float MERGE;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
@ -35,17 +50,47 @@ uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform COMPAT_PRECISION vec2 OrigInputSize;
|
||||
|
||||
// compatibility #defines
|
||||
#define vTexCoord TEX0.xy
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform COMPAT_PRECISION float quality, ntsc_sat, cust_fringing, cust_artifacting, ntsc_bright, ntsc_scale, ntsc_fields, ntsc_phase;
|
||||
#else
|
||||
#define ntsc_fields 0.0
|
||||
#define ntsc_phase 1.0
|
||||
#define ntsc_sat 1.0
|
||||
#define ntsc_bright 1.0
|
||||
#define cust_fringing 0.0
|
||||
#define cust_artifacting 0.0
|
||||
#define quality 0.0
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
float res = ntsc_scale;
|
||||
float OriginalSize = OrigInputSize.x;
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
TEX0.xy = TexCoord.xy;
|
||||
if (res < 1.0) pix_no = vTexCoord * SourceSize.xy * (res * OutSize.xy / InputSize.xy);
|
||||
else
|
||||
pix_no = vTexCoord * SourceSize.xy * ( OutSize.xy / InputSize.xy);
|
||||
pix_no = vTexCoord * SourceSize.xy * (OutSize.xy / InputSize.xy);
|
||||
phase = (ntsc_phase < 1.5) ? ((OriginalSize > 300.0) ? 2.0 : 3.0) : ((ntsc_phase > 2.5) ? 3.0 : 2.0);
|
||||
|
||||
res = max(res, 1.0);
|
||||
CHROMA_MOD_FREQ = (phase < 2.5) ? (4.0 * PI / 15.0) : (PI / 3.0);
|
||||
ARTIFACTING = (quality > -0.5) ? quality * 0.5*(res+1.0) : cust_artifacting;
|
||||
FRINGING = (quality > -0.5) ? quality : cust_fringing;
|
||||
SATURATION = ntsc_sat;
|
||||
BRIGHTNESS = ntsc_bright;
|
||||
pix_no.x = pix_no.x * res;
|
||||
|
||||
MERGE = (int(quality) == 2 || phase < 2.5) ? 0.0 : 1.0;
|
||||
MERGE = (int(quality) == -1) ? ntsc_fields : MERGE;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
@ -80,6 +125,13 @@ uniform COMPAT_PRECISION vec2 OrigInputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
COMPAT_VARYING vec2 pix_no;
|
||||
COMPAT_VARYING float phase;
|
||||
COMPAT_VARYING float BRIGHTNESS;
|
||||
COMPAT_VARYING float SATURATION;
|
||||
COMPAT_VARYING float FRINGING;
|
||||
COMPAT_VARYING float ARTIFACTING;
|
||||
COMPAT_VARYING float CHROMA_MOD_FREQ;
|
||||
COMPAT_VARYING float MERGE;
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
@ -89,16 +141,18 @@ COMPAT_VARYING vec2 pix_no;
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform COMPAT_PRECISION float quality;
|
||||
uniform COMPAT_PRECISION float bw;
|
||||
uniform COMPAT_PRECISION float quality, ntsc_sat, cust_fringing, cust_artifacting, ntsc_bright, ntsc_scale, ntsc_fields, ntsc_phase;
|
||||
#else
|
||||
#define ntsc_fields 0.0
|
||||
#define ntsc_phase 1.0
|
||||
#define ntsc_sat 1.0
|
||||
#define ntsc_bright 1.0
|
||||
#define cust_fringing 0.0
|
||||
#define cust_artifacting 0.0
|
||||
#define quality 0.0
|
||||
#define bw 0.0
|
||||
#endif
|
||||
|
||||
#define PI 3.14159265
|
||||
float phase = (OrigInputSize.x > 300.0) ? 2.0 : 3.0;
|
||||
|
||||
|
||||
#define mix_mat mat3(BRIGHTNESS, FRINGING, FRINGING, ARTIFACTING, 2.0 * SATURATION, 0.0, ARTIFACTING, 0.0, 2.0 * SATURATION)
|
||||
|
||||
@ -123,19 +177,32 @@ vec3 rgb2yiq(vec3 col)
|
||||
return col * yiq_mat;
|
||||
}
|
||||
|
||||
vec4 pack_float(vec4 color)
|
||||
{
|
||||
return ((color * 10.0) - 1.0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float CHROMA_MOD_FREQ = (phase < 2.5) ? (4.0 * PI / 15.0) : (PI / 3.0);
|
||||
float ARTIFACTING = 1.0 - quality;
|
||||
float FRINGING = 1.0 - quality;
|
||||
float SATURATION = 1.0 - bw;
|
||||
// prevent some very slight clipping that happens at 1.0
|
||||
const float BRIGHTNESS = 0.95;
|
||||
vec3 col = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
||||
vec3 yiq = rgb2yiq(col);
|
||||
vec3 yiq2 = yiq;
|
||||
|
||||
float chroma_phase = (phase < 2.5) ? PI * (mod(pix_no.y, 2.0) + mod(float(FrameCount), 2.)) : 0.6667 * PI * (mod(pix_no.y, 3.0) + mod(float(FrameCount), 2.));
|
||||
float mod1 = 2.0;
|
||||
float mod2 = 3.0;
|
||||
|
||||
if (MERGE > 0.5)
|
||||
{
|
||||
float chroma_phase2 = (phase < 2.5) ? PI * (mod(pix_no.y, mod1) + mod(FrameCount+1, 2.)) : 0.6667 * PI * (mod(pix_no.y, mod2) + mod(FrameCount+1, 2.));
|
||||
float mod_phase2 = chroma_phase2 + pix_no.x * CHROMA_MOD_FREQ;
|
||||
float i_mod2 = cos(mod_phase2);
|
||||
float q_mod2 = sin(mod_phase2);
|
||||
yiq2.yz *= vec2(i_mod2, q_mod2); // Modulate.
|
||||
yiq2 *= mix_mat; // Cross-talk.
|
||||
yiq2.yz *= vec2(i_mod2, q_mod2); // Demodulate.
|
||||
}
|
||||
|
||||
float chroma_phase = (phase < 2.5) ? PI * (mod(pix_no.y, mod1) + mod(FrameCount, 2.)) : 0.6667 * PI * (mod(pix_no.y, mod2) + mod(FrameCount, 2.));
|
||||
float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ;
|
||||
|
||||
float i_mod = cos(mod_phase);
|
||||
@ -144,6 +211,12 @@ void main()
|
||||
yiq.yz *= vec2(i_mod, q_mod); // Modulate.
|
||||
yiq *= mix_mat; // Cross-talk.
|
||||
yiq.yz *= vec2(i_mod, q_mod); // Demodulate.
|
||||
|
||||
yiq = (MERGE < 0.5) ? yiq : 0.5*(yiq+yiq2);
|
||||
|
||||
FragColor = vec4(yiq, 1.0);
|
||||
#ifdef GL_ES
|
||||
FragColor = pack_float(FragColor);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -5,8 +5,13 @@
|
||||
|
||||
#pragma parameter linearize "Linearize Output Gamma" 0.0 0.0 1.0 1.0
|
||||
|
||||
#ifdef GL_ES
|
||||
#define fetch_offset(offset, one_x) \
|
||||
unpack_float(COMPAT_TEXTURE(Source, vTexCoord + vec2((offset) * (one_x), 0.0)).xyz)
|
||||
#else
|
||||
#define fetch_offset(offset, one_x) \
|
||||
COMPAT_TEXTURE(Source, vTexCoord + vec2((offset) * (one_x), 0.0)).xyz
|
||||
#endif
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
@ -88,11 +93,18 @@ COMPAT_VARYING vec4 TEX0;
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform COMPAT_PRECISION float linearize;
|
||||
uniform COMPAT_PRECISION float linearize, ntsc_scale, ntsc_phase;
|
||||
#else
|
||||
#define linearize 0.0
|
||||
#define ntsc_scale 1.0
|
||||
#define ntsc_phase 1.0
|
||||
#endif
|
||||
|
||||
vec3 unpack_float(vec3 color)
|
||||
{
|
||||
return (color + 1.0) / 10.0;
|
||||
}
|
||||
|
||||
const mat3 yiq2rgb_mat = mat3(
|
||||
1.0, 0.956, 0.6210,
|
||||
1.0, -0.2720, -0.6474,
|
||||
@ -242,22 +254,86 @@ const float chroma_filter_3_phase[25] = float[25](
|
||||
|
||||
void main()
|
||||
{
|
||||
float phase = (OrigInputSize.x > 300.0) ? 2.0 : 3.0;
|
||||
float one_x = SourceSize.z;
|
||||
float res = ntsc_scale;
|
||||
float OriginalSize = OrigInputSize.x;
|
||||
float phase = (ntsc_phase < 1.5) ? ((OriginalSize > 300.0) ? 2.0 : 3.0) : ((ntsc_phase > 2.5) ? 3.0 : 2.0);
|
||||
float one_x = SourceSize.z / res;
|
||||
vec3 signal = vec3(0.0);
|
||||
|
||||
if(phase < 2.5)
|
||||
{
|
||||
for (int i = 0; i < TAPS_2_phase; i++)
|
||||
{
|
||||
float offset = float(i);
|
||||
vec3 sums = fetch_offset(0.0 - 32.0, one_x) + fetch_offset(32.0 - 0.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[0], chroma_filter_2_phase[0], chroma_filter_2_phase[0]);
|
||||
sums = fetch_offset(1.0 - 32.0, one_x) + fetch_offset(32.0 - 1.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[1], chroma_filter_2_phase[1], chroma_filter_2_phase[1]);
|
||||
sums = fetch_offset(2.0 - 32.0, one_x) + fetch_offset(32.0 - 2.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[2], chroma_filter_2_phase[2], chroma_filter_2_phase[2]);
|
||||
sums = fetch_offset(3.0 - 32.0, one_x) + fetch_offset(32.0 - 3.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[3], chroma_filter_2_phase[3], chroma_filter_2_phase[3]);
|
||||
sums = fetch_offset(4.0 - 32.0, one_x) + fetch_offset(32.0 - 4.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[4], chroma_filter_2_phase[4], chroma_filter_2_phase[4]);
|
||||
sums = fetch_offset(5.0 - 32.0, one_x) + fetch_offset(32.0 - 5.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[5], chroma_filter_2_phase[5], chroma_filter_2_phase[5]);
|
||||
sums = fetch_offset(6.0 - 32.0, one_x) + fetch_offset(32.0 - 6.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[6], chroma_filter_2_phase[6], chroma_filter_2_phase[6]);
|
||||
sums = fetch_offset(7.0 - 32.0, one_x) + fetch_offset(32.0 - 7.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[7], chroma_filter_2_phase[7], chroma_filter_2_phase[7]);
|
||||
sums = fetch_offset(8.0 - 32.0, one_x) + fetch_offset(32.0 - 8.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[8], chroma_filter_2_phase[8], chroma_filter_2_phase[8]);
|
||||
sums = fetch_offset(9.0 - 32.0, one_x) + fetch_offset(32.0 - 9.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[9], chroma_filter_2_phase[9], chroma_filter_2_phase[9]);
|
||||
sums = fetch_offset(10.0 - 32.0, one_x) + fetch_offset(32.0 - 10.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[10], chroma_filter_2_phase[10], chroma_filter_2_phase[10]);
|
||||
sums = fetch_offset(11.0 - 32.0, one_x) + fetch_offset(32.0 - 11.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[11], chroma_filter_2_phase[11], chroma_filter_2_phase[11]);
|
||||
sums = fetch_offset(12.0 - 32.0, one_x) + fetch_offset(32.0 - 12.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[12], chroma_filter_2_phase[12], chroma_filter_2_phase[12]);
|
||||
sums = fetch_offset(13.0 - 32.0, one_x) + fetch_offset(32.0 - 13.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[13], chroma_filter_2_phase[13], chroma_filter_2_phase[13]);
|
||||
sums = fetch_offset(14.0 - 32.0, one_x) + fetch_offset(32.0 - 14.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[14], chroma_filter_2_phase[14], chroma_filter_2_phase[14]);
|
||||
sums = fetch_offset(15.0 - 32.0, one_x) + fetch_offset(32.0 - 15.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[15], chroma_filter_2_phase[15], chroma_filter_2_phase[15]);
|
||||
sums = fetch_offset(16.0 - 32.0, one_x) + fetch_offset(32.0 - 16.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[16], chroma_filter_2_phase[16], chroma_filter_2_phase[16]);
|
||||
sums = fetch_offset(17.0 - 32.0, one_x) + fetch_offset(32.0 - 17.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[17], chroma_filter_2_phase[17], chroma_filter_2_phase[17]);
|
||||
sums = fetch_offset(18.0 - 32.0, one_x) + fetch_offset(32.0 - 18.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[18], chroma_filter_2_phase[18], chroma_filter_2_phase[18]);
|
||||
sums = fetch_offset(19.0 - 32.0, one_x) + fetch_offset(32.0 - 19.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[19], chroma_filter_2_phase[19], chroma_filter_2_phase[19]);
|
||||
sums = fetch_offset(20.0 - 32.0, one_x) + fetch_offset(32.0 - 20.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[20], chroma_filter_2_phase[20], chroma_filter_2_phase[20]);
|
||||
sums = fetch_offset(21.0 - 32.0, one_x) + fetch_offset(32.0 - 21.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[21], chroma_filter_2_phase[21], chroma_filter_2_phase[21]);
|
||||
sums = fetch_offset(22.0 - 32.0, one_x) + fetch_offset(32.0 - 22.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[22], chroma_filter_2_phase[22], chroma_filter_2_phase[22]);
|
||||
sums = fetch_offset(23.0 - 32.0, one_x) + fetch_offset(32.0 - 23.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[23], chroma_filter_2_phase[23], chroma_filter_2_phase[23]);
|
||||
sums = fetch_offset(24.0 - 32.0, one_x) + fetch_offset(32.0 - 24.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[24], chroma_filter_2_phase[24], chroma_filter_2_phase[24]);
|
||||
sums = fetch_offset(25.0 - 32.0, one_x) + fetch_offset(32.0 - 25.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[25], chroma_filter_2_phase[25], chroma_filter_2_phase[25]);
|
||||
sums = fetch_offset(26.0 - 32.0, one_x) + fetch_offset(32.0 - 26.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[26], chroma_filter_2_phase[26], chroma_filter_2_phase[26]);
|
||||
sums = fetch_offset(27.0 - 32.0, one_x) + fetch_offset(32.0 - 27.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[27], chroma_filter_2_phase[27], chroma_filter_2_phase[27]);
|
||||
sums = fetch_offset(28.0 - 32.0, one_x) + fetch_offset(32.0 - 28.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[28], chroma_filter_2_phase[28], chroma_filter_2_phase[28]);
|
||||
sums = fetch_offset(29.0 - 32.0, one_x) + fetch_offset(32.0 - 29.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[29], chroma_filter_2_phase[29], chroma_filter_2_phase[29]);
|
||||
sums = fetch_offset(30.0 - 32.0, one_x) + fetch_offset(32.0 - 30.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[30], chroma_filter_2_phase[30], chroma_filter_2_phase[30]);
|
||||
sums = fetch_offset(31.0 - 32.0, one_x) + fetch_offset(32.0 - 31.0, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[31], chroma_filter_2_phase[31], chroma_filter_2_phase[31]);
|
||||
|
||||
vec3 sums = fetch_offset(offset - float(TAPS_2_phase), one_x) +
|
||||
fetch_offset(float(TAPS_2_phase) - offset, one_x);
|
||||
signal += sums * vec3(luma_filter_2_phase[i], chroma_filter_2_phase[i], chroma_filter_2_phase[i]);
|
||||
}
|
||||
#ifdef GL_ES
|
||||
signal += unpack_float(COMPAT_TEXTURE(Source, vTexCoord).xyz) *
|
||||
vec3(luma_filter_2_phase[TAPS_2_phase], chroma_filter_2_phase[TAPS_2_phase], chroma_filter_2_phase[TAPS_2_phase]);
|
||||
#else
|
||||
signal += COMPAT_TEXTURE(Source, vTexCoord).xyz *
|
||||
vec3(luma_filter_2_phase[TAPS_2_phase], chroma_filter_2_phase[TAPS_2_phase], chroma_filter_2_phase[TAPS_2_phase]);
|
||||
#endif
|
||||
}
|
||||
else if(phase > 2.5)
|
||||
{
|
||||
@ -269,10 +345,15 @@ void main()
|
||||
fetch_offset(float(TAPS_3_phase) - offset, one_x);
|
||||
signal += sums * vec3(luma_filter_3_phase[i], chroma_filter_3_phase[i], chroma_filter_3_phase[i]);
|
||||
}
|
||||
#ifdef GL_ES
|
||||
signal += unpack_float(COMPAT_TEXTURE(Source, vTexCoord).xyz) *
|
||||
vec3(luma_filter_3_phase[TAPS_3_phase], chroma_filter_3_phase[TAPS_3_phase], chroma_filter_3_phase[TAPS_3_phase]);
|
||||
}
|
||||
#else
|
||||
signal += COMPAT_TEXTURE(Source, vTexCoord).xyz *
|
||||
vec3(luma_filter_3_phase[TAPS_3_phase], chroma_filter_3_phase[TAPS_3_phase], chroma_filter_3_phase[TAPS_3_phase]);
|
||||
}
|
||||
|
||||
#endif
|
||||
vec3 rgb = yiq2rgb(signal);
|
||||
FragColor = vec4(rgb, 1.0);
|
||||
if(linearize < 0.5) return;
|
||||
|
Loading…
Reference in New Issue
Block a user