1 2/////////////// 3// TV-out tweaks Linearized Multipass - Pass1 4// Author: aliaspider and RiskyJumps 5// License: GPLv3 6//////////////////////////////////////////////////////// 7 8 9// this shader is meant to be used when running 10// an emulator on a real CRT-TV @240p or @480i 11//////////////////////////////////////////////////////// 12// Basic settings: 13 14// signal resolution 15// higher = sharper 16#pragma parameter TVOUT_RESOLUTION "TVOut Signal Resolution" 256.0 0.0 1024.0 32.0 // default, minimum, maximum, optional step 17 18// simulate a composite connection instead of RGB 19//#pragma parameter TVOUT_COMPOSITE_CONNECTION "TVOut Composite Enable" 0.0 0.0 1.0 1.0 20 21//// use TV video color range (16-235) 22//// instead of PC full range (0-255) 23//#pragma parameter TVOUT_TV_COLOR_LEVELS "TVOut TV Color Levels Enable" 0.0 0.0 1.0 1.0 24//////////////////////////////////////////////////////// 25 26//////////////////////////////////////////////////////// 27// Advanced settings: 28// 29// these values will be used instead 30// if COMPOSITE_CONNECTION is defined 31// to simulate different signal resolutions(bandwidth) 32// for luma (Y) and chroma ( I and Q ) 33// this is just an approximation 34// and will only simulate the low bandwidth anspect of 35// composite signal, not the crosstalk between luma and chroma 36// Y = 4MHz I=1.3MHz Q=0.4MHz 37#pragma parameter TVOUT_RESOLUTION_Y "TVOut Luma (Y) Resolution" 256.0 0.0 1024.0 32.0 38#pragma parameter TVOUT_RESOLUTION_I "TVOut Chroma (I) Resolution" 83.2 0.0 256.0 8.0 39#pragma parameter TVOUT_RESOLUTION_Q "TVOut Chroma (Q) Resolution" 25.6 0.0 256.0 8.0 40 41// formula is MHz=resolution*15750Hz 42// 15750Hz being the horizontal Frequency of NTSC 43// (=262.5*60Hz) 44//////////////////////////////////////////////////////// 45 46#if defined(VERTEX) 47 48#if __VERSION__ >= 130 49#define COMPAT_VARYING out 50#define COMPAT_ATTRIBUTE in 51#define COMPAT_TEXTURE texture 52#else 53#define COMPAT_VARYING varying 54#define COMPAT_ATTRIBUTE attribute 55#define COMPAT_TEXTURE texture2D 56#endif 57 58#ifdef GL_ES 59#define COMPAT_PRECISION mediump 60#else 61#define COMPAT_PRECISION 62#endif 63 64COMPAT_ATTRIBUTE vec4 VertexCoord; 65COMPAT_ATTRIBUTE vec4 COLOR; 66COMPAT_ATTRIBUTE vec4 TexCoord; 67COMPAT_VARYING vec4 COL0; 68COMPAT_VARYING vec4 TEX0; 69 70vec4 _oPosition1; 71uniform mat4 MVPMatrix; 72uniform COMPAT_PRECISION int FrameDirection; 73uniform COMPAT_PRECISION int FrameCount; 74uniform COMPAT_PRECISION vec2 OutputSize; 75uniform COMPAT_PRECISION vec2 TextureSize; 76uniform COMPAT_PRECISION vec2 InputSize; 77 78void main() 79{ 80 gl_Position = MVPMatrix * VertexCoord; 81 TEX0.xy = TexCoord.xy; 82} 83 84#elif defined(FRAGMENT) 85 86#if __VERSION__ >= 130 87#define COMPAT_VARYING in 88#define COMPAT_TEXTURE texture 89out vec4 FragColor; 90#else 91#define COMPAT_VARYING varying 92#define FragColor gl_FragColor 93#define COMPAT_TEXTURE texture2D 94#endif 95 96#ifdef GL_ES 97#ifdef GL_FRAGMENT_PRECISION_HIGH 98precision highp float; 99#else 100precision mediump float; 101#endif 102#define COMPAT_PRECISION mediump 103#else 104#define COMPAT_PRECISION 105#endif 106 107#ifdef PARAMETER_UNIFORM // If the shader implementation understands #pragma parameters, this is defined. 108uniform COMPAT_PRECISION float TVOUT_RESOLUTION; 109uniform COMPAT_PRECISION float TVOUT_COMPOSITE_CONNECTION; 110uniform COMPAT_PRECISION float TVOUT_TV_COLOR_LEVELS; 111uniform COMPAT_PRECISION float TVOUT_RESOLUTION_Y; 112uniform COMPAT_PRECISION float TVOUT_RESOLUTION_I; 113uniform COMPAT_PRECISION float TVOUT_RESOLUTION_Q; 114#else 115// Fallbacks if parameters are not supported. 116#define TVOUT_RESOLUTION 256.0 // Default 117#define TVOUT_COMPOSITE_CONNECTION 0 118#define TVOUT_TV_COLOR_LEVELS 0 119#define TVOUT_RESOLUTION_Y 256.0 120#define TVOUT_RESOLUTION_I 83.2 121#define TVOUT_RESOLUTION_Q 25.6 122#endif 123 124#define pi 3.14159265358 125#define a(x) abs(x) 126#define d(x,b) (pi*b*min(a(x)+0.5,1.0/b)) 127#define e(x,b) (pi*b*min(max(a(x)-0.5,-1.0/b),1.0/b)) 128#define STU(x,b) ((d(x,b)+sin(d(x,b))-e(x,b)-sin(e(x,b)))/(2.0*pi)) 129 130#define GETC(c) \ 131 if (TVOUT_COMPOSITE_CONNECTION > 0.5) \ 132 c = ((COMPAT_TEXTURE(Texture, vec2(TEX0.x - X*oneT,TEX0.y)).xyz) * RGB_to_YIQ); \ 133 else \ 134 c = ((COMPAT_TEXTURE(Texture, vec2(TEX0.x - X*oneT,TEX0.y)).xyz)) 135 136#define VAL(tempColor) \ 137 if (TVOUT_COMPOSITE_CONNECTION > 0.5) \ 138 tempColor += vec3((c.x*STU(X,(TVOUT_RESOLUTION_Y*oneI))),(c.y*STU(X,(TVOUT_RESOLUTION_I*oneI))),(c.z*STU(X,(TVOUT_RESOLUTION_Q*oneI)))); \ 139 else \ 140 tempColor += (c*STU(X,(TVOUT_RESOLUTION*oneI))) 141 142 143uniform COMPAT_PRECISION int FrameDirection; 144uniform COMPAT_PRECISION int FrameCount; 145uniform COMPAT_PRECISION vec2 OutputSize; 146uniform COMPAT_PRECISION vec2 TextureSize; 147uniform COMPAT_PRECISION vec2 InputSize; 148uniform sampler2D Texture; 149COMPAT_VARYING vec4 TEX0; 150 151void main() 152{ 153mat3 RGB_to_YIQ = mat3( 154 0.300, 0.5900, 0.1100, 155 0.599, -0.2773, -0.3217, 156 0.213, -0.5251, 0.3121 157); 158 159mat3 YIQ_to_RGB = mat3( 160 1.0, 0.946882217090069, 0.623556581986143, 161 1.0, -0.274787646298978, -0.635691079187380, 162 1.0, -1.108545034642030, 1.709006928406470 163); 164 165 vec3 tempColor = vec3(0.0,0.0,0.0); 166 float offset = fract((TEX0.x * TextureSize.x) - 0.5); 167 float oneT = 1.0 / TextureSize.x; 168 float oneI = 1.0 / InputSize.x; 169 170 float X; 171 vec3 c; 172 173 X = (offset-(-1.0));//X(-1.0); 174 GETC(c); 175 VAL(tempColor); 176 177 X = (offset-(0.0));//X(0.0); 178 GETC(c); 179 VAL(tempColor); 180 181 X = (offset-(1.0));//X(1.0); 182 GETC(c); 183 VAL(tempColor); 184 185 X = (offset-(2.0));//X(2.0); 186 GETC(c); 187 VAL(tempColor); 188 189 if (TVOUT_COMPOSITE_CONNECTION > 0.5) 190 tempColor = tempColor * YIQ_to_RGB; 191 192 FragColor = vec4(pow(tempColor, vec3(1.0/2.2)), 1.0); 193} 194#endif 195