├── .gitattributes ├── README.md ├── Shaders ├── 3DFX.fx ├── ArtifactColors.fx ├── BasicCRT.fx ├── CRT-Frutbunn.fx ├── CRT-NewPixie.fx ├── CRT-Yee64.fx ├── CRT-Yeetron.fx ├── CRTAperture.fx ├── CRTCX.fx ├── CRTCaligari.fx ├── CRTEasymode.fx ├── CRTFakeLottes.fx ├── CRTGeom.fx ├── CRTHyllian.fx ├── CRTKurg.fx ├── CRTLottes.fx ├── CRTLottes2.fx ├── CRTPi.fx ├── CRTPotatoCool.fx ├── CRTPotatoWarm.fx ├── CRTRefresh.fx ├── CRTSim.fx ├── CRTcgwg.fx ├── Cathode.fx ├── Chromaticity.fx ├── ChromaticitySimplified.fx ├── ColorMAME.fx ├── CoolRetroTerminal.fx ├── DOSGame.fx ├── Deconverge.fx ├── Defocus.fx ├── EGAfilter.fx ├── GTU.fx ├── ImageAdjustment.fx ├── JPEG.fx ├── LeiFX_OA.fx ├── MAMEPostProc.fx ├── MCAmber.fx ├── MCGreen.fx ├── MCOrange.fx ├── MMJCelShader.fx ├── MattiasCRT.fx ├── MetaCRT.fx ├── N64_3Point.fx ├── NTSCCustom.fx ├── NTSC_RetroArch.fx ├── NTSC_RetroArch_NoScanlines.fx ├── NTSC_XOT.fx ├── PAL.fx ├── Phosphor.fx ├── PowerVR2.fx ├── R57_PAL.fx ├── R57_PAL_NEW.fx ├── RGBLCD.fx ├── RetroCRT.fx ├── TVCRTPixels.fx ├── Technicolor.fx ├── VHS.fx ├── VHS_RA.fx ├── cmyk_halftone_dot.fx ├── crt-nes-mini.fx ├── lcd-grid.fx ├── mdapt.fx ├── nGlide_3DFX.fx ├── ntsc.fx ├── scanlines-abs.fx ├── scanlines-fract.fx ├── sgenpt-mix.fx ├── vt220.fx ├── vt220_frame.fx ├── vt220_night.fx └── zfast_crt.fx └── Textures ├── CMYK.png ├── allNoise512.png ├── crt-cx └── tvscreen.png ├── crt-newpixie └── crtframe.png ├── crt_potato ├── crt-potato-thick.png └── crt-potato-thin.png ├── crtsim ├── artifacts.png └── mask.png └── film_noise1.png /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Shaders/3DFX.fx: -------------------------------------------------------------------------------- 1 | // "LeiFX" shader - Pixel filtering process 2 | // 3 | // Copyright (C) 2013 leilei 4 | // 5 | // This program is free software; you can redistribute it and/or modify it 6 | // under the terms of the GNU General Public License as published by the Free 7 | // Software Foundation; either version 2 of the License, or (at your option) 8 | // any later version. 9 | 10 | #include "ReShade.fxh" 11 | 12 | uniform float DITHERAMOUNT < 13 | ui_type = "drag"; 14 | ui_min = 0.0; 15 | ui_max = 1.0; 16 | ui_label = "Dither Amount [3DFX]"; 17 | > = 0.5; 18 | 19 | uniform int DITHERBIAS < 20 | ui_type = "drag"; 21 | ui_min = -16; 22 | ui_max = 16; 23 | ui_label = "Dither Bias [3DFX]"; 24 | > = -1; 25 | 26 | uniform float LEIFX_LINES < 27 | ui_type = "drag"; 28 | ui_min = 0.0; 29 | ui_max = 2.0; 30 | ui_label = "Lines Intensity [3DFX]"; 31 | > = 1.0; 32 | 33 | uniform float LEIFX_PIXELWIDTH < 34 | ui_type = "drag"; 35 | ui_min = 0.0; 36 | ui_max = 100.0; 37 | ui_label = "Pixel Width [3DFX]"; 38 | > = 1.5; 39 | 40 | uniform float GAMMA_LEVEL < 41 | ui_type = "drag"; 42 | ui_min = 0.0; 43 | ui_max = 3.0; 44 | ui_label = "Gamma Level [3DFX]"; 45 | > = 1.0; 46 | 47 | #ifndef FILTCAP 48 | #define FILTCAP 0.04 //[0.0:100.0] //-filtered pixel should not exceed this 49 | #endif 50 | 51 | #ifndef FILTCAPG 52 | #define FILTCAPG (FILTCAP/2) 53 | #endif 54 | 55 | #define mod2(x,y) (x-y*floor(x/y)) 56 | 57 | float fmod(float a, float b) 58 | { 59 | float c = frac(abs(a/b))*abs(b); 60 | return (a < 0) ? -c : c; /* if ( a < 0 ) c = 0-c */ 61 | } 62 | 63 | float4 PS_3DFX(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target 64 | { 65 | float4 colorInput = tex2D(ReShade::BackBuffer, texcoord); 66 | 67 | float2 res; 68 | res.x = ReShade::ScreenSize.x; 69 | res.y = ReShade::ScreenSize.y; 70 | 71 | float2 ditheu = texcoord.xy * res.xy; 72 | 73 | ditheu.x = texcoord.x * res.x; 74 | ditheu.y = texcoord.y * res.y; 75 | 76 | // Dither. Total rewrite. 77 | // NOW, WHAT PIXEL AM I!?? 78 | 79 | int ditx = int(fmod(ditheu.x, 4.0)); 80 | int dity = int(fmod(ditheu.y, 4.0)); 81 | int ditdex = ditx * 4 + dity; // 4x4! 82 | float3 color; 83 | float3 colord; 84 | color.r = colorInput.r * 255; 85 | color.g = colorInput.g * 255; 86 | color.b = colorInput.b * 255; 87 | int yeh = 0; 88 | int ohyes = 0; 89 | 90 | float erroredtable[16] = { 91 | 16,4,13,1, 92 | 8,12,5,9, 93 | 14,2,15,3, 94 | 6,10,7,11 95 | }; 96 | 97 | // looping through a lookup table matrix 98 | //for (yeh=ditdex; yeh<(ditdex+16); yeh++) ohyes = pow(erroredtable[yeh-15], 0.72f); 99 | // Unfortunately, RetroArch doesn't support loops so I have to unroll this. =( 100 | // Dither method adapted from xTibor on Shadertoy ("Ordered Dithering"), generously 101 | // put into the public domain. Thanks! 102 | if (yeh++==ditdex) ohyes = erroredtable[0]; 103 | else if (yeh++==ditdex) ohyes = erroredtable[1]; 104 | else if (yeh++==ditdex) ohyes = erroredtable[2]; 105 | else if (yeh++==ditdex) ohyes = erroredtable[3]; 106 | else if (yeh++==ditdex) ohyes = erroredtable[4]; 107 | else if (yeh++==ditdex) ohyes = erroredtable[5]; 108 | else if (yeh++==ditdex) ohyes = erroredtable[6]; 109 | else if (yeh++==ditdex) ohyes = erroredtable[7]; 110 | else if (yeh++==ditdex) ohyes = erroredtable[8]; 111 | else if (yeh++==ditdex) ohyes = erroredtable[9]; 112 | else if (yeh++==ditdex) ohyes = erroredtable[10]; 113 | else if (yeh++==ditdex) ohyes = erroredtable[11]; 114 | else if (yeh++==ditdex) ohyes = erroredtable[12]; 115 | else if (yeh++==ditdex) ohyes = erroredtable[13]; 116 | else if (yeh++==ditdex) ohyes = erroredtable[14]; 117 | else if (yeh++==ditdex) ohyes = erroredtable[15]; 118 | 119 | // Adjust the dither thing 120 | ohyes = 17 - (ohyes - 1); // invert 121 | ohyes *= DITHERAMOUNT; 122 | ohyes += DITHERBIAS; 123 | 124 | colord.r = color.r + ohyes; 125 | colord.g = color.g + (ohyes / 2); 126 | colord.b = color.b + ohyes; 127 | colorInput.rgb = colord.rgb * 0.003921568627451; // divide by 255, i don't trust em 128 | 129 | // 130 | // Reduce to 16-bit color 131 | // 132 | 133 | float why = 1; 134 | float3 reduceme = 1; 135 | float radooct = 32; // 32 is usually the proper value 136 | 137 | reduceme.r = pow(colorInput.r, why); 138 | reduceme.r *= radooct; 139 | reduceme.r = float(floor(reduceme.r)); 140 | reduceme.r /= radooct; 141 | reduceme.r = pow(reduceme.r, why); 142 | 143 | reduceme.g = pow(colorInput.g, why); 144 | reduceme.g *= radooct * 2; 145 | reduceme.g = float(floor(reduceme.g)); 146 | reduceme.g /= radooct * 2; 147 | reduceme.g = pow(reduceme.g, why); 148 | 149 | reduceme.b = pow(colorInput.b, why); 150 | reduceme.b *= radooct; 151 | reduceme.b = float(floor(reduceme.b)); 152 | reduceme.b /= radooct; 153 | reduceme.b = pow(reduceme.b, why); 154 | 155 | colorInput.rgb = reduceme.rgb; 156 | 157 | // Add the purple line of lineness here, so the filter process catches it and gets gammaed. 158 | { 159 | float leifx_linegamma = (LEIFX_LINES / 10); 160 | float horzline1 = (fmod(ditheu.y, 2.0)); 161 | if (horzline1 < 1) leifx_linegamma = 0; 162 | 163 | colorInput.r += leifx_linegamma; 164 | colorInput.g += leifx_linegamma; 165 | colorInput.b += leifx_linegamma; 166 | } 167 | 168 | return colorInput; 169 | } 170 | 171 | float4 PS_3DFX1(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target 172 | { 173 | float4 colorInput = tex2D(ReShade::BackBuffer, texcoord); 174 | float2 pixel; 175 | 176 | pixel.x = 1 / ReShade::ScreenSize.x; 177 | pixel.y = 1 / ReShade::ScreenSize.y; 178 | 179 | float3 pixel1 = tex2D(ReShade::BackBuffer, texcoord + float2((pixel.x), 0)).rgb; 180 | float3 pixel2 = tex2D(ReShade::BackBuffer, texcoord + float2(-pixel.x, 0)).rgb; 181 | float3 pixelblend; 182 | 183 | // New filter 184 | { 185 | float3 pixeldiff; 186 | float3 pixelmake; 187 | float3 pixeldiffleft; 188 | 189 | pixelmake.rgb = 0; 190 | pixeldiff.rgb = pixel2.rgb- colorInput.rgb; 191 | 192 | pixeldiffleft.rgb = pixel1.rgb - colorInput.rgb; 193 | 194 | if (pixeldiff.r > FILTCAP) pixeldiff.r = FILTCAP; 195 | if (pixeldiff.g > FILTCAPG) pixeldiff.g = FILTCAPG; 196 | if (pixeldiff.b > FILTCAP) pixeldiff.b = FILTCAP; 197 | 198 | if (pixeldiff.r < -FILTCAP) pixeldiff.r = -FILTCAP; 199 | if (pixeldiff.g < -FILTCAPG) pixeldiff.g = -FILTCAPG; 200 | if (pixeldiff.b < -FILTCAP) pixeldiff.b = -FILTCAP; 201 | 202 | if (pixeldiffleft.r > FILTCAP) pixeldiffleft.r = FILTCAP; 203 | if (pixeldiffleft.g > FILTCAPG) pixeldiffleft.g = FILTCAPG; 204 | if (pixeldiffleft.b > FILTCAP) pixeldiffleft.b = FILTCAP; 205 | 206 | if (pixeldiffleft.r < -FILTCAP) pixeldiffleft.r = -FILTCAP; 207 | if (pixeldiffleft.g < -FILTCAPG) pixeldiffleft.g = -FILTCAPG; 208 | if (pixeldiffleft.b < -FILTCAP) pixeldiffleft.b = -FILTCAP; 209 | 210 | pixelmake.rgb = (pixeldiff.rgb / 4) + (pixeldiffleft.rgb / 16); 211 | colorInput.rgb = (colorInput.rgb + pixelmake.rgb); 212 | } 213 | 214 | return colorInput; 215 | } 216 | 217 | float4 PS_3DFX2(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target 218 | { 219 | float4 colorInput = tex2D(ReShade::BackBuffer, texcoord); 220 | 221 | float2 res; 222 | res.x = ReShade::ScreenSize.x; 223 | res.y = ReShade::ScreenSize.y; 224 | 225 | // Gamma scanlines 226 | // the Voodoo drivers usually supply a 1.3 gamma setting whether people liked it or not 227 | // but it was enough to brainwash the competition for looking 'too dark' 228 | 229 | colorInput.r = pow(colorInput.r, 1.0 / GAMMA_LEVEL); 230 | colorInput.g = pow(colorInput.g, 1.0 / GAMMA_LEVEL); 231 | colorInput.b = pow(colorInput.b, 1.0 / GAMMA_LEVEL); 232 | 233 | return colorInput; 234 | } 235 | 236 | technique LeiFx_Tech 237 | { 238 | pass LeiFx 239 | { 240 | VertexShader = PostProcessVS; 241 | PixelShader = PS_3DFX; 242 | } 243 | pass LeiFx1 244 | { 245 | VertexShader = PostProcessVS; 246 | PixelShader = PS_3DFX1; 247 | } 248 | pass LeiFx2 249 | { 250 | VertexShader = PostProcessVS; 251 | PixelShader = PS_3DFX1; 252 | } 253 | pass LeiFx3 254 | { 255 | VertexShader = PostProcessVS; 256 | PixelShader = PS_3DFX1; 257 | } 258 | pass LeiFx4 259 | { 260 | VertexShader = PostProcessVS; 261 | PixelShader = PS_3DFX1; 262 | } 263 | pass LeiFx5 264 | { 265 | VertexShader = PostProcessVS; 266 | PixelShader = PS_3DFX2; 267 | } 268 | } -------------------------------------------------------------------------------- /Shaders/BasicCRT.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float Timer < source = "timer"; >; 4 | 5 | uniform float rowNum < 6 | ui_type = "drag"; 7 | ui_min = "1.0"; 8 | ui_max = "BUFFER_HEIGHT"; 9 | ui_label = "Row Count [BasicCRT]"; 10 | > = 320.0; 11 | 12 | uniform float refreshTime < 13 | ui_type = "drag"; 14 | ui_min = "0.0"; 15 | ui_max = "120.0"; 16 | ui_label = "RefreshTime [BasicCRT]"; 17 | > = 32.0; 18 | 19 | float4 CRTTest( float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target { 20 | float3 col = tex2D(ReShade::BackBuffer, uv).rgb; 21 | // per row offset 22 | float f = sin( uv.y * rowNum * 3.14 ); 23 | float o = f * (0.35 / rowNum); 24 | // scale for subtle effect 25 | float s = f * 0.03 + 0.97; 26 | 27 | float l = sin( Timer*0.001 * refreshTime )*0.03 + 0.97; 28 | // sample in 3 colour offset 29 | float r = tex2D(ReShade::BackBuffer, float2( uv.x+o, uv.y+o ) ).x; 30 | float g = tex2D(ReShade::BackBuffer, float2( uv.x-o, uv.y+o ) ).y; 31 | float b = tex2D(ReShade::BackBuffer, float2( uv.x , uv.y-o ) ).z; 32 | // combine as 33 | return float4( r*0.7f, g, b*0.9f, l)*l*s; 34 | } 35 | 36 | technique BasicCRT 37 | { 38 | pass CRT1 39 | { 40 | VertexShader = PostProcessVS; 41 | PixelShader = CRTTest; 42 | } 43 | } -------------------------------------------------------------------------------- /Shaders/CRT-Frutbunn.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | Adapted for RetroArch from frutbunn's "Another CRT shader" from shadertoy: 5 | https://www.shadertoy.com/view/XdyGzR 6 | */ 7 | 8 | uniform float texture_sizeX < 9 | ui_type = "drag"; 10 | ui_min = 1.0; 11 | ui_max = BUFFER_WIDTH; 12 | ui_label = "Screen Width [CRT-Frutbunn]"; 13 | > = 320.0; 14 | 15 | uniform float texture_sizeY < 16 | ui_type = "drag"; 17 | ui_min = 1.0; 18 | ui_max = BUFFER_HEIGHT; 19 | ui_label = "Screen Height [CRT-Frutbunn]"; 20 | > = 240.0; 21 | 22 | uniform bool CURVATURE < 23 | ui_type = "boolean"; 24 | ui_label = "Curvature Toggle [CRT-Frutbunn]"; 25 | > = true; 26 | 27 | uniform bool SCANLINES < 28 | ui_type = "boolean"; 29 | ui_label = "Scanlines Toggle [CRT-Frutbunn]"; 30 | > = true; 31 | 32 | uniform bool CURVED_SCANLINES < 33 | ui_type = "boolean"; 34 | ui_label = "Scanline Curve Toggle [CRT-Frutbunn]"; 35 | > = true; 36 | 37 | uniform bool LIGHT < 38 | ui_type = "boolean"; 39 | ui_label = "Vignetting Toggle [CRT-Frutbunn]"; 40 | > = true; 41 | 42 | uniform int light < 43 | ui_type = "drag"; 44 | ui_min = 0; 45 | ui_max = 20; 46 | ui_step = 1; 47 | ui_label = "Vignetting Strength [CRT-Frutbunn]"; 48 | > = 9; 49 | 50 | uniform float blur < 51 | ui_type = "drag"; 52 | ui_min = 0.0; 53 | ui_max = 8.0; 54 | ui_step = 0.05; 55 | ui_label = "Blur Strength [CRT-Frutbunn]"; 56 | > = 1.0; 57 | 58 | static const float gamma = 1.0; 59 | static const float contrast = 1.0; 60 | static const float saturation = 1.0; 61 | static const float brightness = 1.0; 62 | 63 | #define texture_size float2(texture_sizeX, texture_sizeY) 64 | #define texture_size_pixel float2(1.0/texture_sizeX, 1.0/texture_sizeY) 65 | 66 | // Sigma 1. Size 3 67 | float3 gaussian(in float2 uv, in sampler tex, in float2 iResolution) { 68 | float b = blur / (iResolution.x / iResolution.y); 69 | 70 | float3 col = tex2D(tex, float2(uv.x - b/iResolution.x, uv.y - b/iResolution.y) ).rgb * 0.077847; 71 | col += tex2D(tex, float2(uv.x - b/iResolution.x, uv.y) ).rgb * 0.123317; 72 | col += tex2D(tex, float2(uv.x - b/iResolution.x, uv.y + b/iResolution.y) ).rgb * 0.077847; 73 | 74 | col += tex2D(tex, float2(uv.x, uv.y - b/iResolution.y) ).rgb * 0.123317; 75 | col += tex2D(tex, float2(uv.x, uv.y) ).rgb * 0.195346; 76 | col += tex2D(tex, float2(uv.x, uv.y + b/iResolution.y) ).rgb * 0.123317; 77 | 78 | col += tex2D(tex, float2(uv.x + b/iResolution.x, uv.y - b/iResolution.y) ).rgb * 0.077847; 79 | col += tex2D(tex, float2(uv.x + b/iResolution.x, uv.y) ).rgb * 0.123317; 80 | col += tex2D(tex, float2(uv.x + b/iResolution.x, uv.y + b/iResolution.y) ).rgb * 0.077847; 81 | 82 | return col; 83 | } 84 | 85 | float4 PS_CRTFrutbunn( float4 pos : SV_Position, float2 txcoord : TEXCOORD0) : SV_Target 86 | { 87 | float2 st = txcoord - float2(0.5,0.5); 88 | 89 | // Curvature/light 90 | float d = length(st*.5 * st*.5); 91 | float2 uv; 92 | 93 | if (CURVATURE){ 94 | uv = st*d + st*.935; 95 | }else{ 96 | uv = st; 97 | } 98 | 99 | // CRT color blur 100 | float3 color = gaussian(uv+.5, ReShade::BackBuffer, texture_size.xy * 2.0); 101 | 102 | // Light 103 | if (LIGHT > 0.5){ 104 | float l = 1. - min(1., d*light); 105 | color *= l; 106 | } 107 | 108 | // Scanlines 109 | float y; 110 | if (CURVED_SCANLINES){ 111 | y = uv.y; 112 | }else{ 113 | y = st.y; 114 | } 115 | 116 | float showScanlines = 1.; 117 | // if (texture_size.y<360.) showScanlines = 0.; 118 | 119 | if (SCANLINES) 120 | { 121 | float s = 2.5 + ReShade::ScreenSize.y * texture_size_pixel.y;//1. - smoothstep(texture_size.x, ReShade::ScreenSize.x, texture_size.y) + 4.;//1. - smoothstep(320., 1440., texture_size.y) + 4.; 122 | float j = cos(y*texture_size.y*s)*.25; // values between .01 to .25 are ok. 123 | color = abs(showScanlines-1.)*color + showScanlines*(color - color*j); 124 | // color *= 1. - ( .01 + ceil(mod( (st.x+.5)*texture_size.x, 3.) ) * (.995-1.01) )*showScanlines; 125 | } 126 | 127 | // Border mask 128 | if (CURVATURE) 129 | { 130 | float m = max(0.0, 1. - 2.*max(abs(uv.x), abs(uv.y) ) ); 131 | m = min(m*200., 1.); 132 | color *= m; 133 | } 134 | 135 | return float4(color, 1.0);//float4(max(float3(0.0,0.0,0.0), min(float3(1.0,1.0,1.0), color)), 1.); 136 | } 137 | 138 | technique CRTFrutbunn { 139 | pass CRTFrutbunn { 140 | VertexShader = PostProcessVS; 141 | PixelShader = PS_CRTFrutbunn; 142 | } 143 | } -------------------------------------------------------------------------------- /Shaders/CRT-Yee64.fx: -------------------------------------------------------------------------------- 1 | /* 2 | Ported from RSDKV5U Decompile project 3 | CRT-Soft from Sonic Mania 4 | */ 5 | 6 | #include "ReShade.fxh" 7 | 8 | uniform float pixel_sizeX < 9 | ui_type = "drag"; 10 | ui_min = 1.0; 11 | ui_max = BUFFER_WIDTH; 12 | ui_label = "Internal Width [CRT-Yee64]"; 13 | > = 320.0; 14 | 15 | uniform float pixel_sizeY < 16 | ui_type = "drag"; 17 | ui_min = 1.0; 18 | ui_max = BUFFER_HEIGHT; 19 | ui_label = "Internal Height [CRT-Yee64]"; 20 | > = 240.0; 21 | 22 | #define pixel_size float2(pixel_sizeX, pixel_sizeY) 23 | 24 | uniform float texture_sizeX < 25 | ui_type = "drag"; 26 | ui_min = 1.0; 27 | ui_max = BUFFER_WIDTH; 28 | ui_label = "Screen Width [CRT-Yee64]"; 29 | > = 320.0; 30 | 31 | uniform float texture_sizeY < 32 | ui_type = "drag"; 33 | ui_min = 1.0; 34 | ui_max = BUFFER_HEIGHT; 35 | ui_label = "Screen Height [CRT-Yee64]"; 36 | > = 240.0; 37 | 38 | #define texture_size float2(texture_sizeX, texture_sizeY) 39 | 40 | uniform int viewSizeHD < 41 | ui_type = "drag"; 42 | ui_min = 1; 43 | ui_max = BUFFER_HEIGHT; 44 | ui_step = 1; 45 | ui_label = "View Size HD [CRT-Yee64]"; 46 | ui_tooltip = "How tall ResolutionScale has to be before it simulates the dimming effect"; 47 | > = 720; 48 | 49 | uniform float3 intencity < 50 | ui_type = "drag"; 51 | ui_min = 0.0; 52 | ui_max = 1.0; 53 | ui_step = 0.001; 54 | ui_label = "Dimming Intensity [CRT-Yee64]"; 55 | ui_tooltip = "How much to dim the screen when simulating the CRT effect."; 56 | > = float3(1.2, 0.9, 0.9); 57 | 58 | uniform float brightness < 59 | ui_type = "drag"; 60 | ui_min = 0.0; 61 | ui_max = 10.0; 62 | ui_step = 0.001; 63 | ui_label = "Mask Brightness [CRT-Yee64]"; 64 | ui_tooltip = "Brightness multiplier of the mask."; 65 | > = 1.25; 66 | 67 | float4 PS_CRTYee64(float4 pos : SV_Position, float2 coords : TEXCOORD0) : SV_Target 68 | { 69 | float2 texelPos = (texture_size.xy / pixel_size.xy) * coords.xy; 70 | float4 size = (pixel_size.xy / texture_size.xy).xyxy * texelPos.xyxy; 71 | float2 exp = size.zw * texture_size.xy + -floor(size.zw * texture_size.xy) + -0.5; 72 | 73 | float4 factor = pow(2, pow(-exp.x + float4(-1, 1, -2, 2), 2) * -3); 74 | float factor2 = pow(2, pow(exp.x, 2) * -3); // used for the same stuff as 'factor', just doesn't fit in a float4 :) 75 | 76 | float3 power; 77 | power.x = pow(2, pow(exp.y, 2) * -8); 78 | power.y = pow(2, pow(-exp.y + -1, 2) * -8); 79 | power.z = pow(2, pow(-exp.y + 1, 2) * -8); 80 | 81 | float2 viewPos = floor(texelPos.xy * ReShade::ScreenSize.xy) + 0.5; 82 | float intencityPos = frac((viewPos.y * 3.0 + viewPos.x) * 0.166667); 83 | 84 | float4 scanlineIntencity; 85 | if (intencityPos < 0.333) 86 | scanlineIntencity.rgb = intencity.xyz; 87 | else if (intencityPos < 0.666) 88 | scanlineIntencity.rgb = intencity.zxy; 89 | else 90 | scanlineIntencity.rgb = intencity.yzx; 91 | 92 | float3 color1 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + float2( 1, -1)) + 0.5) / texture_size.xy).rgb * factor.y * brightness; 93 | float3 color2 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + float2(-2, 0)) + 0.5) / texture_size.xy).rgb * factor.z * brightness; 94 | float3 color3 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + float2(-1, 0)) + 0.5) / texture_size.xy).rgb * factor.x * brightness; 95 | float3 color4 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + float2( 1, 0)) + 0.5) / texture_size.xy).rgb * factor.y * brightness; 96 | float3 color5 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + 0) + 0.5) / texture_size.xy).rgb * factor2 * brightness; 97 | float3 color6 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + float2(-1, 1)) + 0.5) / texture_size.xy).rgb * factor.x * brightness; 98 | float3 color7 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + float2( 2, 0)) + 0.5) / texture_size.xy).rgb * factor.w * brightness; 99 | float3 color8 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + -1) + 0.5) / texture_size.xy).rgb * factor.x * brightness; 100 | float3 color9 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + float2( 0, -1)) + 0.5) / texture_size.xy).rgb * factor2 * brightness; 101 | float3 color10 = tex2D(ReShade::BackBuffer, (floor(size.zw * texture_size.xy + 1) + 0.5) / texture_size.xy).rgb * factor.y * brightness; 102 | float3 color11 = tex2D(ReShade::BackBuffer, (floor(size.xy * texture_size.xy + float2( 0, 1)) + 0.5) / texture_size.xy).rgb * factor2 * brightness; 103 | 104 | float3 final = 105 | power.x * (color2 + color3 + color4 + color5 + color7) / (factor.z + factor.x + factor.y + factor2 + factor.w) + 106 | power.y * (color1 + color8 + color9) / (factor.y + factor.x + factor2) + 107 | power.z * (color10 + color6 + color11) / (factor.y + factor.x + factor2); 108 | 109 | float4 outColor; 110 | outColor.rgb = viewSizeHD < ReShade::ScreenSize.y ? (scanlineIntencity.rgb * final.rgb) : final.rgb; 111 | outColor.a = 1.0; 112 | 113 | return outColor; 114 | } 115 | 116 | technique CRTYee64 117 | { 118 | pass CRTYee64 119 | { 120 | VertexShader = PostProcessVS; 121 | PixelShader = PS_CRTYee64; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Shaders/CRT-Yeetron.fx: -------------------------------------------------------------------------------- 1 | /* 2 | Ported from RSDKV5U Decompile project 3 | CRT-Sharp from Sonic Mania 4 | */ 5 | 6 | #include "ReShade.fxh" 7 | 8 | uniform float pixel_sizeX < 9 | ui_type = "drag"; 10 | ui_min = 1.0; 11 | ui_max = BUFFER_WIDTH; 12 | ui_label = "Internal Width [CRT-Yee64]"; 13 | > = 320.0; 14 | 15 | uniform float pixel_sizeY < 16 | ui_type = "drag"; 17 | ui_min = 1.0; 18 | ui_max = BUFFER_HEIGHT; 19 | ui_label = "Internal Height [CRT-Yee64]"; 20 | > = 240.0; 21 | 22 | #define pixel_size float2(pixel_sizeX, pixel_sizeY) 23 | 24 | uniform float texture_sizeX < 25 | ui_type = "drag"; 26 | ui_min = 1.0; 27 | ui_max = BUFFER_WIDTH; 28 | ui_label = "Screen Width [CRT-Yee64]"; 29 | > = 320.0; 30 | 31 | uniform float texture_sizeY < 32 | ui_type = "drag"; 33 | ui_min = 1.0; 34 | ui_max = BUFFER_HEIGHT; 35 | ui_label = "Screen Height [CRT-Yee64]"; 36 | > = 240.0; 37 | 38 | #define texture_size float2(texture_sizeX, texture_sizeY) 39 | 40 | #define RSDK_PI 3.14159 41 | 42 | uniform int viewSizeHD < 43 | ui_type = "drag"; 44 | ui_min = 1; 45 | ui_max = BUFFER_HEIGHT; 46 | ui_step = 1; 47 | ui_label = "View Size HD [CRT-Yee64]"; 48 | ui_tooltip = "How tall ResolutionScale has to be before it simulates the dimming effect"; 49 | > = 720; 50 | 51 | uniform float3 intencity < 52 | ui_type = "drag"; 53 | ui_min = 0.0; 54 | ui_max = 1.0; 55 | ui_step = 0.001; 56 | ui_label = "Dimming Intensity [CRT-Yee64]"; 57 | ui_tooltip = "How much to dim the screen when simulating the CRT effect."; 58 | > = float3(1.2, 0.9, 0.9); 59 | 60 | float4 PS_CRTYeetron(float4 pos : SV_Position, float2 coords : TEXCOORD0) : SV_Target 61 | { 62 | float2 viewPos = floor((texture_size.xy / pixel_size.xy) * coords.xy * ReShade::ScreenSize.xy) + 0.5; 63 | float intencityPos = frac((viewPos.y * 3.0 + viewPos.x) * 0.166667); 64 | 65 | float4 scanlineIntencity; 66 | if (intencityPos < 0.333) 67 | scanlineIntencity.rgb = intencity.xyz; 68 | else if (intencityPos < 0.666) 69 | scanlineIntencity.rgb = intencity.zxy; 70 | else 71 | scanlineIntencity.rgb = intencity.yzx; 72 | 73 | float2 pixelPos = coords.xy * texture_size.xy; 74 | float2 roundedPixelPos = floor(pixelPos.xy); 75 | 76 | scanlineIntencity.a = clamp(abs(sin(pixelPos.y * RSDK_PI)) + 0.25, 0.5, 1.0); 77 | pixelPos.xy = frac(pixelPos.xy) + -0.5; 78 | 79 | float2 invTexPos = -coords.xy * texture_size.xy + (roundedPixelPos + 0.5); 80 | 81 | float2 newTexPos; 82 | newTexPos.x = clamp(-abs(invTexPos.x * 0.5) + 1.5, 0.8, 1.25); 83 | newTexPos.y = clamp(-abs(invTexPos.y * 2.0) + 1.25, 0.5, 1.0); 84 | 85 | float2 colorMod; 86 | colorMod.x = newTexPos.x * newTexPos.y; 87 | colorMod.y = newTexPos.x * ((scanlineIntencity.a + newTexPos.y) * 0.5); 88 | 89 | scanlineIntencity.a *= newTexPos.x; 90 | 91 | float2 texPos = ((pixelPos.xy + -clamp(pixelPos.xy, -0.25, 0.25)) * 2.0 + roundedPixelPos + 0.5) / texture_size.xy; 92 | float4 texColor = tex2D(ReShade::BackBuffer, texPos.xy); 93 | 94 | float3 blendedColor; 95 | blendedColor.r = scanlineIntencity.a * texColor.r; 96 | blendedColor.gb = colorMod.xy * texColor.gb; 97 | 98 | float4 outColor; 99 | outColor.rgb = ReShade::ScreenSize.y >= viewSizeHD ? (scanlineIntencity.rgb * blendedColor.rgb) : blendedColor.rgb; 100 | outColor.a = texColor.a; 101 | 102 | return outColor; 103 | } 104 | 105 | technique CRTYeetron 106 | { 107 | pass CRTYeetron 108 | { 109 | VertexShader = PostProcessVS; 110 | PixelShader = PS_CRTYeetron; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Shaders/CRTAperture.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | CRT Shader by EasyMode 5 | License: GPL 6 | */ 7 | 8 | uniform float resX < 9 | ui_type = "drag"; 10 | ui_min = 1.0; 11 | ui_max = BUFFER_WIDTH; 12 | ui_label = "Screen Width [CRT-Aperture]"; 13 | > = 320.0; 14 | 15 | uniform float resY < 16 | ui_type = "drag"; 17 | ui_min = 1.0; 18 | ui_max = BUFFER_HEIGHT; 19 | ui_label = "Screen Height [CRT-Aperture]"; 20 | > = 240.0; 21 | 22 | uniform float video_sizeX < 23 | ui_type = "drag"; 24 | ui_min = 1.0; 25 | ui_max = BUFFER_WIDTH; 26 | ui_label = "Frame Width [CRT-Aperture]"; 27 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 28 | > = 320.0; 29 | 30 | uniform float video_sizeY < 31 | ui_type = "drag"; 32 | ui_min = 1.0; 33 | ui_max = BUFFER_HEIGHT; 34 | ui_label = "Frame Height [CRT-Aperture]"; 35 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 36 | > = 240.0; 37 | 38 | uniform int SHARPNESS_IMAGE < 39 | ui_type = "drag"; 40 | ui_min = 1.0; 41 | ui_max = 5.0; 42 | ui_step = 1.0; 43 | ui_label = "Sharpness Image [CRT-Aperture]"; 44 | > = 1; 45 | 46 | uniform int SHARPNESS_EDGES < 47 | ui_type = "drag"; 48 | ui_min = 1; 49 | ui_max = 5; 50 | ui_step = 1; 51 | ui_label = "Sharpness Edges [CRT-Aperture]"; 52 | > = 3; 53 | 54 | uniform float GLOW_WIDTH < 55 | ui_type = "drag"; 56 | ui_min = 0.05; 57 | ui_max = 0.65; 58 | ui_step = 0.05; 59 | ui_label = "Glow Width [CRT-Aperture]"; 60 | > = 0.5; 61 | 62 | uniform float GLOW_HEIGHT < 63 | ui_type = "drag"; 64 | ui_min = 0.05; 65 | ui_max = 0.65; 66 | ui_step = 0.05; 67 | ui_label = "Glow Height [CRT-Aperture]"; 68 | > = 0.5; 69 | 70 | uniform float GLOW_HALATION < 71 | ui_type = "drag"; 72 | ui_min = 0.0; 73 | ui_max = 1.0; 74 | ui_step = 0.01; 75 | ui_label = "Glow Halation [CRT-Aperture]"; 76 | > = 0.1; 77 | 78 | uniform float GLOW_DIFFUSION < 79 | ui_type = "drag"; 80 | ui_min = 0.0; 81 | ui_max = 1.0; 82 | ui_step = 0.01; 83 | ui_label = "Glow Diffusion [CRT-Aperture]"; 84 | > = 0.05; 85 | 86 | uniform float MASK_COLORS < 87 | ui_type = "drag"; 88 | ui_min = 2.0; 89 | ui_max = 3.0; 90 | ui_step = 1.0; 91 | ui_label = "Mask Colors [CRT-Aperture]"; 92 | > = 2.0; 93 | 94 | uniform float MASK_STRENGTH < 95 | ui_type = "drag"; 96 | ui_min = 0.0; 97 | ui_max = 1.0; 98 | ui_step = 0.05; 99 | ui_label = "Mask Strength [CRT-Aperture]"; 100 | > = 0.3; 101 | 102 | uniform int MASK_SIZE < 103 | ui_type = "drag"; 104 | ui_min = 1; 105 | ui_max = 9; 106 | ui_step = 1; 107 | ui_label = "Mask Size [CRT-Aperture]"; 108 | > = 1; 109 | 110 | uniform float SCANLINE_SIZE_MIN < 111 | ui_type = "drag"; 112 | ui_min = 0.5; 113 | ui_max = 1.5; 114 | ui_step = 0.05; 115 | ui_label = "Scanline Size Min. [CRT-Aperture]"; 116 | > = 0.5; 117 | 118 | uniform float SCANLINE_SIZE_MAX < 119 | ui_type = "drag"; 120 | ui_min = 0.5; 121 | ui_max = 1.5; 122 | ui_step = 0.05; 123 | ui_label = "Scanline Size Max. [CRT-Aperture]"; 124 | > = 1.5; 125 | 126 | uniform float GAMMA_INPUT < 127 | ui_type = "drag"; 128 | ui_min = 1.0; 129 | ui_max = 5.0; 130 | ui_step = 0.1; 131 | ui_label = "Gamma Input [CRT-Aperture]"; 132 | > = 2.4; 133 | 134 | uniform float GAMMA_OUTPUT < 135 | ui_type = "drag"; 136 | ui_min = 1.0; 137 | ui_max = 5.0; 138 | ui_step = 0.1; 139 | ui_label = "Gamma Output [CRT-Aperture]"; 140 | > = 2.4; 141 | 142 | uniform float BRIGHTNESS < 143 | ui_type = "drag"; 144 | ui_min = 0.0; 145 | ui_max = 2.0; 146 | ui_step = 0.05; 147 | ui_label = "Brightness [CRT-Aperture]"; 148 | > = 1.5; 149 | 150 | #define FIX(c) max(abs(c), 1e-5) 151 | #define PI 3.141592653589 152 | #define TEX2D(c) pow(tex2D(tex, c).rgb, GAMMA_INPUT) 153 | #define texture_size float2(resX, resY) 154 | #define video_size float2(video_sizeX, video_sizeY) 155 | #define mod(x,y) (x - y * trunc(x/y)) 156 | 157 | float3 blur(float3x3 m, float dist, float rad) 158 | { 159 | float3 x = float3(dist - 1.0, dist, dist + 1.0) / rad; 160 | float3 w = exp2(x * x * -1.0); 161 | 162 | return (m[0] * w.x + m[1] * w.y + m[2] * w.z) / (w.x + w.y + w.z); 163 | } 164 | 165 | float3x3 get_color_matrix(sampler2D tex, float2 co, float2 dx) 166 | { 167 | return float3x3(TEX2D(co - dx), TEX2D(co), TEX2D(co + dx)); 168 | } 169 | 170 | float3 filter_gaussian(sampler2D tex, float2 co, float2 tex_size) 171 | { 172 | float2 dx = float2(1.0 / tex_size.x, 0.0); 173 | float2 dy = float2(0.0, 1.0 / tex_size.y); 174 | float2 pix_co = co * tex_size; 175 | float2 tex_co = (floor(pix_co) + 0.5) / tex_size; 176 | float2 dist = (frac(pix_co) - 0.5) * -1.0; 177 | 178 | float3x3 line0 = get_color_matrix(tex, tex_co - dy, dx); 179 | float3x3 line1 = get_color_matrix(tex, tex_co, dx); 180 | float3x3 line2 = get_color_matrix(tex, tex_co + dy, dx); 181 | float3x3 column = float3x3(blur(line0, dist.x, GLOW_WIDTH), 182 | blur(line1, dist.x, GLOW_WIDTH), 183 | blur(line2, dist.x, GLOW_WIDTH)); 184 | 185 | return blur(column, dist.y, GLOW_HEIGHT); 186 | } 187 | 188 | float3 filter_lanczos(sampler2D tex, float2 co, float2 tex_size, float sharp) 189 | { 190 | tex_size.x *= sharp; 191 | 192 | float2 dx = float2(1.0 / tex_size.x, 0.0); 193 | float2 pix_co = co * tex_size - float2(0.5, 0.0); 194 | float2 tex_co = (floor(pix_co) + float2(0.5, 0.0)) / tex_size; 195 | float2 dist = frac(pix_co); 196 | float4 coef = PI * float4(dist.x + 1.0, dist.x, dist.x - 1.0, dist.x - 2.0); 197 | 198 | coef = FIX(coef); 199 | coef = 2.0 * sin(coef) * sin(coef / 2.0) / (coef * coef); 200 | coef /= dot(coef, float4(1.0,1.0,1.0,1.0)); 201 | 202 | float4 col1 = float4(TEX2D(tex_co), 1.0); 203 | float4 col2 = float4(TEX2D(tex_co + dx), 1.0); 204 | 205 | return mul(coef, float4x4(col1, col1, col2, col2)).rgb; 206 | } 207 | 208 | float3 get_scanline_weight(float x, float3 col) 209 | { 210 | float3 beam = lerp(float3(SCANLINE_SIZE_MIN,SCANLINE_SIZE_MIN,SCANLINE_SIZE_MIN), float3(SCANLINE_SIZE_MAX,SCANLINE_SIZE_MAX,SCANLINE_SIZE_MAX), col); 211 | float3 x_mul = 2.0 / beam; 212 | float3 x_offset = x_mul * 0.5; 213 | 214 | return smoothstep(0.0, 1.0, 1.0 - abs(x * x_mul - x_offset)) * x_offset; 215 | } 216 | 217 | float3 get_mask_weight(float x) 218 | { 219 | float i = mod(floor(x * ReShade::ScreenSize.x * texture_size.x / (video_size.x * MASK_SIZE)), MASK_COLORS); 220 | 221 | if (i == 0.0) return lerp(float3(1.0, 0.0, 1.0), float3(1.0, 0.0, 0.0), MASK_COLORS - 2.0); 222 | else if (i == 1.0) return float3(0.0, 1.0, 0.0); 223 | else return float3(0.0, 0.0, 1.0); 224 | } 225 | 226 | float4 PS_CRTAperture(float4 vpos : SV_Position, float2 co : TEXCOORD0) : SV_Target 227 | { 228 | float3 col_glow = filter_gaussian(ReShade::BackBuffer, co, texture_size).rgb; 229 | float3 col_soft = filter_lanczos(ReShade::BackBuffer, co, texture_size, SHARPNESS_IMAGE).rgb; 230 | float3 col_sharp = filter_lanczos(ReShade::BackBuffer, co, texture_size, SHARPNESS_EDGES).rgb; 231 | float3 col = sqrt(col_sharp * col_soft); 232 | 233 | col *= get_scanline_weight(frac(co.y * texture_size.y), col_soft); 234 | col_glow = saturate(col_glow - col); 235 | col += col_glow * col_glow * GLOW_HALATION; 236 | col = lerp(col, col * get_mask_weight(co.x) * MASK_COLORS, MASK_STRENGTH); 237 | col += col_glow * GLOW_DIFFUSION; 238 | col = pow(col * BRIGHTNESS, 1.0 / GAMMA_OUTPUT); 239 | 240 | return float4(col, 1.0); 241 | } 242 | 243 | technique ApertureCRT { 244 | pass CRT_Aperture { 245 | VertexShader=PostProcessVS; 246 | PixelShader=PS_CRTAperture; 247 | } 248 | } -------------------------------------------------------------------------------- /Shaders/CRTCX.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float m_curve_x < 4 | ui_type = "drag"; 5 | ui_min = 0.0; 6 | ui_max = 1.0; 7 | ui_step = 0.001; 8 | ui_label = "Curvature X [CRT-CX]"; 9 | > = 1.0; 10 | 11 | uniform float m_curve_y < 12 | ui_type = "drag"; 13 | ui_min = 0.0; 14 | ui_max = 1.0; 15 | ui_step = 0.001; 16 | ui_label = "Curvature Y [CRT-CX]"; 17 | > = 1.0; 18 | 19 | uniform float m_scale_x < 20 | ui_type = "drag"; 21 | ui_min = 0.0; 22 | ui_max = 2.0; 23 | ui_step = 0.001; 24 | ui_label = "Overscan X [CRT-CX]"; 25 | > = 1.0; 26 | 27 | uniform float m_scale_y < 28 | ui_type = "drag"; 29 | ui_min = 0.0; 30 | ui_max = 2.0; 31 | ui_step = 0.001; 32 | ui_label = "Overscan Y [CRT-CX]"; 33 | > = 1.0; 34 | 35 | uniform float m_translate_x < 36 | ui_type = "drag"; 37 | ui_min = -1.0; 38 | ui_max = 1.0; 39 | ui_step = 0.001; 40 | ui_label = "Monitor Position X [CRT-CX]"; 41 | > = 0.0; 42 | 43 | uniform float m_translate_y < 44 | ui_type = "drag"; 45 | ui_min = -1.0; 46 | ui_max = 1.0; 47 | ui_step = 0.001; 48 | ui_label = "Moniton Position Y [CRT-CX]"; 49 | > = 0.0; 50 | 51 | uniform int m_resolution_x < 52 | ui_type = "drag"; 53 | ui_min = 1; 54 | ui_max = BUFFER_WIDTH; 55 | ui_step = 1; 56 | ui_label = "Resolution X [CRT-CX]"; 57 | > = 320; 58 | 59 | uniform int m_resolution_y < 60 | ui_type = "drag"; 61 | ui_min = 1; 62 | ui_max = BUFFER_HEIGHT; 63 | ui_step = 1; 64 | ui_label = "Resolution Y [CRT-CX]"; 65 | > = 240; 66 | 67 | uniform float m_scanline_intensity < 68 | ui_type = "drag"; 69 | ui_min = 0.0; 70 | ui_max = 2.0; 71 | ui_step = 0.001; 72 | ui_label = "Scanline Intensity [CRT-CX]"; 73 | > = 0.2; 74 | 75 | uniform float m_rgb_split_intensity < 76 | ui_type = "drag"; 77 | ui_min = 0.0; 78 | ui_max = 2.0; 79 | ui_step = 0.001; 80 | ui_label = "RGB Phosphor Intensity [CRT-CX]"; 81 | > = 0.4; 82 | 83 | uniform float m_brightness < 84 | ui_type = "drag"; 85 | ui_min = 0.0; 86 | ui_max = 2.0; 87 | ui_step = 0.001; 88 | ui_label = "Brightness [CRT-CX]"; 89 | > = 0.5; 90 | 91 | uniform float m_contrast < 92 | ui_type = "drag"; 93 | ui_min = 0.0; 94 | ui_max = 2.0; 95 | ui_step = 0.001; 96 | ui_label = "Contrast [CRT-CX]"; 97 | > = 0.5; 98 | 99 | uniform float m_gamma < 100 | ui_type = "drag"; 101 | ui_min = 0.0; 102 | ui_max = 2.0; 103 | ui_step = 0.001; 104 | ui_label = "Gamma [CRT-CX]"; 105 | > = 0.5; 106 | 107 | texture tFrameCX < source = "crt-cx/tvscreen.png"; > 108 | { 109 | Width = 1024; 110 | Height = 1024; 111 | MipLevels = 1; 112 | }; 113 | 114 | sampler sFrameCX { Texture = tFrameCX; AddressU = BORDER; AddressV = BORDER; MinFilter = LINEAR; MagFilter = LINEAR;}; 115 | 116 | float4 PS_CRTCX(float4 pos: SV_Position, float2 uv_tx : TEXCOORD0) : SV_Target 117 | { 118 | 119 | //float2 texcoords = (b3d_ClipPosition.st/b3d_ClipPosition.w)*0.5+0.5; 120 | float2 texels = uv_tx * ReShade::ScreenSize; //this is because the original shader uses OpenGL's fragCoord, which is in texels rather than pixels 121 | float2 texcoords = uv_tx; //this is because the original shader uses OpenGL's fragCoord, which is in texels rather than pixels 122 | 123 | // get color for position on screen: 124 | float2 resfac = float2(m_resolution_x, m_resolution_y)/float2(BUFFER_WIDTH, BUFFER_HEIGHT); 125 | float bl = 0.03; 126 | float x = texcoords.x*(1.0+bl)-bl/2.0; 127 | float y = texcoords.y*(1.0+bl)-bl/2.0; 128 | float x2 = (x-0.5)*(1.0+ 0.5*(0.3*m_curve_x)*((y-0.5)*(y-0.5)))/m_scale_x+0.5-m_translate_x; 129 | float y2 = (y-0.5)*(1.0+ 0.25*(0.3*m_curve_y)*((x-0.5)*(x-0.5)))/m_scale_y+0.5-m_translate_y; 130 | float2 v2 = float2(x2, y2); 131 | float4 temp = tex2D(ReShade::BackBuffer, v2); // v2*resfac 132 | 133 | // brightness and contrast: 134 | temp = clamp(float4((temp.rgb - 0.5) * (m_contrast*2.0) + 0.5 + (m_brightness*2.0-1.0), 1.0), 0.0, 1.0); 135 | 136 | // gamma: 137 | float gamma2 = 2.0-m_gamma*2.0; 138 | temp = float4(pow(abs(temp.r), gamma2),pow(abs(temp.g), gamma2),pow(abs(temp.b), gamma2), 1.0); 139 | 140 | // grb splitting and scanlines: 141 | if (v2.x<0.0 || v2.x>1.0 || v2.y<0.0 || v2.y>1.0) { 142 | temp = float4(0.0,0.0,0.0,1.0); 143 | } else { 144 | 145 | float cr = sin((x2*m_resolution_x) *2.0*3.1415) +0.1; 146 | float cg = sin((x2*m_resolution_x-1.0*2.0*3.1415)*2.0*3.1415) +0.1; 147 | float cb = sin((x2*m_resolution_x-2.0*2.0*3.1415)*2.0*3.1415) +0.1; 148 | temp = lerp(temp*float4(cr,cg,cb,1.0),temp,1.0-m_rgb_split_intensity); 149 | float ck = (sin((y2*m_resolution_y)*2.0*3.1415)+0.1)*m_scanline_intensity; 150 | temp += (temp*0.9)*ck*0.1; 151 | } 152 | 153 | // frame (taken from newpixie) 154 | 155 | float4 f= tex2D(sFrameCX,uv_tx.xy);//*((1.0)+2.0*fscale)-fscale-float2(-0.0, 0.005)); 156 | f.xyz = lerp( f.xyz, float3(0.0,0.0,0.0), 0.5 ); 157 | temp = lerp( temp, lerp( max( temp, 0.0), pow( abs( f.xyz ), float3( 1.0,1.0,1.0 ) ), f.w), float3( 1.0,1.0,1.0 ) ); 158 | 159 | // final color: 160 | return float4((temp.rgb)*0.9, 1.0); 161 | } 162 | 163 | technique CRT_CX 164 | { 165 | pass PS_CRTCX 166 | { 167 | VertexShader = PostProcessVS; 168 | PixelShader = PS_CRTCX; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /Shaders/CRTCaligari.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | Phosphor shader - Copyright (C) 2011 caligari. 5 | 6 | Ported by Hyllian. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License 10 | as published by the Free Software Foundation; either version 2 11 | of the License, or (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not, write to the Free Software 20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 | 22 | */ 23 | 24 | uniform float texture_sizeX < 25 | ui_type = "drag"; 26 | ui_min = 1.0; 27 | ui_max = BUFFER_WIDTH; 28 | ui_label = "Screen Width [CRTCaligari]"; 29 | > = 320.0; 30 | 31 | uniform float texture_sizeY < 32 | ui_type = "drag"; 33 | ui_min = 1.0; 34 | ui_max = BUFFER_HEIGHT; 35 | ui_label = "Screen Height [CRTCaligari]"; 36 | > = 240.0; 37 | 38 | uniform float SPOT_WIDTH < 39 | ui_type = "drag"; 40 | ui_min = 0.1; 41 | ui_max = 1.5; 42 | ui_step = 0.05; 43 | ui_label = "Spot Width [CRTCaligari]"; 44 | > = 0.9; 45 | 46 | uniform float SPOT_HEIGHT < 47 | ui_type = "drag"; 48 | ui_min = 0.1; 49 | ui_max = 1.5; 50 | ui_step = 0.05; 51 | ui_label = "Spot Height [CRTCaligari]"; 52 | > = 0.65; 53 | 54 | uniform float COLOR_BOOST < 55 | ui_type = "drag"; 56 | ui_min = 1.0; 57 | ui_max = 2.0; 58 | ui_step = 0.05; 59 | ui_label = "Color Boost [CRTCaligari]"; 60 | > = 1.45; 61 | 62 | uniform float InputGamma < 63 | ui_type = "drag"; 64 | ui_min = 0.0; 65 | ui_max = 5.0; 66 | ui_step = 0.1; 67 | ui_label = "Input Gamma [CRTCaligari]"; 68 | > = 2.4; 69 | 70 | uniform float OutputGamma < 71 | ui_type = "drag"; 72 | ui_min = 0.0; 73 | ui_max = 5.0; 74 | ui_step = 0.1; 75 | ui_label = "Output Gamma [CRTCaligari]"; 76 | > = 2.2; 77 | 78 | #define texture_size float2(texture_sizeX, texture_sizeY) 79 | 80 | /* Default Vertex shader */ 81 | 82 | #define GAMMA_IN(color) pow(color, float4(InputGamma, InputGamma, InputGamma, InputGamma)) 83 | #define GAMMA_OUT(color) pow(color, float4(1.0 / OutputGamma, 1.0 / OutputGamma, 1.0 / OutputGamma, 1.0 / OutputGamma)) 84 | 85 | #define TEX2D(coords) GAMMA_IN( tex2D(ReShade::BackBuffer, coords) ) 86 | 87 | // Macro for weights computing 88 | float WEIGHT(float w){ 89 | if(w>1.0){ 90 | w=1.0; 91 | } 92 | w = 1.0 - w * w; 93 | w = w * w; 94 | 95 | return w; 96 | } 97 | 98 | float4 PS_CRTCaligari( float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 99 | { 100 | float2 texCoord = texcoord + float2(0.0, 0.0); 101 | float2 onex = float2(1.0 / texture_size.x, 0.0); 102 | float2 oney = float2(0.0, 1.0 / texture_size.y); 103 | float2 coords = ( texCoord * texture_size ); 104 | float2 pixel_center = floor( coords ) + float2(0.5, 0.5); 105 | float2 texture_coords = pixel_center / texture_size; 106 | 107 | float4 color = TEX2D( texture_coords ); 108 | 109 | float dx = coords.x - pixel_center.x; 110 | 111 | float h_weight_00 = (dx / SPOT_WIDTH); 112 | WEIGHT(h_weight_00); 113 | 114 | color *= float4( h_weight_00, h_weight_00, h_weight_00, h_weight_00 ); 115 | 116 | // get closest horizontal neighbour to blend 117 | float2 coords01; 118 | if (dx>0.0) { 119 | coords01 = onex; 120 | dx = 1.0 - dx; 121 | } else { 122 | coords01 = -onex; 123 | dx = 1.0 + dx; 124 | } 125 | 126 | float4 colorNB = TEX2D( texture_coords + coords01 ); 127 | 128 | float h_weight_01 = dx / SPOT_WIDTH; 129 | WEIGHT( h_weight_01 ); 130 | 131 | color = color + colorNB * float4( h_weight_01, h_weight_01, h_weight_01, h_weight_01 ); 132 | 133 | ////////////////////////////////////////////////////// 134 | // Vertical Blending 135 | float dy = coords.y - pixel_center.y; 136 | float v_weight_00 = dy / SPOT_HEIGHT; 137 | WEIGHT(v_weight_00); 138 | color *= float4( v_weight_00, v_weight_00, v_weight_00, v_weight_00 ); 139 | 140 | // get closest vertical neighbour to blend 141 | float2 coords10; 142 | if (dy>0.0) { 143 | coords10 = oney; 144 | dy = 1.0 - dy; 145 | } else { 146 | coords10 = -oney; 147 | dy = 1.0 + dy; 148 | } 149 | colorNB = TEX2D( texture_coords + coords10 ); 150 | 151 | float v_weight_10 = dy / SPOT_HEIGHT; 152 | WEIGHT( v_weight_10 ); 153 | 154 | color = color + colorNB * float4( v_weight_10 * h_weight_00, v_weight_10 * h_weight_00, v_weight_10 * h_weight_00, v_weight_10 * h_weight_00 ); 155 | 156 | colorNB = TEX2D( texture_coords + coords01 + coords10 ); 157 | 158 | color = color + colorNB * float4( v_weight_10 * h_weight_01, v_weight_10 * h_weight_01, v_weight_10 * h_weight_01, v_weight_10 * h_weight_01 ); 159 | 160 | color *= float4( COLOR_BOOST, COLOR_BOOST, COLOR_BOOST, COLOR_BOOST ); 161 | 162 | 163 | return clamp( GAMMA_OUT(color), 0.0, 1.0 ); 164 | } 165 | 166 | technique CRTCaligari { 167 | pass CRTCaligari { 168 | VertexShader=PostProcessVS; 169 | PixelShader=PS_CRTCaligari; 170 | } 171 | } -------------------------------------------------------------------------------- /Shaders/CRTFakeLottes.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | // Simple scanlines with curvature and mask effects lifted from crt-lottes 4 | // by hunterk 5 | 6 | //////////////////////////////////////////////////////////////////// 7 | //////////////////////////// SETTINGS //////////////////////////// 8 | ///// comment these lines to disable effects and gain speed ////// 9 | //////////////////////////////////////////////////////////////////// 10 | 11 | #ifndef MASK 12 | #define MASK 1 // fancy, expensive phosphor mask effect 13 | #endif 14 | 15 | #ifndef CURVATURE 16 | #define CURVATURE 1 // applies barrel distortion to the screen 17 | #endif 18 | 19 | #ifndef SCANLINES 20 | #define SCANLINES 1 // applies horizontal scanline effect 21 | #endif 22 | 23 | #ifndef ROTATE_SCANLINES 24 | #define ROTATE_SCANLINES 0 // for TATE games; also disables the mask effects, which look bad with it 25 | #endif 26 | 27 | #ifndef EXTRA_MASKS 28 | #define EXTRA_MASKS 1 // disable these if you need extra registers freed up 29 | #endif 30 | 31 | //////////////////////////////////////////////////////////////////// 32 | ////////////////////////// END SETTINGS ////////////////////////// 33 | //////////////////////////////////////////////////////////////////// 34 | 35 | // prevent stupid behavior 36 | #if (ROTATE_SCANLINES == 1) && (SCANLINES == 0) 37 | #define SCANLINES 1 38 | #endif 39 | 40 | uniform float video_sizeX < 41 | ui_type = "drag"; 42 | ui_min = 1.0; 43 | ui_max = BUFFER_WIDTH; 44 | ui_label = "Frame Width [CRT-FakeLottes]"; 45 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 46 | > = 320.0; 47 | 48 | uniform float video_sizeY < 49 | ui_type = "drag"; 50 | ui_min = 1.0; 51 | ui_max = BUFFER_HEIGHT; 52 | ui_label = "Frame Height [CRT-FakeLottes]"; 53 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 54 | > = 240.0; 55 | 56 | uniform float shadowMask < 57 | ui_type = "drag"; 58 | ui_min = 0.0; 59 | ui_max = 4.0; 60 | ui_step = 1.0; 61 | ui_label = "shadowMask [CRT-FakeLottes]"; 62 | > = 1.0; 63 | 64 | uniform float SCANLINE_SINE_COMP_B < 65 | ui_type = "drag"; 66 | ui_min = 0.0; 67 | ui_max = 1.0; 68 | ui_step = 0.05; 69 | ui_label = "Scanline Intensity [CRT-FakeLottes]"; 70 | > = 0.40; 71 | 72 | uniform float warpX < 73 | ui_type = "drag"; 74 | ui_min = 0.0; 75 | ui_max = 0.125; 76 | ui_step = 0.01; 77 | ui_label = "warpX [CRT-FakeLottes]"; 78 | > = 0.031; 79 | 80 | uniform float warpY < 81 | ui_type = "drag"; 82 | ui_min = 0.0; 83 | ui_max = 0.125; 84 | ui_step = 0.01; 85 | ui_label = "warpY [CRT-FakeLottes]"; 86 | > = 0.041; 87 | 88 | uniform float maskDark < 89 | ui_type = "drag"; 90 | ui_min = 0.0; 91 | ui_max = 2.0; 92 | ui_step = 0.1; 93 | ui_label = "maskDark [CRT-FakeLottes]"; 94 | > = 0.5; 95 | 96 | uniform float maskLight < 97 | ui_type = "drag"; 98 | ui_min = 0.0; 99 | ui_max = 2.0; 100 | ui_step = 0.1; 101 | ui_label = "maskLight [CRT-FakeLottes]"; 102 | > = 1.5; 103 | 104 | uniform float crt_gamma < 105 | ui_type = "drag"; 106 | ui_min = 1.0; 107 | ui_max = 4.0; 108 | ui_step = 0.05; 109 | ui_label = "CRT Gamma [CRT-FakeLottes]"; 110 | > = 2.5; 111 | 112 | uniform float monitor_gamma < 113 | ui_type = "drag"; 114 | ui_min = 1.0; 115 | ui_max = 4.0; 116 | ui_step = 0.05; 117 | ui_label = "Monitor Gamma [CRT-FakeLottes]"; 118 | > = 2.2; 119 | uniform float SCANLINE_SINE_COMP_A < 120 | ui_type = "drag"; 121 | ui_min = 0.0; 122 | ui_max = 0.10; 123 | ui_step = 0.01; 124 | ui_label = "Scanline Sine Comp A [CRT-FakeLottes]"; 125 | > = 0.0; 126 | 127 | uniform float SCANLINE_BASE_BRIGHTNESS < 128 | ui_type = "drag"; 129 | ui_min = 0.0; 130 | ui_max = 1.0; 131 | ui_step = 0.01; 132 | ui_label = "Scanline Base Brightness [CRT-FakeLottes]"; 133 | > = 0.95; 134 | 135 | #define video_size float2(video_sizeX, video_sizeY) 136 | 137 | float4 scanline(float2 coord, float4 frame) { 138 | #if (SCANLINES == 1) 139 | float2 omega = float2(3.1415 * ReShade::ScreenSize.x, 2.0 * 3.1415 * video_size.y); 140 | float2 sine_comp = float2(SCANLINE_SINE_COMP_A, SCANLINE_SINE_COMP_B); 141 | float3 res = frame.xyz; 142 | #if(ROTATE_SCANLINES == 1) 143 | sine_comp = sine_comp.yx; 144 | omega = omega.yx; 145 | #endif 146 | float3 scanline = res * (SCANLINE_BASE_BRIGHTNESS + dot(sine_comp * sin(coord * omega), float2(1.0, 1.0))); 147 | 148 | return float4(scanline.x, scanline.y, scanline.z, 1.0); 149 | #else 150 | return frame; 151 | #endif 152 | } 153 | 154 | #if (CURVATURE == 1) 155 | // Distortion of scanlines, and end of screen alpha. 156 | float2 Warp(float2 pos) 157 | { 158 | pos = pos*2.0-1.0; 159 | pos *= float2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY); 160 | 161 | return pos*0.5 + 0.5; 162 | } 163 | #endif 164 | 165 | #if (MASK == 1) && (ROTATE_SCANLINES == 0) 166 | // Shadow mask. 167 | float4 Mask(float2 pos) 168 | { 169 | float3 mask = float3(maskDark, maskDark, maskDark); 170 | 171 | // Very compressed TV style shadow mask. 172 | if (shadowMask == 1.0) 173 | { 174 | float line = maskLight; 175 | float odd = 0.0; 176 | 177 | if (frac(pos.x*0.166666666) < 0.5) odd = 1.0; 178 | if (frac((pos.y + odd) * 0.5) < 0.5) line = maskDark; 179 | 180 | pos.x = frac(pos.x*0.333333333); 181 | 182 | if (pos.x < 0.333) mask.r = maskLight; 183 | else if (pos.x < 0.666) mask.g = maskLight; 184 | else mask.b = maskLight; 185 | mask*=line; 186 | } 187 | 188 | // Aperture-grille. 189 | else if (shadowMask == 2.0) 190 | { 191 | pos.x = frac(pos.x*0.333333333); 192 | 193 | if (pos.x < 0.333) mask.r = maskLight; 194 | else if (pos.x < 0.666) mask.g = maskLight; 195 | else mask.b = maskLight; 196 | } 197 | #if (EXTRA_MASKS == 1) 198 | // These can cause moire with curvature and scanlines 199 | // so they're an easy target for freeing up registers 200 | 201 | // Stretched VGA style shadow mask (same as prior shaders). 202 | else if (shadowMask == 3.0) 203 | { 204 | pos.x += pos.y*3.0; 205 | pos.x = frac(pos.x*0.166666666); 206 | 207 | if (pos.x < 0.333) mask.r = maskLight; 208 | else if (pos.x < 0.666) mask.g = maskLight; 209 | else mask.b = maskLight; 210 | } 211 | 212 | // VGA style shadow mask. 213 | else if (shadowMask == 4.0) 214 | { 215 | pos.xy = floor(pos.xy*float2(1.0, 0.5)); 216 | pos.x += pos.y*3.0; 217 | pos.x = frac(pos.x*0.166666666); 218 | 219 | if (pos.x < 0.333) mask.r = maskLight; 220 | else if (pos.x < 0.666) mask.g = maskLight; 221 | else mask.b = maskLight; 222 | } 223 | #endif 224 | 225 | else mask = float3(1.,1.,1.); 226 | 227 | return float4(mask, 1.0); 228 | } 229 | #endif 230 | 231 | float4 PS_CRTFakeLottes(float4 vpos : SV_Position, float2 txcoord : TexCoord) : SV_Target 232 | { 233 | float4 col; 234 | #if (CURVATURE == 1) 235 | float2 pos = Warp(txcoord.xy); 236 | #else 237 | float2 pos = txcoord.xy; 238 | #endif 239 | 240 | #if (MASK == 1) && (ROTATE_SCANLINES == 0) 241 | // mask effects look bad unless applied in linear gamma space 242 | float4 in_gamma = float4(monitor_gamma, monitor_gamma, monitor_gamma, 1.0); 243 | float4 out_gamma = float4(1.0 / crt_gamma, 1.0 / crt_gamma, 1.0 / crt_gamma, 1.0); 244 | float4 res = pow(tex2D(ReShade::BackBuffer, pos), in_gamma); 245 | #else 246 | float4 res = tex2D(ReShade::BackBuffer, pos); 247 | #endif 248 | 249 | #if (MASK == 1) && (ROTATE_SCANLINES == 0) 250 | // apply the mask; looks bad with vert scanlines so make them mutually exclusive 251 | res *= Mask(txcoord * ReShade::ScreenSize.xy * 1.0001); 252 | #endif 253 | 254 | #if (MASK == 1) && (ROTATE_SCANLINES == 0) 255 | // re-apply the gamma curve for the mask path 256 | col = pow(scanline(pos, res), out_gamma); 257 | #else 258 | col = scanline(pos, res); 259 | #endif 260 | 261 | return col; 262 | } 263 | 264 | technique CRTFakeLottes { 265 | pass CRT_FakeLottes { 266 | VertexShader=PostProcessVS; 267 | PixelShader=PS_CRTFakeLottes; 268 | } 269 | } -------------------------------------------------------------------------------- /Shaders/CRTKurg.fx: -------------------------------------------------------------------------------- 1 | /* 2 | CRT shader 3 | 4 | Copyright (C) 2014 kurg, SKR! 5 | 6 | This program is free software; you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by the Free 8 | Software Foundation; either version 2 of the License, or (at your option) 9 | any later version. 10 | */ 11 | 12 | #include "ReShade.fxh" 13 | 14 | uniform float display_sizeX < 15 | ui_type = "drag"; 16 | ui_min = 1.0; 17 | ui_max = BUFFER_WIDTH; 18 | ui_step = 1.0; 19 | ui_label = "Screen Width [CRT-KurgV2]"; 20 | > = 320.0; 21 | 22 | uniform float display_sizeY < 23 | ui_type = "drag"; 24 | ui_min = 1.0; 25 | ui_max = BUFFER_HEIGHT; 26 | ui_step = 1.0; 27 | ui_label = "Screen Height [CRT-KurgV2]"; 28 | > = 240.0; 29 | 30 | #define ILLUMASPECT 2.4 31 | #define DIST(dx, dy) clamp((2.0 - sqrt(dx*dx+(dy*ILLUMASPECT)*(dy*ILLUMASPECT))) / 2.0, 0.0, 1.0) 32 | #define ATT(dx, dy) DIST(dx, pow(dy, 1.3) * 0.6) 33 | 34 | float4 PS_CRTKurg(float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 35 | { 36 | float4 col = tex2D(ReShade::BackBuffer, texcoord.xy); 37 | float2 rubyTextureSize = float2(display_sizeX / 1.0, display_sizeY / 2.0); 38 | float vert_column = texcoord.s * rubyTextureSize.x; 39 | float horz_line = texcoord.t * rubyTextureSize.y; 40 | float dx1 = frac(vert_column); 41 | float dy1 = frac(horz_line); 42 | 43 | float2 texel; 44 | texel.x = texcoord.s - dx1/rubyTextureSize.x + 1.0/rubyTextureSize.x/2.0; 45 | texel.y = texcoord.t - dy1/rubyTextureSize.y + 1.0/rubyTextureSize.y/2.0; 46 | float4 rgb1 = tex2D(ReShade::BackBuffer, texel.xy); 47 | float4 rgb2 = tex2D(ReShade::BackBuffer, float2(texel.s + 1.0/rubyTextureSize.x, texel.t)); 48 | float4 rgb3 = tex2D(ReShade::BackBuffer, float2(texel.s, texel.t + 1.0/rubyTextureSize.y)); 49 | float4 rgb4 = tex2D(ReShade::BackBuffer, float2(texel.s + 1.0/rubyTextureSize.x, texel.t + 1.0/rubyTextureSize.y)); 50 | 51 | float4 rgb5 = tex2D(ReShade::BackBuffer, float2(texel.s - 1.0/rubyTextureSize.x, texel.t - 1.0/rubyTextureSize.y)); 52 | float4 rgb6 = tex2D(ReShade::BackBuffer, float2(texel.s + 0.0/rubyTextureSize.x, texel.t - 1.0/rubyTextureSize.y)); 53 | float4 rgb7 = tex2D(ReShade::BackBuffer, float2(texel.s + 1.0/rubyTextureSize.x, texel.t - 1.0/rubyTextureSize.y)); 54 | float4 rgb8 = tex2D(ReShade::BackBuffer, float2(texel.s + 2.0/rubyTextureSize.x, texel.t - 1.0/rubyTextureSize.y)); 55 | 56 | float4 rgb9 = tex2D(ReShade::BackBuffer, float2(texel.s - 1.0/rubyTextureSize.x, texel.t + 0.0/rubyTextureSize.y)); 57 | float4 rgb10 = tex2D(ReShade::BackBuffer, float2(texel.s + 2.0/rubyTextureSize.x, texel.t + 0.0/rubyTextureSize.y)); 58 | float4 rgb11 = tex2D(ReShade::BackBuffer, float2(texel.s - 1.0/rubyTextureSize.x, texel.t + 1.0/rubyTextureSize.y)); 59 | float4 rgb12 = tex2D(ReShade::BackBuffer, float2(texel.s + 2.0/rubyTextureSize.x, texel.t + 1.0/rubyTextureSize.y)); 60 | 61 | float4 rgb13 = tex2D(ReShade::BackBuffer, float2(texel.s - 1.0/rubyTextureSize.x, texel.t + 2.0/rubyTextureSize.y)); 62 | float4 rgb14 = tex2D(ReShade::BackBuffer, float2(texel.s + 0.0/rubyTextureSize.x, texel.t + 2.0/rubyTextureSize.y)); 63 | float4 rgb15 = tex2D(ReShade::BackBuffer, float2(texel.s + 1.0/rubyTextureSize.x, texel.t + 2.0/rubyTextureSize.y)); 64 | float4 rgb16 = tex2D(ReShade::BackBuffer, float2(texel.s + 2.0/rubyTextureSize.x, texel.t + 2.0/rubyTextureSize.y)); 65 | 66 | float4x4 dist; 67 | dist[0][0] = DIST(dx1, dy1); 68 | dist[0][1] = DIST((1.0 - dx1), dy1); 69 | dist[0][2] = DIST(dx1, (1.0 - dy1)); 70 | dist[0][3] = DIST((1.0 - dx1), (1.0 - dy1)); 71 | 72 | dist[1][0] = DIST((1.0 + dx1), (1.0 + dy1)); 73 | dist[1][1] = DIST((0.0 + dx1), (1.0 + dy1)); 74 | dist[1][2] = DIST((1.0 - dx1), (1.0 + dy1)); 75 | dist[1][3] = DIST((2.0 - dx1), (1.0 + dy1)); 76 | 77 | dist[2][0] = DIST((1.0 + dx1), dy1); 78 | dist[2][1] = DIST((2.0 - dx1), dy1); 79 | dist[2][2] = DIST((1.0 + dx1), (1.0 - dy1)); 80 | dist[2][3] = DIST((2.0 - dx1), (1.0 - dy1)); 81 | 82 | dist[3][0] = DIST((1.0 + dx1), (2.0 - dy1)); 83 | dist[3][1] = DIST((0.0 + dx1), (2.0 - dy1)); 84 | dist[3][2] = DIST((1.0 - dx1), (2.0 - dy1)); 85 | dist[3][3] = DIST((2.0 - dx1), (2.0 - dy1)); 86 | 87 | float4 tex1 = (rgb1*dist[0][0] + rgb2*dist[0][1] + rgb3*dist[0][2] + rgb4*dist[0][3]); 88 | float4 tex2 = (rgb5*dist[1][0] + rgb6*dist[1][1] + rgb7*dist[1][2] + rgb8*dist[1][3]); 89 | float4 tex3 = (rgb9*dist[2][0] + rgb10*dist[2][1] + rgb11*dist[2][2] + rgb12*dist[2][3]); 90 | float4 tex4 = (rgb13*dist[3][0] + rgb14*dist[3][1] + rgb15*dist[3][2] + rgb16*dist[3][3]); 91 | 92 | float4 tex = (tex1 + tex2 + tex3 + tex4 + ((rgb9+rgb11)/2.0)*0.3) / 2.0; 93 | col = float4(tex.rgb, 1.0); 94 | return col; 95 | } 96 | 97 | technique CRTKurgV2 { 98 | pass CRTKurgV2 { 99 | VertexShader=PostProcessVS; 100 | PixelShader=PS_CRTKurg; 101 | } 102 | } -------------------------------------------------------------------------------- /Shaders/CRTPotatoCool.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /////////////////////////////////////////////////////////////////////////// 4 | // // 5 | // Copyright (C) 2017 - Brad Parker // 6 | // // 7 | // This program is free software: you can redistribute it and/or modify // 8 | // it under the terms of the GNU General Public License as published by // 9 | // the Free Software Foundation, either version 3 of the License, or // 10 | // (at your option) any later version. // 11 | // // 12 | // This program is distributed in the hope that it will be useful, // 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of // 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 15 | // GNU General Public License for more details. // 16 | // // 17 | // You should have received a copy of the GNU General Public License // 18 | // along with this program. If not, see . // 19 | // // 20 | /////////////////////////////////////////////////////////////////////////// 21 | 22 | uniform float texture_sizeX < 23 | ui_type = "drag"; 24 | ui_min = 1.0; 25 | ui_max = BUFFER_WIDTH; 26 | ui_label = "Screen Width [CRT-Potato]"; 27 | ui_step = 1.0; 28 | > = 320.0; 29 | 30 | uniform float texture_sizeY < 31 | ui_type = "drag"; 32 | ui_min = 1.0; 33 | ui_max = BUFFER_HEIGHT; 34 | ui_label = "Screen Height [CRT-Potato]"; 35 | ui_step = 1.0; 36 | > = 240.0; 37 | 38 | //Stuff 39 | #define texture_size float2(texture_sizeX, texture_sizeY) 40 | 41 | texture tMaskThin { Width=2; Height=5;}; 42 | sampler sMaskThin { 43 | Texture = tMaskThin; 44 | MinFilter = POINT; 45 | MagFilter = POINT; 46 | AddressU = REPEAT; 47 | AddressV = REPEAT; 48 | AddressW = REPEAT; 49 | }; 50 | 51 | float4 PS_CRTPotatoCool(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target 52 | { 53 | float2 tiles_per_screen = texture_size / tex2Dsize(sMaskThin); 54 | float2 mask_coord = frac(uv * tiles_per_screen); 55 | 56 | float3 base_col = tex2D(ReShade::BackBuffer, uv).rgb; 57 | float3 mask_col = tex2D(sMaskThin, mask_coord).rgb; 58 | return float4(mask_col * base_col, 1.0); 59 | } 60 | 61 | technique CRTPotatoCool { 62 | pass CRTPotatoCool { 63 | VertexShader=PostProcessVS; 64 | PixelShader=PS_CRTPotatoCool; 65 | } 66 | } -------------------------------------------------------------------------------- /Shaders/CRTPotatoWarm.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /////////////////////////////////////////////////////////////////////////// 4 | // // 5 | // Copyright (C) 2017 - Brad Parker // 6 | // // 7 | // This program is free software: you can redistribute it and/or modify // 8 | // it under the terms of the GNU General Public License as published by // 9 | // the Free Software Foundation, either version 3 of the License, or // 10 | // (at your option) any later version. // 11 | // // 12 | // This program is distributed in the hope that it will be useful, // 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of // 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 15 | // GNU General Public License for more details. // 16 | // // 17 | // You should have received a copy of the GNU General Public License // 18 | // along with this program. If not, see . // 19 | // // 20 | /////////////////////////////////////////////////////////////////////////// 21 | 22 | uniform float texture_sizeX < 23 | ui_type = "drag"; 24 | ui_min = 1.0; 25 | ui_max = BUFFER_WIDTH; 26 | ui_label = "Screen Width [CRT-Potato]"; 27 | ui_step = 1.0; 28 | > = 320.0; 29 | 30 | uniform float texture_sizeY < 31 | ui_type = "drag"; 32 | ui_min = 1.0; 33 | ui_max = BUFFER_HEIGHT; 34 | ui_label = "Screen Height [CRT-Potato]"; 35 | ui_step = 1.0; 36 | > = 240.0; 37 | 38 | //Stuff 39 | #define texture_size float2(texture_sizeX, texture_sizeY) 40 | 41 | texture tMaskThick { Width=2; Height=5;}; 42 | sampler sMaskThick { 43 | Texture=tMaskThick; 44 | MinFilter=POINT; 45 | MagFilter=POINT; 46 | AddressU = REPEAT; 47 | AddressV = REPEAT; 48 | AddressW = REPEAT; 49 | }; 50 | 51 | float4 PS_CRTPotatoWarm(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target 52 | { 53 | float2 tiles_per_screen = texture_size / tex2Dsize(sMaskThick); 54 | float2 mask_coord = frac(uv * tiles_per_screen); 55 | 56 | float3 base_col = tex2D(ReShade::BackBuffer, uv).rgb; 57 | float3 mask_col = tex2D(sMaskThick, mask_coord).rgb; 58 | return float4(mask_col * base_col, 1.0); 59 | } 60 | 61 | technique CRTPotatoWarm { 62 | pass CRTPotatoWarm { 63 | VertexShader=PostProcessVS; 64 | PixelShader=PS_CRTPotatoWarm; 65 | } 66 | } -------------------------------------------------------------------------------- /Shaders/CRTRefresh.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float fRollingFlicker_Factor < 4 | ui_label = "Rolling Flicker Factor [CRTRefresh]"; 5 | ui_type = "drag"; 6 | ui_min = 0.0; 7 | ui_max = 1.0; 8 | > = 0.25; 9 | 10 | uniform float fRollingFlicker_VSyncTime < 11 | ui_label = "Rolling Flicker V Sync Time [CRTRefresh]"; 12 | ui_type = "drag"; 13 | ui_min = -144.0; 14 | ui_max = 144.0; 15 | > = 1.0; 16 | 17 | uniform float fTimer ; 18 | 19 | float fmod(float a, float b) { 20 | float c = frac(abs(a / b)) * abs(b); 21 | return (a < 0) ? -c : c; 22 | } 23 | 24 | float wrap(float f, float f_min, float f_max) { 25 | return (f < f_min) ? (f_max - fmod(f_min - f, f_max - f_min)) : (f_min + fmod(f - f_min, f_max - f_min)); 26 | } 27 | 28 | void RollingFlicker(inout float3 col, float2 uv) { 29 | float t = fTimer * fRollingFlicker_VSyncTime * 0.001; 30 | float y = fmod(-t, 1.0); 31 | float rolling_flicker = uv.y + y; 32 | rolling_flicker = wrap(rolling_flicker, 0.0, 1.0); 33 | col *= lerp(1.0, rolling_flicker, fRollingFlicker_Factor); 34 | } 35 | 36 | float4 PS_RefreshRate (float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 37 | { 38 | float3 rgb = tex2D(ReShade::BackBuffer, texcoord).rgb; 39 | RollingFlicker(rgb,texcoord); 40 | return float4(rgb,1.0); 41 | } 42 | 43 | technique CRTRefresh 44 | { 45 | pass RefreshPass 46 | { 47 | VertexShader = PostProcessVS; 48 | PixelShader = PS_RefreshRate; 49 | } 50 | } -------------------------------------------------------------------------------- /Shaders/CRTcgwg.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | cgwg's CRT shader 5 | 6 | Copyright (C) 2010-2011 cgwg, Themaister 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | 13 | (cgwg gave their consent to have their code distributed under the GPL in 14 | this message: 15 | 16 | http://board.byuu.org/viewtopic.php?p=26075#p26075 17 | 18 | "Feel free to distribute my shaders under the GPL. After all, the 19 | barrel distortion code was taken from the Curvature shader, which is 20 | under the GPL." 21 | ) 22 | */ 23 | 24 | uniform float texture_sizeX < 25 | ui_type = "drag"; 26 | ui_min = 1.0; 27 | ui_max = BUFFER_WIDTH; 28 | ui_label = "Screen Width [CRT-cgwg]"; 29 | > = 320.0; 30 | 31 | uniform float texture_sizeY < 32 | ui_type = "drag"; 33 | ui_min = 1.0; 34 | ui_max = BUFFER_HEIGHT; 35 | ui_label = "Screen Height [CRT-cgwg]"; 36 | > = 240.0; 37 | 38 | uniform float video_sizeX < 39 | ui_type = "drag"; 40 | ui_min = 1.0; 41 | ui_max = BUFFER_WIDTH; 42 | ui_label = "Frame Width [CRT-cgwg]"; 43 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 44 | > = 320.0; 45 | 46 | uniform float video_sizeY < 47 | ui_type = "drag"; 48 | ui_min = 1.0; 49 | ui_max = BUFFER_HEIGHT; 50 | ui_label = "Frame Height [CRT-cgwg]"; 51 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 52 | > = 240.0; 53 | 54 | uniform float CRTCGWG_GAMMA < 55 | ui_type = "drag"; 56 | ui_min = 0.0; 57 | ui_max = 10.0; 58 | ui_step = 0.01; 59 | ui_label = "Gamma [CRT-cgwg]"; 60 | > = 2.7; 61 | 62 | float fmod(float a, float b) 63 | { 64 | float c = frac(abs(a/b))*abs(b); 65 | return (a < 0) ? -c : c; /* if ( a < 0 ) c = 0-c */ 66 | } 67 | 68 | #define TEX2D(c) tex2D(ReShade::BackBuffer,(c)) 69 | #define PI 3.141592653589 70 | #define texture_size float2(texture_sizeX, texture_sizeY) 71 | #define video_size float2(video_sizeX, video_sizeY) 72 | 73 | float4 PS_CRTcgwg(float4 vpos : SV_Position, float2 uv : TexCoord) : SV_Target 74 | { 75 | 76 | float2 delta = 1.0 / texture_size; 77 | float dx = delta.x; 78 | float dy = delta.y; 79 | 80 | float2 c01 = uv + float2(-dx, 0.0); 81 | float2 c11 = uv + float2(0.0, 0.0); 82 | float2 c21 = uv + float2(dx, 0.0); 83 | float2 c31 = uv + float2(2.0 * dx, 0.0); 84 | float2 c02 = uv + float2(-dx, dy); 85 | float2 c12 = uv + float2(0.0, dy); 86 | float2 c22 = uv + float2(dx, dy); 87 | float2 c32 = uv + float2(2.0 * dx, dy); 88 | float mod_factor = uv.x * ReShade::ScreenSize.x * texture_size.x / video_size.x; 89 | float2 ratio_scale = uv * texture_size; 90 | 91 | 92 | float2 uv_ratio = frac(ratio_scale); 93 | float4 col, col2; 94 | 95 | float4x4 texes0 = float4x4((TEX2D(c01).xyz),0.0, (TEX2D(c11).xyz),0.0, (TEX2D(c21).xyz),0.0, (TEX2D(c31).xyz),0.0); 96 | float4x4 texes1 = float4x4((TEX2D(c02).xyz),0.0, (TEX2D(c12).xyz),0.0, (TEX2D(c22).xyz),0.0, (TEX2D(c32).xyz),0.0); 97 | 98 | float4 coeffs = float4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x) + 0.005; 99 | coeffs = sin(PI * coeffs) * sin(0.5 * PI * coeffs) / (coeffs * coeffs); 100 | coeffs = coeffs / dot(coeffs, float(1.0)); 101 | 102 | float3 weights = float3(3.33 * uv_ratio.y, 3.33 * uv_ratio.y, 3.33 * uv_ratio.y); 103 | float3 weights2 = float3(uv_ratio.y * -3.33 + 3.33, uv_ratio.y * -3.33 + 3.33, uv_ratio.y * -3.33 + 3.33); 104 | 105 | col = saturate(mul(coeffs, texes0)); 106 | col2 = saturate(mul(coeffs, texes1)); 107 | 108 | float3 wid = 2.0 * pow(col, float4(4.0, 4.0, 4.0, 0.0)) + 2.0; 109 | float3 wid2 = 2.0 * pow(col2, float4(4.0, 4.0, 4.0, 0.0)) + 2.0; 110 | 111 | col = pow(col, float4(CRTCGWG_GAMMA, CRTCGWG_GAMMA, CRTCGWG_GAMMA,0.0)); 112 | col2 = pow(col2, float4(CRTCGWG_GAMMA, CRTCGWG_GAMMA, CRTCGWG_GAMMA,0.0)); 113 | 114 | float3 sqrt1 = rsqrt(0.5 * wid); 115 | float3 sqrt2 = rsqrt(0.5 * wid2); 116 | 117 | float3 pow_mul1 = weights * sqrt1; 118 | float3 pow_mul2 = weights2 * sqrt2; 119 | 120 | float3 div1 = 0.1320 * wid + 0.392; 121 | float3 div2 = 0.1320 * wid2 + 0.392; 122 | 123 | float3 pow1 = -pow(pow_mul1, wid); 124 | float3 pow2 = -pow(pow_mul2, wid2); 125 | 126 | weights = exp(pow1) / div1; 127 | weights2 = exp(pow2) / div2; 128 | 129 | float3 multi = col * weights + col2 * weights2; 130 | float3 mcol = lerp(float3(1.0, 0.7, 1.0), float3(0.7, 1.0, 0.7), floor(fmod(mod_factor, 2.0))); 131 | 132 | return float4(pow(mcol * multi, float3(0.454545, 0.454545, 0.454545)), 1.0); 133 | } 134 | 135 | technique cgwgCRT { 136 | pass CRT_cgwg_fast { 137 | VertexShader=PostProcessVS; 138 | PixelShader=PS_CRTcgwg; 139 | } 140 | } -------------------------------------------------------------------------------- /Shaders/Cathode.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | //Cathode by nimitz (twitter: @stormoid) 4 | //2017 nimitz All rights reserved 5 | 6 | /* 7 | CRT simulation shadowmask style, I also have a trinitron version 8 | optimized for 4X scaling on a ~100ppi display. 9 | 10 | The "Scanlines" seen in the simulated picture are only a side effect of the phoshor placement 11 | and decay, instead of being artificially added on at the last step. This has the advantage 12 | 13 | I have done some testing and it performs especially well with "hard" input such a faked 14 | (dither based) transparency and faked specular highlights as seen in the bigger sprite. 15 | A version tweaked and made for 4k displays could look pretty close to the real thing. 16 | */ 17 | 18 | uniform float resSize < 19 | ui_type = "drag"; 20 | ui_min = 1.0; 21 | ui_max = 20.0; 22 | ui_step = 1.0; 23 | ui_label = "Resolution Size [Cathode]"; 24 | ui_tooltip = "Size of the scanlines."; 25 | > = 4.0; 26 | 27 | #define mod(x,y) (x-y*floor(x/y)) 28 | 29 | //Phosphor decay 30 | float decay(in float d) 31 | { 32 | return lerp(exp2(-d*d*2.5-.3),0.05/(d*d*d*0.45+0.055),.65)*0.99; 33 | } 34 | 35 | //Phosphor shape 36 | float sqd(in float2 a, in float2 b) 37 | { 38 | a -= b; 39 | a *= float2(1.25,1.8)*.905; 40 | float d = max(abs(a.x), abs(a.y)); 41 | d = lerp(d, length(a*float2(1.05, 1.))*0.85, .3); 42 | return d; 43 | } 44 | 45 | float3 phosphors(in float2 p, sampler2D tex, float2 frgCoord) 46 | { 47 | float3 col = float3(0.0,0.0,0.0); 48 | p -= 0.25; 49 | p.y += mod(frgCoord.x,2.)<1.?.03:-0.03; 50 | p.y += mod(frgCoord.x,4.)<2.?.02:-0.02; 51 | 52 | //5x5 kernel (this means a given fragment can be affected by a pixel 4 game pixels away) 53 | for(int i=-2;i<=2;i++) 54 | for(int j=-2;j<=2;j++) 55 | { 56 | float2 tap = floor(p) + 0.5 + float2(i,j); 57 | float3 rez = tex2D(tex, frgCoord.xy).rgb; //nearest neighbor 58 | 59 | //center points 60 | float rd = sqd(tap, p + float2(0.0,0.2));//distance to red dot 61 | const float xoff = .25; 62 | float gd = sqd(tap, p + float2(xoff,.0));//distance to green dot 63 | float bd = sqd(tap, p + float2(-xoff,.0));//distance to blue dot 64 | 65 | rez = pow(rez,float3(1.18,1.18,1.18))*1.08; 66 | rez.r *= decay(rd); 67 | rez.g *= decay(gd); 68 | rez.b *= decay(bd); 69 | 70 | col += rez; 71 | } 72 | return col; 73 | } 74 | 75 | void PS_Cathode(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 frgcol : COLOR0) 76 | { 77 | float2 uv = txcoord.xy * ReShade::ScreenSize.xy; 78 | float2 p = uv.xy/ReShade::ScreenSize.xy; 79 | float2 f = uv.xy; 80 | 81 | float3 col = phosphors(uv.xy/resSize, ReShade::BackBuffer, txcoord.xy); 82 | frgcol = float4(col, 1.0); 83 | } 84 | 85 | technique Cathode { 86 | pass Cathode 87 | { 88 | VertexShader = PostProcessVS; 89 | PixelShader = PS_Cathode; 90 | } 91 | } -------------------------------------------------------------------------------- /Shaders/Chromaticity.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* Filename: chromaticity 4 | 5 | Copyright (C) 2023 W. M. Martinez 6 | splitted and adjusted by DariusG 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | */ 21 | 22 | /* 23 | SMPTE-C/170M used by NTSC and PAL and by SDTV in general. 24 | REC709 used by HDTV in general. 25 | SRGB used by most webcams and computer graphics. ***NOTE***: Gamma 2.4 26 | BT2020 used by Ultra-high definition television (UHDTV) and wide color gamut. 27 | SMPTE240 used during the early days of HDTV (1988-1998). 28 | NTSC1953 used by NTSC at 1953. 29 | EBU used by PAL/SECAM in 1975. Identical to REC601. 30 | */ 31 | 32 | 33 | // RX RY GX GY BX BY RL GL BL TR0 TR TR2 34 | // SMPTE C 0.630 0.340 / 0.310 0.595 / 0.155 0.070 / 0.299 0.587 0.114 / 0.018 0.099 4.5 35 | // REC709 0.640 0.330 / 0.300 0.600 / 0.150 0.060 / 0.212 0.715 0.072 / 0.018 0.099 4.5 36 | // SRGB 0.640 0.330 / 0.300 0.600 / 0.150 0.060 / 0.299 0.587 0.114 / 0.040 0.055 12.92 37 | // BT2020 0.708 0.292 / 0.170 0.797 / 0.131 0.046 / 0.262 0.678 0.059 / 0.059 0.099 4.5 38 | // SMPTE240 0.630 0.340 / 0.310 0.595 / 0.155 0.070 / 0.212 0.701 0.086 / 0.091 0.111 4.0 39 | // NTSC1953 0.670 0.330 / 0.210 0.710 / 0.140 0.080 / 0.210 0.710 0.080 / 0.081 0.099 4.5 40 | // EBU 0.640 0.330 / 0.290 0.600 / 0.150 0.060 / 0.299 0.587 0.114 / 0.081 0.099 4.5 41 | // SECAM 0.640 0.330 / 0.290 0.600 / 0.150 0.060 / 0.334 0.585 0.081 / 0.081 0.099 4.5 42 | 43 | uniform float CHROMA_A_X < 44 | ui_type = "drag"; 45 | ui_min = 0.0; 46 | ui_max = 1.0; 47 | ui_step = 0.001; 48 | ui_label = "Chromaticity R (X) [Chromaticity]"; 49 | > = 0.670; 50 | 51 | uniform float CHROMA_A_Y < 52 | ui_type = "drag"; 53 | ui_min = 0.0; 54 | ui_max = 1.0; 55 | ui_step = 0.001; 56 | ui_label = "Chromaticity R (Y) [Chromaticity]"; 57 | > = 0.330; 58 | 59 | uniform float CHROMA_B_X < 60 | ui_type = "drag"; 61 | ui_min = 0.0; 62 | ui_max = 1.0; 63 | ui_step = 0.001; 64 | ui_label = "Chromaticity G (X) [Chromaticity]"; 65 | > = 0.210; 66 | 67 | uniform float CHROMA_B_Y < 68 | ui_type = "drag"; 69 | ui_min = 0.0; 70 | ui_max = 1.0; 71 | ui_step = 0.001; 72 | ui_label = "Chromaticity G (Y) [Chromaticity]"; 73 | > = 0.710; 74 | 75 | uniform float CHROMA_C_X < 76 | ui_type = "drag"; 77 | ui_min = 0.0; 78 | ui_max = 1.0; 79 | ui_step = 0.001; 80 | ui_label = "Chromaticity B (X) [Chromaticity]"; 81 | > = 0.140; 82 | 83 | uniform float CHROMA_C_Y < 84 | ui_type = "drag"; 85 | ui_min = 0.0; 86 | ui_max = 1.0; 87 | ui_step = 0.001; 88 | ui_label = "Chromaticity B (Y) [Chromaticity]"; 89 | > = 0.080; 90 | 91 | uniform float CHROMA_A_WEIGHT < 92 | ui_type = "drag"; 93 | ui_min = 0.0; 94 | ui_max = 1.0; 95 | ui_step = 0.01; 96 | ui_label = "Chromaticity R luminance weight [Chromaticity]"; 97 | > = 0.299; 98 | 99 | uniform float CHROMA_B_WEIGHT < 100 | ui_type = "drag"; 101 | ui_min = 0.0; 102 | ui_max = 1.0; 103 | ui_step = 0.01; 104 | ui_label = "Chromaticity G luminance weight [Chromaticity]"; 105 | > = 0.587; 106 | 107 | uniform float CHROMA_C_WEIGHT < 108 | ui_type = "drag"; 109 | ui_min = 0.0; 110 | ui_max = 1.0; 111 | ui_step = 0.01; 112 | ui_label = "Chromaticity B luminance weight [Chromaticity]"; 113 | > = 0.114; 114 | 115 | uniform float CRT_TR0 < 116 | ui_type = "drag"; 117 | ui_min = 0.0; 118 | ui_max = 0.2; 119 | ui_step = 0.001; 120 | ui_label = "Transfer Function (0) [Chromaticity]"; 121 | > = 0.018; 122 | 123 | uniform float CRT_TR < 124 | ui_type = "drag"; 125 | ui_min = 0.0; 126 | ui_max = 0.2; 127 | ui_step = 0.001; 128 | ui_label = "Transfer Function (1) [Chromaticity]"; 129 | > = 0.099; 130 | 131 | uniform float CRT_TR2 < 132 | ui_type = "drag"; 133 | ui_min = 3.0; 134 | ui_max = 5.0; 135 | ui_step = 0.05; 136 | ui_label = "Transfer Function (2) [Chromaticity]"; 137 | > = 4.5; 138 | 139 | uniform bool SCALE_W < 140 | ui_type = "bool"; 141 | ui_label = "Scale White Point [Chromaticity]"; 142 | > = true; 143 | 144 | uniform float GAMMAIN < 145 | ui_type = "drag"; 146 | ui_min = 1.0; 147 | ui_max = 4.0; 148 | ui_step = 0.05; 149 | ui_label = "Gamma In [Chromaticity]"; 150 | > = 2.4; 151 | 152 | uniform float GAMMAOUT < 153 | ui_type = "drag"; 154 | ui_min = 1.0; 155 | ui_max = 4.0; 156 | ui_step = 0.05; 157 | ui_label = "Gamma Out [Chromaticity]"; 158 | > = 2.2; 159 | 160 | static const float3 WHITE = float3(1.0, 1.0, 1.0); 161 | 162 | static const float3x3 XYZ_TO_sRGB = float3x3( 163 | 3.2406255, -0.9689307, 0.0557101, 164 | -1.5372080, 1.8758561, -0.2040211, 165 | -0.4986286, 0.0415175, 1.0569959); 166 | 167 | float3x3 colorspace_rgb() 168 | { 169 | return XYZ_TO_sRGB; 170 | } 171 | 172 | 173 | float3 xyY_to_XYZ(const float3 xyY) 174 | { 175 | float x = xyY.x; 176 | float y = xyY.y; 177 | float Y = xyY.z; 178 | float z = 1.0 - x - y; 179 | 180 | return float3(Y * x / y, Y, Y * z / y); 181 | } 182 | 183 | float3 Yrgb_to_RGB(float3x3 toRGB, float3 W, float3 Yrgb) 184 | { 185 | float3x3 xyYrgb = float3x3(CHROMA_A_X, CHROMA_A_Y, Yrgb.r, 186 | CHROMA_B_X, CHROMA_B_Y, Yrgb.g, 187 | CHROMA_C_X, CHROMA_C_Y, Yrgb.b); 188 | float3x3 XYZrgb = float3x3(xyY_to_XYZ(xyYrgb[0]), 189 | xyY_to_XYZ(xyYrgb[1]), 190 | xyY_to_XYZ(xyYrgb[2])); 191 | float3x3 RGBrgb = float3x3(mul(XYZrgb[0],toRGB), 192 | mul(XYZrgb[1],toRGB), 193 | mul(XYZrgb[2],toRGB)); 194 | return float3(dot(W, float3(RGBrgb[0].r, RGBrgb[1].r, RGBrgb[2].r)), 195 | dot(W, float3(RGBrgb[0].g, RGBrgb[1].g, RGBrgb[2].g)), 196 | dot(W, float3(RGBrgb[0].b, RGBrgb[1].b, RGBrgb[2].b))); 197 | } 198 | 199 | 200 | float sdr_linear(const float x) 201 | { 202 | return x < CRT_TR0 ? x / CRT_TR2 : pow((x + CRT_TR) / (1.0+ CRT_TR), GAMMAIN); 203 | } 204 | 205 | float3 sdr_linear(const float3 x) 206 | { 207 | return float3(sdr_linear(x.r), sdr_linear(x.g), sdr_linear(x.b)); 208 | } 209 | 210 | float srgb_gamma(const float x) 211 | { 212 | return x <= 0.0031308 ? 12.92 * x : 1.055 * pow(x, 1.0 / GAMMAOUT) - 0.055; 213 | } 214 | 215 | float3 srgb_gamma(const float3 x) 216 | { 217 | return float3(srgb_gamma(x.r), srgb_gamma(x.g), srgb_gamma(x.b)); 218 | } 219 | 220 | void PS_Chromaticity(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 color : COLOR0) 221 | { 222 | float3x3 toRGB = colorspace_rgb(); 223 | float3 Yrgb = tex2D(ReShade::BackBuffer, txcoord).rgb; 224 | Yrgb = sdr_linear(Yrgb); 225 | float3 W = float3(CHROMA_A_WEIGHT, CHROMA_B_WEIGHT, CHROMA_C_WEIGHT); 226 | float3 RGB = Yrgb_to_RGB(toRGB, W, Yrgb); 227 | if (SCALE_W > 0.0) { 228 | float3 white = Yrgb_to_RGB(toRGB, W, WHITE); 229 | float G = 1.0 / max(max(white.r, white.g), white.b); 230 | 231 | RGB *= G; 232 | } 233 | RGB = clamp(RGB, 0.0, 1.0); 234 | RGB = srgb_gamma(RGB); 235 | color = float4(RGB, 1.0); 236 | } 237 | 238 | technique Chromaticity { 239 | pass Chromaticity_1 { 240 | VertexShader = PostProcessVS; 241 | PixelShader = PS_Chromaticity; 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /Shaders/ChromaticitySimplified.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform int COLOR_MODE < 4 | ui_type = "combo"; 5 | ui_items = "SRGB\0SMPTE C\0REC709\0BT2020\0SMPTE240\0NTSC1953\0EBU\0"; 6 | ui_label = "Color Mode [Cromaticity-Simplified]"; 7 | ui_tooltip = "Change the color standard."; 8 | > = 1; 9 | 10 | uniform int Dx < 11 | ui_type = "combo"; 12 | ui_items = "D50\0D55\0D60\0D65\0D75\0"; 13 | ui_label = "Temperature [Cromaticity-Simplified]"; 14 | ui_tooltip = "Change the color temperature."; 15 | > = 1; 16 | 17 | static const float3 WHITE = float3(1.0, 1.0, 1.0); 18 | 19 | static const float3x3 XYZ_TO_sRGB = float3x3( 20 | 3.2406255, -0.9689307, 0.0557101, 21 | -1.5372080, 1.8758561, -0.2040211, 22 | -0.4986286, 0.0415175, 1.0569959); 23 | 24 | float3x3 colorspace_rgb() 25 | { 26 | return XYZ_TO_sRGB; 27 | } 28 | 29 | 30 | float3 xyY_to_XYZ(const float3 xyY) 31 | { 32 | float x = xyY.x; 33 | float y = xyY.y; 34 | float Y = xyY.z; 35 | float z = 1.0 - x - y; 36 | 37 | return float3(Y * x / y, Y, Y * z / y); 38 | } 39 | 40 | float3 Yrgb_to_RGB(float3x3 toRGB, float3 W, float3 Yrgb) 41 | { 42 | 43 | 44 | //0 SRGB 0.640 0.330 / 0.300 0.600 / 0.150 0.060 -- 45 | //1 SMPTE C 0.630 0.340 / 0.310 0.595 / 0.155 0.070 -- 46 | //2 REC709 0.640 0.330 / 0.300 0.600 / 0.150 0.060 -- 47 | //3 BT2020 0.708 0.292 / 0.170 0.797 / 0.131 0.046 -- 48 | //4 SMPTE240 0.630 0.340 / 0.310 0.595 / 0.155 0.070 -- 49 | //5 NTSC1953 0.670 0.330 / 0.210 0.710 / 0.140 0.080 50 | //6 EBU 0.640 0.330 / 0.290 0.600 / 0.150 0.060 -- 51 | 52 | float CHROMA_A_X, CHROMA_A_Y,CHROMA_B_X, CHROMA_B_Y, CHROMA_C_X, CHROMA_C_Y; 53 | if (COLOR_MODE == 0 || COLOR_MODE == 2 ) 54 | { 55 | CHROMA_A_X=0.64; 56 | CHROMA_A_Y=0.33; 57 | CHROMA_B_X=0.3; 58 | CHROMA_B_Y=0.6; 59 | CHROMA_C_X= 0.15; 60 | CHROMA_C_Y= 0.06; 61 | } 62 | 63 | else if (COLOR_MODE == 1 || COLOR_MODE == 4) 64 | { 65 | CHROMA_A_X=0.63; 66 | CHROMA_A_Y=0.34; 67 | CHROMA_B_X=0.31; 68 | CHROMA_B_Y=0.595; 69 | CHROMA_C_X= 0.155; 70 | CHROMA_C_Y= 0.070; 71 | } 72 | 73 | else if (COLOR_MODE == 3 ) 74 | { 75 | CHROMA_A_X=0.708; 76 | CHROMA_A_Y=0.292; 77 | CHROMA_B_X=0.17; 78 | CHROMA_B_Y=0.797; 79 | CHROMA_C_X= 0.131; 80 | CHROMA_C_Y= 0.046; 81 | } 82 | 83 | else if (COLOR_MODE == 5 ) 84 | { 85 | CHROMA_A_X=0.67; 86 | CHROMA_A_Y=0.33; 87 | CHROMA_B_X=0.21; 88 | CHROMA_B_Y=0.71; 89 | CHROMA_C_X= 0.14; 90 | CHROMA_C_Y= 0.08; 91 | } 92 | 93 | else if (COLOR_MODE == 6) 94 | { 95 | CHROMA_A_X=0.64; 96 | CHROMA_A_Y=0.33; 97 | CHROMA_B_X=0.29; 98 | CHROMA_B_Y=0.60; 99 | CHROMA_C_X= 0.15; 100 | CHROMA_C_Y= 0.06; 101 | } 102 | 103 | float3x3 xyYrgb = float3x3(CHROMA_A_X, CHROMA_A_Y, Yrgb.r, 104 | CHROMA_B_X, CHROMA_B_Y, Yrgb.g, 105 | CHROMA_C_X, CHROMA_C_Y, Yrgb.b); 106 | float3x3 XYZrgb = float3x3(xyY_to_XYZ(xyYrgb[0]), 107 | xyY_to_XYZ(xyYrgb[1]), 108 | xyY_to_XYZ(xyYrgb[2])); 109 | float3x3 RGBrgb = float3x3(mul(XYZrgb[0],toRGB), 110 | mul(XYZrgb[1],toRGB), 111 | mul(XYZrgb[2],toRGB)); 112 | return float3(dot(W, float3(RGBrgb[0].r, RGBrgb[1].r, RGBrgb[2].r)), 113 | dot(W, float3(RGBrgb[0].g, RGBrgb[1].g, RGBrgb[2].g)), 114 | dot(W, float3(RGBrgb[0].b, RGBrgb[1].b, RGBrgb[2].b))); 115 | } 116 | 117 | float3 luminance() 118 | { 119 | //0 SRGB 0.299 0.587 0.114 120 | //1 SMPTE C 0.299 0.587 0.114 121 | //2 REC709 0.212 0.715 0.072 122 | //3 BT2020 0.262 0.678 0.059 123 | //4 SMPTE240 0.212 0.701 0.086 124 | //5 NTSC1953 0.299 0.587 0.114 125 | //6 EBU 0.299 0.587 0.114 126 | 127 | float CHROMA_A_WEIGHT, CHROMA_B_WEIGHT, CHROMA_C_WEIGHT; 128 | if (COLOR_MODE == 0 || COLOR_MODE == 1 || 129 | COLOR_MODE == 5 || COLOR_MODE == 6) 130 | { 131 | CHROMA_A_WEIGHT = 0.299; 132 | CHROMA_B_WEIGHT = 0.587; 133 | CHROMA_C_WEIGHT = 0.114; 134 | } 135 | 136 | else if (COLOR_MODE == 2.0 || COLOR_MODE == 4.0) 137 | { 138 | CHROMA_A_WEIGHT = 0.2126; 139 | CHROMA_B_WEIGHT = 0.7152; 140 | CHROMA_C_WEIGHT = 0.0722; 141 | } 142 | 143 | else if (COLOR_MODE == 3.0 ) 144 | { 145 | CHROMA_A_WEIGHT = 0.2627; 146 | CHROMA_B_WEIGHT = 0.678; 147 | CHROMA_C_WEIGHT = 0.0593; 148 | } 149 | 150 | return float3(CHROMA_A_WEIGHT, CHROMA_B_WEIGHT, CHROMA_C_WEIGHT); 151 | } 152 | 153 | //////////////////////////////////////////////// 154 | /// GAMMA IN FUNCTION ///////////////////////// 155 | 156 | float sdr_linear(const float x) 157 | { 158 | // RX RY GX GY BX BY RL GL BL TR1 TR2 TR3 159 | //0 SRGB 0.040 0.055 12.92 160 | //1 SMPTE C 0.018 0.099 4.5 161 | //2 REC709 0.018 0.099 4.5 162 | //3 BT2020 0.059 0.099 4.5 163 | //4 SMPTE240 0.091 0.111 4.0 164 | //5 NTSC1953 0.018 0.099 4.5 165 | //6 EBU 0.081 0.099 4.5 166 | 167 | float CRT_TR1 ,CRT_TR2, CRT_TR3, GAMMAIN; 168 | 169 | if (COLOR_MODE == 0) 170 | { 171 | CRT_TR1 = 0.04045; 172 | CRT_TR2 = 0.055; 173 | CRT_TR3 = 12.92; 174 | GAMMAIN = 2.4; 175 | } 176 | 177 | else if (COLOR_MODE == 1 || COLOR_MODE == 2) 178 | { 179 | CRT_TR1 = 0.081; 180 | CRT_TR2 = 0.099; 181 | CRT_TR3 = 4.5; 182 | GAMMAIN = 2.2; 183 | } 184 | else if (COLOR_MODE == 3 ) 185 | { 186 | CRT_TR1 = 0.018; 187 | CRT_TR2 = 0.099; 188 | CRT_TR3 = 4.5; 189 | GAMMAIN = 2.2; 190 | } 191 | else if (COLOR_MODE == 4 ) 192 | { 193 | CRT_TR1 = 0.0913; 194 | CRT_TR2 = 0.1115; 195 | CRT_TR3 = 4.0; 196 | GAMMAIN = 2.2; 197 | } 198 | else if (COLOR_MODE == 5 || COLOR_MODE == 6) 199 | { 200 | CRT_TR1 = 0.081; 201 | CRT_TR2 = 0.099; 202 | CRT_TR3 = 4.5; 203 | GAMMAIN = 2.2; 204 | } 205 | 206 | return x < CRT_TR1 ? x / CRT_TR3 : pow((x + CRT_TR2) / (1.0+ CRT_TR2), GAMMAIN); 207 | } 208 | 209 | float3 sdr_linear(const float3 x) 210 | { 211 | return float3(sdr_linear(x.r), sdr_linear(x.g), sdr_linear(x.b)); 212 | } 213 | 214 | 215 | //////////////////////////////////////////////// 216 | /// GAMMA OUT FUNCTION ///////////////////////// 217 | 218 | float srgb_gamma(const float x) 219 | { 220 | //0 SRGB 0.00313 0.055 12.92 221 | //1 SMPTE C 0.018 0.099 4.5 222 | //2 REC709 0.018 0.099 4.5 223 | //3 BT2020 0.059 0.099 4.5 224 | //4 SMPTE240 0.091 0.111 4.0 225 | //5 NTSC1953 0.018 0.099 4.5 226 | //6 EBU 0.081 0.099 4.5 227 | 228 | float LCD_TR1 ,LCD_TR2, LCD_TR3, GAMMAOUT; 229 | 230 | if (COLOR_MODE == 0) 231 | { 232 | LCD_TR1 = 0.00313; 233 | LCD_TR2 = 0.055; 234 | LCD_TR3 = 12.92; 235 | GAMMAOUT = 2.4; 236 | } 237 | 238 | else if (COLOR_MODE == 1 || COLOR_MODE == 2) 239 | { 240 | LCD_TR1 = 0.018; 241 | LCD_TR2 = 0.099; 242 | LCD_TR3 = 4.5; 243 | GAMMAOUT = 2.2; 244 | } 245 | else if (COLOR_MODE == 3 ) 246 | { 247 | LCD_TR1 = 0.018; 248 | LCD_TR2 = 0.099; 249 | LCD_TR3 = 4.5; 250 | GAMMAOUT = 2.2; 251 | } 252 | else if (COLOR_MODE == 4 ) 253 | { 254 | LCD_TR1 = 0.0228; 255 | LCD_TR2 = 0.1115; 256 | LCD_TR3 = 4.0; 257 | GAMMAOUT = 2.2; 258 | } 259 | else if (COLOR_MODE == 5 || COLOR_MODE == 6) 260 | { 261 | LCD_TR1 = 0.018; 262 | LCD_TR2 = 0.099; 263 | LCD_TR3 = 4.5; 264 | GAMMAOUT = 2.2; 265 | } 266 | return x <= LCD_TR1 ? LCD_TR3 * x : (1.0+LCD_TR2) * pow(x, 1.0 / GAMMAOUT) - LCD_TR2; 267 | } 268 | 269 | float3 srgb_gamma(const float3 x) 270 | { 271 | return float3(srgb_gamma(x.r), srgb_gamma(x.g), srgb_gamma(x.b)); 272 | } 273 | 274 | float3 TEMP () 275 | { 276 | if (Dx == 0.0) return float3(0.964,1.0,0.8252); 277 | else if (Dx == 1.0) return float3(0.95682,1.0,0.92149); 278 | else if (Dx == 2.0) return float3(0.95047,1.0,1.0888); 279 | else if (Dx == 3.0) return float3(0.94972,1.0,1.22638); 280 | else return float3(1.0,1.0,1.0); 281 | } 282 | 283 | void PS_ChromaticitySimplified(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 color : COLOR0) 284 | { 285 | float3x3 toRGB = colorspace_rgb(); 286 | float3 Yrgb = tex2D(ReShade::BackBuffer, txcoord).rgb; 287 | Yrgb = sdr_linear(Yrgb); 288 | float3 W = luminance(); 289 | float3 RGB = Yrgb_to_RGB(toRGB, W, Yrgb); 290 | 291 | RGB = clamp(RGB, 0.0, 1.0); 292 | RGB = srgb_gamma(RGB)*TEMP(); 293 | color = float4(RGB, 1.0); 294 | } 295 | 296 | technique ChromaticitySimple { 297 | pass ChromaticitySimple_1 { 298 | VertexShader = PostProcessVS; 299 | PixelShader = PS_ChromaticitySimplified; 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /Shaders/ColorMAME.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float3 RedRatios < 4 | ui_type = "drag"; 5 | ui_min = 0.0; 6 | ui_max = 2.0; 7 | ui_step = 0.001; 8 | ui_label = "Red Output from R,G and B [Color]"; 9 | ui_tooltip = "Each float is a channel."; 10 | > = float3(1.0, 0.0, 0.0); 11 | 12 | uniform float3 GrnRatios < 13 | ui_type = "drag"; 14 | ui_min = 0.0; 15 | ui_max = 2.0; 16 | ui_step = 0.001; 17 | ui_label = "Green Output from R,G and B [Color]"; 18 | ui_tooltip = "Each float is a channel."; 19 | > = float3(0.0, 1.0, 0.0); 20 | 21 | uniform float3 BluRatios < 22 | ui_type = "drag"; 23 | ui_min = 0.0; 24 | ui_max = 2.0; 25 | ui_step = 0.001; 26 | ui_label = "Blue Output from R,G and B [Color]"; 27 | ui_tooltip = "Each float is a channel."; 28 | > = float3(0.0, 0.0, 1.0); 29 | 30 | uniform float3 Offset < 31 | ui_type = "drag"; 32 | ui_min = 0.0; 33 | ui_max = 2.0; 34 | ui_step = 0.001; 35 | ui_label = "Signal Offset [Color]"; 36 | > = float3(0.0, 0.0, 0.0); 37 | 38 | uniform float3 Scale < 39 | ui_type = "drag"; 40 | ui_min = 0.0; 41 | ui_max = 2.0; 42 | ui_step = 0.001; 43 | ui_label = "Signal Scale [Color]"; 44 | > = float3(0.95, 0.95, 0.95); 45 | 46 | uniform float Saturation < 47 | ui_type = "drag"; 48 | ui_min = 0.0; 49 | ui_max = 4.0; 50 | ui_step = 0.001; 51 | ui_label = "Saturation [Color]"; 52 | > = float(1.0); 53 | 54 | uniform float3 Power < 55 | ui_type = "drag"; 56 | ui_min = 0.0; 57 | ui_max = 1.0; 58 | ui_step = 0.001; 59 | ui_label = "Signal Power [Color]"; 60 | > = float3(1.0,1.0,1.0); 61 | 62 | uniform float3 Floor < 63 | ui_type = "drag"; 64 | ui_min = 0.0; 65 | ui_max = 1.0; 66 | ui_step = 0.001; 67 | ui_label = "Signal Floor [Color]"; 68 | > = float3(0.0, 0.0, 0.0); 69 | 70 | float4 PS_ColorMAME(float4 vpos : SV_Position0, float2 texcoord : TEXCOORD0) : SV_Target 71 | { 72 | texcoord += 0.5 / ReShade::ScreenSize.xy; 73 | 74 | float4 BaseTexel = tex2D(ReShade::BackBuffer, texcoord); 75 | 76 | float3 OutRGB = BaseTexel.rgb; 77 | 78 | // RGB Tint & Shift 79 | float ShiftedRed = dot(OutRGB, RedRatios); 80 | float ShiftedGrn = dot(OutRGB, GrnRatios); 81 | float ShiftedBlu = dot(OutRGB, BluRatios); 82 | 83 | // RGB Scale & Offset 84 | float3 OutTexel = float3(ShiftedRed, ShiftedGrn, ShiftedBlu) * Scale + Offset; 85 | 86 | // Saturation 87 | float3 Grayscale = float3(0.299, 0.587, 0.114); 88 | float OutLuma = dot(OutTexel, Grayscale); 89 | float3 OutChroma = OutTexel - OutLuma; 90 | float3 Saturated = OutLuma + OutChroma * Saturation; 91 | 92 | // Color Compression (may not affect bloom), which isn't there. 93 | // increasing the floor of the signal without affecting the ceiling 94 | Saturated.rgb = Floor + (1.0f - Floor) * Saturated.rgb; 95 | 96 | // Color Power (may affect bloom) 97 | Saturated.r = pow(Saturated.r, Power.r); 98 | Saturated.g = pow(Saturated.g, Power.g); 99 | Saturated.b = pow(Saturated.b, Power.b); 100 | 101 | return float4(Saturated, BaseTexel.a); 102 | } 103 | 104 | technique ColorMAME 105 | { 106 | pass ColorMAME_PS1 107 | { 108 | VertexShader = PostProcessVS; 109 | PixelShader = PS_ColorMAME; 110 | } 111 | } -------------------------------------------------------------------------------- /Shaders/DOSGame.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /** 4 | * Dos Game shader by Boris Vorontsov 5 | * enbdev.com/effect_dosgame.zip 6 | */ 7 | 8 | uniform int PIXELSIZE < 9 | ui_type = "drag"; 10 | ui_min = 1; 11 | ui_max = 20; 12 | ui_label = "Pixel Size [DOSGame]"; 13 | ui_step = 1; 14 | > = 2; 15 | 16 | uniform bool ENABLE_SCREENSIZE < 17 | ui_type = "boolean"; 18 | ui_label = "Use Absolute Res [DOSGame]"; 19 | > = true; 20 | 21 | uniform int2 DOSScreenSize < 22 | ui_type = "drag"; 23 | ui_min = 1; 24 | ui_max = 99999; 25 | ui_step = 1; 26 | ui_label = "Screen Resolution [DOSGame]"; 27 | > = int2(320,240); 28 | 29 | uniform bool DOSCOLOR < 30 | ui_type = "boolean"; 31 | ui_label = "Enable Color Banding [DOSGame]"; 32 | > = true; 33 | 34 | uniform int DOSColorsCount < 35 | ui_type = "drag"; 36 | ui_min = 1; 37 | ui_max = 255; 38 | ui_step = 1; 39 | ui_label = "Colors Count [DOSGame]"; 40 | > = 16; 41 | 42 | uniform bool ENABLE_POSTCURVE < 43 | ui_type = "boolean"; 44 | ui_label = "Enable Brightness Curve [DOSGame]"; 45 | > = true; 46 | 47 | uniform float POSTCURVE < 48 | ui_type = "drag"; 49 | ui_min = 0.0; 50 | ui_max = 5.0; 51 | ui_step = 0.001; 52 | ui_label = "Curve Adjustment [DOSGame]"; 53 | > = 0.5; 54 | 55 | uniform bool ENABLE_AGD < 56 | ui_type = "boolean"; 57 | ui_label = "Enable Gamma Adjustment [DOSGame]"; 58 | > = true; 59 | 60 | uniform float DoSgammaValue < 61 | ui_type = "drag"; 62 | ui_min = 0.0; 63 | ui_max = 10.0; 64 | ui_step = 0.001; 65 | ui_label = "Gamma Value [DOSGame]"; 66 | > = 2.2; 67 | 68 | float4 PS_DosFX(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target 69 | { 70 | float2 xs = ReShade::ScreenSize / PIXELSIZE; 71 | 72 | if (ENABLE_SCREENSIZE) xs=DOSScreenSize; 73 | 74 | texcoord.xy=floor(texcoord.xy * xs)/xs; 75 | 76 | float4 origcolor=tex2D(ReShade::BackBuffer, texcoord); 77 | 78 | origcolor+=0.0001; 79 | 80 | if (DOSCOLOR) { 81 | float graymax=max(origcolor.x, max(origcolor.y, origcolor.z)); 82 | float3 ncolor=origcolor.xyz/graymax; 83 | graymax=floor(graymax * DOSColorsCount)/DOSColorsCount; 84 | origcolor.xyz*=graymax; 85 | 86 | if (ENABLE_POSTCURVE) origcolor.xyz = pow(origcolor.xyz, POSTCURVE); 87 | } 88 | 89 | return origcolor; 90 | } 91 | 92 | float4 PS_DosGamma(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target 93 | { 94 | float4 color=tex2D(ReShade::BackBuffer, texcoord); 95 | if (ENABLE_AGD) color.xyz = lerp(color.xyz,-0.0039*pow(1.0/0.0039, 1.0-color.xyz)+1.0,0.7*(DoSgammaValue/2.2)); 96 | return color; 97 | } 98 | 99 | technique DosFX_Tech 100 | { 101 | pass DosFXGammaPass 102 | { 103 | VertexShader = PostProcessVS; 104 | PixelShader = PS_DosGamma; 105 | } 106 | 107 | pass DosFXPass 108 | { 109 | VertexShader = PostProcessVS; 110 | PixelShader = PS_DosFX; 111 | } 112 | } -------------------------------------------------------------------------------- /Shaders/Deconverge.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float3 ConvergeX < 4 | ui_type = "drag"; 5 | ui_min = 0.0; 6 | ui_max = 1.0; 7 | ui_step = 0.001; 8 | ui_label = "Horizontal Convergence [Converge]"; 9 | ui_tooltip = "Convergence on the X Axis"; 10 | > = float3(0.0, 0.0, 0.0); 11 | 12 | uniform float3 ConvergeY < 13 | ui_type = "drag"; 14 | ui_min = 0.0; 15 | ui_max = 1.0; 16 | ui_step = 0.001; 17 | ui_label = "Vertical Convergence [Converge]"; 18 | ui_tooltip = "Convergence on the Y Axis"; 19 | > = float3(0.0, 0.0, 0.0); 20 | 21 | uniform float3 RadialConvergeX < 22 | ui_type = "drag"; 23 | ui_min = 0.0; 24 | ui_max = 1.0; 25 | ui_step = 0.001; 26 | ui_label = "Radial Horizontal Convergence [Converge]"; 27 | ui_tooltip = "Radial convergence on the X Axis"; 28 | > = float3(0.0, 0.0, 0.0); 29 | 30 | uniform float3 RadialConvergeY < 31 | ui_type = "drag"; 32 | ui_min = 0.0; 33 | ui_max = 1.0; 34 | ui_step = 0.001; 35 | ui_label = "Radial Vertical Convergence [Converge]"; 36 | ui_tooltip = "Radial convergence on the Y Axis"; 37 | > = float3(0.0, 0.0, 0.0); 38 | 39 | 40 | //DEV NOTE: Even if they have those options, best to leave them to same or the best looking, since ReShade can't go that deep on injection 41 | uniform float2 ScreenDims < 42 | ui_type = "drag"; 43 | ui_min = 1.0; 44 | ui_max = 100000.0; 45 | ui_step = 1.0; 46 | ui_label = "Screen Dimensions [Converge]"; 47 | ui_tooltip = "Should be your display resolution"; 48 | > = float2(320.0,240.0); 49 | 50 | uniform float2 TargetDims < 51 | ui_type = "drag"; 52 | ui_min = 1.0; 53 | ui_max = 100000.0; 54 | ui_step = 1.0; 55 | ui_label = "Target Dimensions [Converge]"; 56 | ui_tooltip = "Should be your desired or game resolution"; 57 | > = float2(320.0,240.0); 58 | 59 | 60 | float4 PS_Deconverge(float4 vpos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target0 61 | { 62 | vpos.xy /= ReShade::ScreenSize.xy; 63 | vpos.y = 1.0f - texcoord.y; // flip y 64 | vpos.xy -= 0.5f; // center 65 | vpos.xy *= 2.0f; // zoom 66 | 67 | texcoord += 0.5f / TargetDims; // half texel offset correction (DX9) 68 | 69 | // imaginary texel dimensions independed from screen dimension, but ratio 70 | float2 TexelDims = (1.0f / 1024); 71 | 72 | // center coordinates 73 | texcoord.x -= 0.5f; 74 | texcoord.y -= 0.5f; 75 | 76 | // radial converge offset to "translate" the most outer pixel as thay would be translated by the linar converge with the same amount 77 | float2 radialConvergeOffset = 2.0f; 78 | 79 | // radial converge 80 | texcoord.x *= 1.0f + RadialConvergeX * TexelDims.x * radialConvergeOffset.x; 81 | texcoord.y *= 1.0f + RadialConvergeY * TexelDims.y * radialConvergeOffset.y; 82 | 83 | // un-center coordinates 84 | texcoord.x += 0.5f; 85 | texcoord.y += 0.5f; 86 | 87 | // linear converge 88 | texcoord.x += ConvergeX * TexelDims.x; 89 | texcoord.y += ConvergeY * TexelDims.y; 90 | 91 | float3 col = tex2D(ReShade::BackBuffer,texcoord).rgb; 92 | 93 | return float4(col,1.0); 94 | } 95 | 96 | technique Deconverge_MAME 97 | { 98 | pass DeconvergeMAME 99 | { 100 | VertexShader = PostProcessVS; 101 | PixelShader = PS_Deconverge; 102 | } 103 | } -------------------------------------------------------------------------------- /Shaders/Defocus.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float2 Defocus < 4 | ui_type = "drag"; 5 | ui_min = 0.0; 6 | ui_max = 1.0; 7 | ui_step = 0.001; 8 | ui_label = "Defocus [Defocus]"; 9 | ui_tooltip = "X and Y Axis Defocusing"; 10 | > = float2(0.0f, 0.0f); 11 | 12 | // previously this pass was applied two times with offsets of 0.25, 0.5, 0.75, 1.0 13 | // now this pass is applied only once with offsets of 0.25, 0.55, 1.0, 1.6 to achieve the same appearance as before till a maximum defocus of 2.0 14 | static const float2 CoordOffset8[8] = 15 | { 16 | // 0.075x² + 0.225x + 0.25 17 | float2(-1.60f, 0.25f), 18 | float2(-1.00f, -0.55f), 19 | float2(-0.55f, 1.00f), 20 | float2(-0.25f, -1.60f), 21 | float2( 0.25f, 1.60f), 22 | float2( 0.55f, -1.00f), 23 | float2( 1.00f, 0.55f), 24 | float2( 1.60f, -0.25f), 25 | }; 26 | 27 | float4 PS_Defocus(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target 28 | { 29 | // imaginary texel dimensions independed from source and target dimension 30 | float2 TexelDims = (1.0f / 1024.0f); 31 | 32 | float2 DefocusTexelDims = Defocus * TexelDims; 33 | 34 | float3 texel = tex2D(ReShade::BackBuffer, texcoord).rgb; 35 | float samples = 1.0f; 36 | 37 | for (int i = 0; i < 8; i++) 38 | { 39 | texel += tex2D(ReShade::BackBuffer, texcoord + CoordOffset8[i] * DefocusTexelDims).rgb; 40 | samples += 1.0f; 41 | } 42 | 43 | return float4(texel / samples, 1.0f); 44 | } 45 | 46 | technique Defocus 47 | { 48 | pass 49 | { 50 | VertexShader = PostProcessVS; 51 | PixelShader = PS_Defocus; 52 | } 53 | } -------------------------------------------------------------------------------- /Shaders/EGAfilter.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | Downsamples to 16 colors using quantization. 5 | Uses 4-bit RGBI values for an "EGA"/"Tandy" look 6 | 7 | Author: VileR 8 | License: public domain 9 | */ 10 | 11 | // 1.0 is the 'proper' value, 1.2 seems to give better results but brighter 12 | // colors may clip. 13 | #define color_enhance 1.2 14 | 15 | sampler2D SourcePointSampler 16 | { 17 | Texture = ReShade::BackBufferTex; 18 | MinFilter = POINT; 19 | MagFilter = POINT; 20 | MipFilter = POINT; 21 | AddressU = CLAMP; 22 | AddressV = CLAMP; 23 | }; 24 | 25 | float3 nearest_rgbi (float3 original) { 26 | 27 | float3 rgbi_palette[16] = { 28 | float3(0.0, 0.0, 0.0), 29 | float3(0.0, 0.0, 0.66667), 30 | float3(0.0, 0.66667, 0.0), 31 | float3(0.0, 0.66667, 0.66667), 32 | float3(0.66667, 0.0, 0.0), 33 | float3(0.66667, 0.0, 0.66667), 34 | float3(0.66667, 0.33333, 0.0), 35 | float3(0.66667, 0.66667, 0.66667), 36 | float3(0.33333, 0.33333, 0.33333), 37 | float3(0.33333, 0.33333, 1.0), 38 | float3(0.33333, 1.0, 0.33333), 39 | float3(0.33333, 1.0, 1.0), 40 | float3(1.0, 0.33333, 0.33333), 41 | float3(1.0, 0.33333, 1.0), 42 | float3(1.0, 1.0, 0.33333), 43 | float3(1.0, 1.0, 1.0), 44 | }; 45 | 46 | float dst; 47 | float min_dst = 2.0; 48 | int idx = 0; 49 | for (int i=0; i<16; i++) { 50 | dst = distance(original, rgbi_palette[i]); 51 | if (dst < min_dst) { 52 | min_dst = dst; 53 | idx = i; 54 | } 55 | } 56 | return rgbi_palette[idx]; 57 | } 58 | 59 | float4 PS_EGA(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target 60 | { 61 | float3 fragcolor = tex2D(SourcePointSampler, texcoord).rgb; 62 | return float4(nearest_rgbi(fragcolor*color_enhance), 1); 63 | } 64 | 65 | technique EGAfilter 66 | { 67 | pass EGAfilterPass 68 | { 69 | VertexShader = PostProcessVS; 70 | PixelShader = PS_EGA; 71 | } 72 | } -------------------------------------------------------------------------------- /Shaders/GTU.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | //////////////////////////////////////////////////////// 4 | // GTU version 0.50 5 | // Author: aliaspider - aliaspider@gmail.com 6 | // License: GPLv3 7 | // Ported to ReShade by Matsilagi 8 | //////////////////////////////////////////////////////// 9 | 10 | uniform float texture_sizeX < 11 | ui_type = "drag"; 12 | ui_min = 1.0; 13 | ui_max = BUFFER_WIDTH; 14 | ui_label = "Screen Width (GTU)"; 15 | > = 320.0; 16 | 17 | uniform float texture_sizeY < 18 | ui_type = "drag"; 19 | ui_min = 1.0; 20 | ui_max = BUFFER_HEIGHT; 21 | ui_label = "Screen Height (GTU)"; 22 | > = 240.0; 23 | 24 | uniform float video_sizeX < 25 | ui_type = "drag"; 26 | ui_min = 1.0; 27 | ui_max = BUFFER_WIDTH; 28 | ui_label = "Frame Width (GTU)"; 29 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 30 | > = 320.0; 31 | 32 | uniform float video_sizeY < 33 | ui_type = "drag"; 34 | ui_min = 1.0; 35 | ui_max = BUFFER_HEIGHT; 36 | ui_label = "Frame Height (GTU)"; 37 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 38 | > = 240.0; 39 | 40 | uniform bool compositeConnection < 41 | ui_label = "Enables Composite Connection (GTU)"; 42 | > = 0; 43 | 44 | uniform bool noScanlines < 45 | ui_label = "Disables Scanlines (GTU)"; 46 | > = 0; 47 | 48 | uniform float signalResolution < 49 | ui_type = "drag"; 50 | ui_min = 16.0; ui_max = 1024.0; 51 | ui_tooltip = "Signal Resolution Y (GTU)"; 52 | ui_step = 16.0; 53 | > = 256.0; 54 | 55 | uniform float signalResolutionI < 56 | ui_type = "drag"; 57 | ui_min = 1.0; ui_max = 350.0; 58 | ui_tooltip = "Signal Resolution I (GTU)"; 59 | ui_step = 2.0; 60 | > = 83.0; 61 | 62 | uniform float signalResolutionQ < 63 | ui_type = "drag"; 64 | ui_min = 1.0; ui_max = 350.0; 65 | ui_tooltip = "Signal Resolution Q (GTU)"; 66 | ui_step = 2.0; 67 | > = 25.0; 68 | 69 | uniform float tvVerticalResolution < 70 | ui_type = "drag"; 71 | ui_min = 20.0; ui_max = 1000.0; 72 | ui_tooltip = "TV Vertical Resolution (GTU)"; 73 | ui_step = 10.0; 74 | > = 250.0; 75 | 76 | uniform float blackLevel < 77 | ui_type = "drag"; 78 | ui_min = -0.30; ui_max = 0.30; 79 | ui_tooltip = "Black Level (GTU)"; 80 | ui_step = 0.01; 81 | > = 0.07; 82 | 83 | uniform float contrast < 84 | ui_type = "drag"; 85 | ui_min = 0.0; ui_max = 2.0; 86 | ui_tooltip = "Constrast (GTU)"; 87 | ui_step = 0.1; 88 | > = 1.0; 89 | 90 | texture target0_gtu 91 | { 92 | Width = BUFFER_WIDTH; 93 | Height = BUFFER_HEIGHT; 94 | Format = RGBA32F; 95 | }; 96 | sampler s0 { Texture = target0_gtu; }; 97 | 98 | #define _tex2D(sp, uv) tex2Dlod(sp, float4(uv, 0.0, 0.0)) 99 | 100 | #define texture_size float2(texture_sizeX, texture_sizeY) 101 | #define video_size float2(video_sizeX, video_sizeY) 102 | 103 | #define RGB_to_YIQ transpose(float3x3( 0.299 , 0.595716 , 0.211456 , 0.587 , -0.274453 , -0.522591 , 0.114 , -0.321263 , 0.311135 )) 104 | #define pi 3.14159265358 105 | 106 | //PASS 2 107 | #define YIQ_to_RGB transpose(float3x3( 1.0 , 1.0 , 1.0 , 0.9563 , -0.2721 , -1.1070 , 0.6210 , -0.6474 , 1.7046 )) 108 | #define a(x) abs(x) 109 | #define d(x,b) (pi*b*min(a(x)+0.5,1.0/b)) 110 | #define e(x,b) (pi*b*min(max(a(x)-0.5,-1.0/b),1.0/b)) 111 | #define STU(x,b) ((d(x,b)+sin(d(x,b))-e(x,b)-sin(e(x,b)))/(2.0*pi)) 112 | #define X(i) (offset-(i)) 113 | #define GETC (_tex2D(s0, float2(tex.x - X/texture_size.x,tex.y)).rgb) 114 | 115 | #define VAL_composite float3((c.x*STU(X,(signalResolution/video_size.x))),(c.y*STU(X,(signalResolutionI/video_size.x))),(c.z*STU(X,(signalResolutionQ/video_size.x)))) 116 | #define VAL (c*STU(X,(signalResolution/video_size.x))) 117 | 118 | #define PROCESS(i) X=X(i);c=GETC;tempColor+=VAL; 119 | #define PROCESS_composite(i) X=X(i);c=GETC;tempColor+=VAL_composite; 120 | 121 | //PASS 3 122 | #define normalGauss(x) ((exp(-(x)*(x)*0.5))/sqrt(2.0*pi)) 123 | 124 | float normalGaussIntegral(float x) 125 | { 126 | float a1 = 0.4361836; 127 | float a2 = -0.1201676; 128 | float a3 = 0.9372980; 129 | float p = 0.3326700; 130 | float t = 1.0 / (1.0 + p*abs(x)); 131 | return (0.5-normalGauss(x) * (t*(a1 + t*(a2 + a3*t))))*sign(x); 132 | } 133 | 134 | float3 scanlines( float x , float3 c){ 135 | float temp=sqrt(2*pi)*(tvVerticalResolution/texture_sizeY); 136 | 137 | float rrr=0.5*(texture_sizeY/ReShade::ScreenSize.y); 138 | float x1=(x+rrr)*temp; 139 | float x2=(x-rrr)*temp; 140 | c.r=(c.r*(normalGaussIntegral(x1)-normalGaussIntegral(x2))); 141 | c.g=(c.g*(normalGaussIntegral(x1)-normalGaussIntegral(x2))); 142 | c.b=(c.b*(normalGaussIntegral(x1)-normalGaussIntegral(x2))); 143 | c*=(ReShade::ScreenSize.y/texture_sizeY); 144 | return c; 145 | } 146 | 147 | #define Y(j) (offset.y-(j)) 148 | 149 | #define SOURCE(j) float2(tex.x,tex.y - Y(j)/texture_size.y) 150 | #define C(j) (_tex2D(ReShade::BackBuffer, SOURCE(j)).xyz) 151 | 152 | #define VAL_1(j) (C(j)*STU(Y(j),(tvVerticalResolution/video_size.y))) 153 | 154 | #define VAL_scanlines(j) (scanlines(Y(j),C(j))) 155 | 156 | float4 PS_GTU1(float4 vpos : SV_Position, float2 tex : TexCoord) : SV_Target 157 | { 158 | float4 c=tex2D(ReShade::BackBuffer, tex); 159 | if(compositeConnection){ 160 | c.rgb=mul(RGB_to_YIQ,c.rgb); 161 | } 162 | return c; 163 | } 164 | 165 | float4 PS_GTU2(float4 vpos : SV_Position, float2 tex : TexCoord) : SV_Target 166 | { 167 | // return tex2D(s0, tex); 168 | float offset = frac((tex.x * texture_size.x) - 0.5); 169 | float3 tempColor = float3(0.0,0.0,0.0); 170 | float X; 171 | float3 c; 172 | float range; 173 | if (compositeConnection){ 174 | range=ceil(0.5+video_size.x/min(min(signalResolution,signalResolutionI),signalResolutionQ)); 175 | } else { 176 | range=ceil(0.5+video_size.x/signalResolution); 177 | } 178 | 179 | float i; 180 | if(compositeConnection){ 181 | //[loop] 182 | for (i=-range;i = 2.2; 10 | 11 | uniform float ia_monitor_gamma < 12 | ui_type = "drag"; 13 | ui_min = 0.1; 14 | ui_max = 5.0; 15 | ui_step = 0.1; 16 | ui_label = "Monitor Gamma [Image Adjustment]"; 17 | > = 2.2; 18 | 19 | 20 | uniform float ia_overscan_percent_x < 21 | ui_type = "drag"; 22 | ui_min = -25.0; 23 | ui_max = 25.0; 24 | ui_step = 1.0; 25 | ui_label = "Horizontal Overscan % [Image Adjustment]"; 26 | > = 0.0; 27 | 28 | uniform float ia_overscan_percent_y < 29 | ui_type = "drag"; 30 | ui_min = -25.0; 31 | ui_max = 25.0; 32 | ui_step = 1.0; 33 | ui_label = "Vertical Overscan % [Image Adjustment]"; 34 | > = 0.0; 35 | 36 | uniform float ia_saturation < 37 | ui_type = "drag"; 38 | ui_min = 0.0; 39 | ui_max = 2.0; 40 | ui_step = 0.01; 41 | ui_label = "Saturation [Image Adjustment]"; 42 | > = 1.0; 43 | 44 | uniform float ia_contrast < 45 | ui_type = "drag"; 46 | ui_min = 0.0; 47 | ui_max = 10.0; 48 | ui_step = 0.05; 49 | ui_label = "Contrast [Image Adjustment]"; 50 | > = 1.0; 51 | 52 | uniform float ia_luminance < 53 | ui_type = "drag"; 54 | ui_min = 0.0; 55 | ui_max = 2.0; 56 | ui_step = 0.03; 57 | ui_label = "Luminance [Image Adjustment]"; 58 | > = 1.0; 59 | 60 | uniform float ia_black_level < 61 | ui_type = "drag"; 62 | ui_min = -0.30; 63 | ui_max = 0.30; 64 | ui_step = 0.01; 65 | ui_label = "Black Level [Image Adjustment]"; 66 | > = 0.0; 67 | 68 | uniform float ia_bright_boost < 69 | ui_type = "drag"; 70 | ui_min = -1.0; 71 | ui_max = 1.0; 72 | ui_step = 0.05; 73 | ui_label = "Brightness Boost [Image Adjustment]"; 74 | > = 0.0; 75 | 76 | uniform float ia_R < 77 | ui_type = "drag"; 78 | ui_min = 0.0; 79 | ui_max = 2.0; 80 | ui_step = 0.05; 81 | ui_label = "Red Channel [Image Adjustment]"; 82 | > = 1.0; 83 | 84 | uniform float ia_G < 85 | ui_type = "drag"; 86 | ui_min = 0.0; 87 | ui_max = 2.0; 88 | ui_step = 0.05; 89 | ui_label = "Green Channel [Image Adjustment]"; 90 | > = 1.0; 91 | 92 | uniform float ia_B < 93 | ui_type = "drag"; 94 | ui_min = 0.0; 95 | ui_max = 2.0; 96 | ui_step = 0.05; 97 | ui_label = "Blue Channel [Image Adjustment]"; 98 | > = 1.0; 99 | 100 | uniform float ia_ZOOM < 101 | ui_type = "drag"; 102 | ui_min = 0.0; 103 | ui_max = 4.0; 104 | ui_step = 0.01; 105 | ui_label = "Zoom Factor [Image Adjustment]"; 106 | > = 1.0; 107 | 108 | uniform float ia_XPOS < 109 | ui_type = "drag"; 110 | ui_min = -2.0; 111 | ui_max = 2.0; 112 | ui_step = 0.005; 113 | ui_label = "X Modifier [Image Adjustment]"; 114 | > = 0.0; 115 | 116 | uniform float ia_YPOS < 117 | ui_type = "drag"; 118 | ui_min = -2.0; 119 | ui_max = 2.0; 120 | ui_step = 0.005; 121 | ui_label = "Y Modifier [Image Adjustment]"; 122 | > = 0.0; 123 | 124 | uniform float ia_TOPMASK < 125 | ui_type = "drag"; 126 | ui_min = 0.0; 127 | ui_max = 1.0; 128 | ui_step = 0.0025; 129 | ui_label = "Overscan Mask Top [Image Adjustment]"; 130 | > = 0.0; 131 | 132 | uniform float ia_BOTMASK < 133 | ui_type = "drag"; 134 | ui_min = 0.0; 135 | ui_max = 1.0; 136 | ui_step = 0.0025; 137 | ui_label = "Overscan Mask Bottom [Image Adjustment]"; 138 | > = 0.0; 139 | 140 | uniform float ia_LMASK < 141 | ui_type = "drag"; 142 | ui_min = 0.0; 143 | ui_max = 1.0; 144 | ui_step = 0.0025; 145 | ui_label = "Overscan Mask Left [Image Adjustment]"; 146 | > = 0.0; 147 | 148 | uniform float ia_RMASK < 149 | ui_type = "drag"; 150 | ui_min = 0.0; 151 | ui_max = 1.0; 152 | ui_step = 0.0025; 153 | ui_label = "Overscan Mask Right [Image Adjustment]"; 154 | > = 0.0; 155 | 156 | uniform float ia_GRAIN_STR < 157 | ui_type = "drag"; 158 | ui_min = 0.0; 159 | ui_max = 72.0; 160 | ui_step = 6.0; 161 | ui_label = "Film Grain [Image Adjustment]"; 162 | > = 0.0; 163 | 164 | //Tools 165 | 166 | uniform int ia_framecount < source = "framecount"; >; 167 | 168 | float fmod(float a, float b) { 169 | float c = frac(abs(a / b)) * abs(b); 170 | return a < 0 ? -c : c; 171 | } 172 | 173 | #define mod(x,y) (x-y*floor(x/y)) 174 | 175 | //Actual Shader Code 176 | 177 | //https://www.shadertoy.com/view/4sXSWs strength= 16.0 178 | float3 filmGrain(float2 uv, float strength, float frameCount ){ 179 | float x = (uv.x + 4.0 ) * (uv.y + 4.0 ) * ((fmod(frameCount, 800.0) + 10.0) * 10.0); 180 | float v = fmod((mod(x, 13.0) + 1.0) * (fmod(x, 123.0) + 1.0), 0.01)-0.005; 181 | return float3(v, v, v) * strength; 182 | } 183 | 184 | float3 grayscale(float3 col) 185 | { 186 | // ATSC grayscale standard 187 | float b = dot(col, float3(0.2126, 0.7152, 0.0722)); 188 | return float3(b, b, b); 189 | } 190 | 191 | float3 rgb2hsv(float3 c) 192 | { 193 | float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 194 | float4 p = c.g < c.b ? float4(c.bg, K.wz) : float4(c.gb, K.xy); 195 | float4 q = c.r < p.x ? float4(p.xyw, c.r) : float4(c.r, p.yzx); 196 | 197 | float d = q.x - min(q.w, q.y); 198 | float e = 1.0e-10; 199 | return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 200 | } 201 | 202 | float3 hsv2rgb(float3 c) 203 | { 204 | float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 205 | float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); 206 | return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 207 | } 208 | 209 | float4 PS_ImageAdjustment(float4 pos : SV_Position, float2 coords : TEXCOORD0) : SV_Target 210 | { 211 | 212 | float2 shift = 0.5 * ReShade::ScreenSize / ReShade::ScreenSize; 213 | float2 overscan_coord = ((coords - shift) / ia_ZOOM) * (1.0 - float2(ia_overscan_percent_x / 100.0, ia_overscan_percent_y / 100.0)) + shift; 214 | float2 coord_final = overscan_coord + float2(ia_XPOS, ia_YPOS); 215 | 216 | float2 texCoord = coord_final; 217 | 218 | float3 film_grain = filmGrain(texCoord.xy, ia_GRAIN_STR, ia_framecount); 219 | float2 fragcoord = texCoord.xy * (ReShade::ScreenSize.xy / ReShade::ScreenSize.xy); 220 | float3 res = tex2D(ReShade::BackBuffer, texCoord).rgb; // sample the texture 221 | res += film_grain; 222 | float gamma_ratio = ia_monitor_gamma / ia_target_gamma; 223 | float3 gamma = float3(gamma_ratio, gamma_ratio, gamma_ratio); // setup ratio of display's gamma vs desired gamma 224 | 225 | //saturation and luminance 226 | float3 satColor = clamp(hsv2rgb(rgb2hsv(res) * float3(1.0, ia_saturation, ia_luminance)), 0.0, 1.0); 227 | 228 | //contrast and brightness 229 | float3 conColor = clamp((satColor - 0.5) * ia_contrast + 0.5 + ia_bright_boost, 0.0, 1.0); 230 | 231 | conColor -= float3(ia_black_level, ia_black_level, ia_black_level); // apply black level 232 | float min_black = 1.0-ia_black_level; 233 | conColor *= (1.0 / float3(min_black, min_black, min_black)); 234 | conColor = pow(conColor, 1.0 / float3(gamma)); // Apply gamma correction 235 | conColor *= float3(ia_R, ia_G, ia_B); 236 | if (fragcoord.y > ia_TOPMASK && fragcoord.y < (1.0 - ia_BOTMASK)) 237 | conColor = conColor; 238 | else 239 | conColor = 0.0; 240 | 241 | if (fragcoord.x > ia_LMASK && fragcoord.x < (1.0 - ia_RMASK)) 242 | conColor = conColor; 243 | else 244 | conColor = 0.0; 245 | return float4(conColor, 1.0); 246 | } 247 | 248 | technique RA_ImageAdjustment 249 | { 250 | pass ImageAdjustment_1 251 | { 252 | VertexShader = PostProcessVS; 253 | PixelShader = PS_ImageAdjustment; 254 | } 255 | } -------------------------------------------------------------------------------- /Shaders/JPEG.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float fCompressionStrentgh < 4 | ui_type = "drag"; 5 | ui_min = 0.0; 6 | ui_max = 6.0; 7 | ui_step = 0.001; 8 | ui_label = "Compression Strength [JPEG]"; 9 | ui_tooltip = "How compressed the image is."; 10 | > = 1.0; 11 | 12 | texture JPEG0_tex { 13 | Width = BUFFER_WIDTH; 14 | Height = BUFFER_HEIGHT; 15 | Format = RGBA32F; 16 | }; 17 | 18 | sampler sJPEG0 { 19 | Texture = JPEG0_tex; 20 | }; 21 | 22 | #define pi 2.0*asin(1.0) 23 | #define a(x) (x!=0.?1.:1./sqrt(2.)) 24 | 25 | float3 toYCbCr(float3 rgb) 26 | { 27 | float3 RGB2Y = float3( 0.299, 0.587, 0.114); 28 | float3 RGB2Cb = float3(-0.169,-0.331, 0.500); 29 | float3 RGB2Cr = float3(0.500,-0.419,-0.081); 30 | float3 newmat = float3(dot(rgb, RGB2Y), dot(rgb, RGB2Cb), dot(rgb, RGB2Cr)); 31 | float3 addit = float3(0.0,0.5,0.5); 32 | return newmat+addit; 33 | } 34 | 35 | float3 pre( float2 coord ){ 36 | return floor(256.0*(toYCbCr(tex2D(ReShade::BackBuffer, coord/ReShade::ScreenSize.xy).xyz) - .5)); 37 | } 38 | 39 | float3 DCT8x8( float2 coord, float2 uv ) { 40 | float3 res = float3(0,0,0); 41 | for(float x = 0.; x < 8.; x++){ 42 | for(float y = 0.; y < 8.; y++){ 43 | res += pre(coord + float2(x,y)) * 44 | cos((2.*x+1.)*uv.x*pi/16.) * 45 | cos((2.*y+1.)*uv.y*pi/16.); 46 | } 47 | } 48 | return res * .25 * a(uv.x) * a(uv.y); 49 | } 50 | 51 | void PS_JPEG1(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 col : COLOR0) 52 | { 53 | col.w = 0.; 54 | float2 texcoord = txcoord * ReShade::ScreenSize; 55 | float2 uv = floor(texcoord-8.0*floor(texcoord/8.0)); 56 | int CombmA, mA[64] = { 16, 11, 10, 16, 24, 40, 51, 61, 57 | 12, 12, 14, 19, 26, 58, 60, 55, 58 | 14, 13, 16, 24, 40, 57, 69, 56, 59 | 14, 17, 22, 29, 51, 87, 80, 62, 60 | 18, 22, 37, 56, 68, 109, 103, 77, 61 | 24, 35, 55, 64, 81, 104, 113, 92, 62 | 49, 64, 78, 87, 103, 121, 120, 101, 63 | 72, 92, 95, 98, 112, 100, 103, 99 64 | }; 65 | //uv range needs to be set to range of array. from lowest number to max value. 66 | float q = (1.0+fCompressionStrentgh*20.0)*float(CombmA = mA[int(uv.x+uv.y*8.)]); 67 | col.xyz = (floor(.5+DCT8x8(8.*floor(texcoord/8.0),uv)/q))*q; 68 | } 69 | 70 | 71 | float3 toRGB(float3 ybr) { 72 | return mul( float3x3( 73 | 1., 0.00, 1.402, 74 | 1.,-0.344136,-0.714136, 75 | 1., 1.772, 0.00), ybr-float3(0,.5,.5)); 76 | } 77 | 78 | float3 inp(float2 coord){ 79 | return tex2Dfetch(sJPEG0, float4(int2(coord.xy),0,0)).xyz; 80 | } 81 | 82 | float3 IDCT8x8(float2 coord, float2 xy ) { 83 | float3 res = float3(0.0,0.0,0.0); 84 | for(float u = 0.; u < 8.0; u++){ 85 | for(float v = 0.; v < 8.0; v++){ 86 | res += inp(coord + float2(u,v)) * 87 | a(u) * a(v) * 88 | cos((2.*xy.x+1.)*u*pi/16.) * 89 | cos((2.*xy.y+1.)*v*pi/16.); 90 | } 91 | } 92 | return res * .25; 93 | } 94 | 95 | 96 | void PS_JPEG2(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 col : COLOR0) 97 | { 98 | col.w = 0.; 99 | float2 texcoord = txcoord * ReShade::ScreenSize; 100 | float2 uv = floor(texcoord-8.0*floor(texcoord/8.0)); 101 | col.xyz = toRGB(IDCT8x8(8.*floor(texcoord/8.),uv)/256.+.5); 102 | //col.xyz = tex2D(ReShade::BackBuffer, texcoord/ReShade::ScreenSize.xy).xyz; 103 | } 104 | 105 | technique JPEGCompression { 106 | pass JPEG_Base { 107 | VertexShader=PostProcessVS; 108 | PixelShader=PS_JPEG1; 109 | RenderTarget=JPEG0_tex; 110 | } 111 | pass JPEG_Final { 112 | VertexShader=PostProcessVS; 113 | PixelShader=PS_JPEG2; 114 | } 115 | } -------------------------------------------------------------------------------- /Shaders/MCAmber.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform int colors < 4 | ui_type = "drag"; 5 | ui_min = 8; 6 | ui_max = 256; 7 | ui_tooltip = "Display Colors [MC Amber]"; 8 | > = 256; 9 | 10 | float4 PS_MCAmber (float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 11 | { 12 | float3 ink = float3(0.55, 0.41, 0.0); 13 | float3 c11 = tex2D(ReShade::BackBuffer, texcoord).xyz; 14 | float lct = floor(colors*length(c11))/colors; 15 | return float4(lct*ink,1); 16 | } 17 | 18 | technique MCAmber 19 | { 20 | pass MCAmber0 21 | { 22 | VertexShader = PostProcessVS; 23 | PixelShader = PS_MCAmber; 24 | } 25 | } -------------------------------------------------------------------------------- /Shaders/MCGreen.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform int colors < 4 | ui_type = "drag"; 5 | ui_min = 8; 6 | ui_max = 256; 7 | ui_tooltip = "Display Colors [MC Green]"; 8 | > = 256; 9 | 10 | float4 PS_MCGreen (float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 11 | { 12 | float3 ink = float3(0.32, 0.50, 0.0); 13 | float3 c11 = tex2D(ReShade::BackBuffer, texcoord).xyz; 14 | float lct = floor(colors*length(c11))/colors; 15 | return float4(lct*ink,1); 16 | } 17 | 18 | technique MCGreen 19 | { 20 | pass MCGreen0 21 | { 22 | VertexShader = PostProcessVS; 23 | PixelShader = PS_MCGreen; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Shaders/MCOrange.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform int colors < 4 | ui_type = "drag"; 5 | ui_min = 8; 6 | ui_max = 256; 7 | ui_tooltip = "Display Colors [MC Orange]"; 8 | > = 256; 9 | 10 | float4 PS_MCOrange (float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 11 | { 12 | float3 ink = float3(0.57, 0.28, 0.0); 13 | float3 c11 = tex2D(ReShade::BackBuffer, texcoord).xyz; 14 | float lct = floor(colors*length(c11))/colors; 15 | return float4(lct*ink,1); 16 | } 17 | 18 | technique MCOrange 19 | { 20 | pass MCAmber0 21 | { 22 | VertexShader = PostProcessVS; 23 | PixelShader = PS_MCOrange; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Shaders/MMJCelShader.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | MMJ's Cel Shader - v1.03 5 | ---------------------------------------------------------------- 6 | -- 180403 -- 7 | This is a port of my old shader from around 2006 for Pete's OGL2 8 | plugin for ePSXe. It started out as a shader based on the 9 | "CComic" shader by Maruke. I liked his concept, but I was 10 | looking for something a little different in the output. 11 | 12 | Since the last release, I've seen some test screenshots from MAME 13 | using a port of my original shader and have also seen another 14 | port to get it working with the PCSX2 emulator. Having recently 15 | seen some Kingdom Hearts II and Soul Calibur 3 YouTube videos with 16 | my ported shader inspired me to revisit it and get it working in 17 | RetroArch. 18 | 19 | As for this version (1.03), I've made a few small modifications 20 | (such as to remove the OGL2Param references, which were specific 21 | to Pete's plugin) and I added some RetroArch Parameter support, 22 | so some values can now be changed in real time. 23 | 24 | Keep in mind, that this was originally developed for PS1, using 25 | various 3D games as a test. In general, it will look better in 26 | games with less detailed textures, as "busy" textures will lead 27 | to more outlining / messy appearance. Increasing "Outline 28 | Brightness" can help mitigate this some by lessening the 29 | "strength" of the outlines. 30 | 31 | Also (in regards to PS1 - I haven't really tested other systems 32 | too much yet), 1x internal resolution will look terrible. 2x 33 | will also probably be fairly blurry/messy-looking. For best 34 | results, you should probably stick to 4x or higher internal 35 | resolution with this shader. 36 | 37 | Parameters: 38 | ----------- 39 | White Level Cutoff = Anything above this luminance value will be 40 | forced to pure white. 41 | 42 | Black Level Cutoff = Anything below this luminance value will be 43 | forced to pure black. 44 | 45 | Shading Levels = Determines how many color "slices" there should 46 | be (not counting black/white cutoffs, which are always 47 | applied). 48 | 49 | Saturation Modifier = Increase or decrease color saturation. 50 | Default value boosts saturation a little for a more 51 | cartoonish look. Set to 0.00 for grayscale. 52 | 53 | Outline Brightness = Adjusts darkness of the outlines. At a 54 | setting of 1, outlines should be disabled. 55 | 56 | Shader Strength = Adjusts the weight of the color banding 57 | portion of the shader from 0% (0.00) to 100% (1.00). At a 58 | setting of 0.00, you can turn off the color banding effect 59 | altogether, but still keep outlines enabled. 60 | ----------- 61 | MMJuno 62 | */ 63 | 64 | uniform float WhtCutoff < 65 | ui_type = "drag"; 66 | ui_min = 0.50; 67 | ui_max = 1.0; 68 | ui_step = 0.01; 69 | ui_label = "White Level Cutoff [MMJCelShader]"; 70 | > = 0.97; 71 | 72 | uniform float BlkCutoff < 73 | ui_type = "drag"; 74 | ui_min = 0.0; 75 | ui_max = 0.5; 76 | ui_step = 0.01; 77 | ui_label = "Black Level Cutoff [MMJCelShader]"; 78 | > = 0.03; 79 | 80 | uniform float ShdLevels < 81 | ui_type = "drag"; 82 | ui_min = 1.0; 83 | ui_max = 16.0; 84 | ui_step = 1.0; 85 | ui_label = "Shading Levels [MMJCelShader]"; 86 | > = 9.0; 87 | 88 | uniform float SatModify < 89 | ui_type = "drag"; 90 | ui_min = 0.0; 91 | ui_max = 2.0; 92 | ui_step = 0.01; 93 | ui_label = "Saturation Modifier [MMJCelShader]"; 94 | > = 1.15; 95 | 96 | uniform float OtlModify < 97 | ui_type = "drag"; 98 | ui_min = 0.0; 99 | ui_max = 1.0; 100 | ui_step = 0.01; 101 | ui_label = "Outline Brightness [MMJCelShader]"; 102 | > = 0.20; 103 | 104 | uniform float ShdWeight < 105 | ui_type = "drag"; 106 | ui_min = 0.0; 107 | ui_max = 1.0; 108 | ui_step = 0.01; 109 | ui_label = "Shader Strength [MMJCelShader]"; 110 | > = 0.50; 111 | 112 | sampler RetroArchSRGB { Texture = ReShade::BackBufferTex; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; SRGBTexture = true;}; 113 | 114 | #define mod(x,y) (x-y*floor(x/y)) 115 | 116 | float3 RGB2HCV(in float3 RGB) 117 | { 118 | RGB = saturate(RGB); 119 | float Epsilon = 1e-10; 120 | // Based on work by Sam Hocevar and Emil Persson 121 | float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0/3.0) : float4(RGB.gb, 0.0, -1.0/3.0); 122 | float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx); 123 | float C = Q.x - min(Q.w, Q.y); 124 | float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z); 125 | return float3(H, C, Q.x); 126 | } 127 | 128 | float3 RGB2HSL(in float3 RGB) 129 | { 130 | float3 HCV = RGB2HCV(RGB); 131 | float L = HCV.z - HCV.y * 0.5; 132 | float S = HCV.y / (1.0000001 - abs(L * 2 - 1)); 133 | return float3(HCV.x, S, L); 134 | } 135 | 136 | float3 HSL2RGB(in float3 HSL) 137 | { 138 | HSL = saturate(HSL); 139 | //HSL.z *= 0.99; 140 | float3 RGB = saturate(float3(abs(HSL.x * 6.0 - 3.0) - 1.0,2.0 - abs(HSL.x * 6.0 - 2.0),2.0 - abs(HSL.x * 6.0 - 4.0))); 141 | float C = (1 - abs(2 * HSL.z - 1)) * HSL.y; 142 | return (RGB - 0.5) * C + HSL.z; 143 | } 144 | 145 | float3 colorAdjust(float3 cRGB) 146 | { 147 | float3 cHSL = RGB2HSL(cRGB); 148 | 149 | float cr = 1.0 / ShdLevels; 150 | 151 | // brightness modifier 152 | float BrtModify = mod(cHSL[2], cr); 153 | 154 | if (cHSL[2] > WhtCutoff) { cHSL[1] = 1.0; cHSL[2] = 1.0; } 155 | else if(cHSL[2] > BlkCutoff) { cHSL[1] *= SatModify; cHSL[2] += (cHSL[2] * cr - BrtModify); } 156 | else { cHSL[1] = 0.0; cHSL[2] = 0.0; } 157 | cRGB = 1.2 * HSL2RGB(cHSL); 158 | 159 | return cRGB; 160 | } 161 | 162 | void PS_MMJCel(in float4 pos : SV_POSITION, in float2 texcoord : TEXCOORD0, out float4 fragColor : COLOR0) 163 | { 164 | 165 | float2 offset = float2(0.0,0.0); 166 | float2 offset_inv = float2(0.0,0.0); 167 | float2 TEX0 = texcoord.xy; 168 | float2 TEX1 = float2(0.0,0.0); 169 | float2 TEX1_INV = float2(0.0,0.0); 170 | float2 TEX2 = float2(0.0,0.0); 171 | float2 TEX2_INV = float2(0.0,0.0); 172 | float2 TEX3 = float2(0.0,0.0); 173 | float2 TEX3_INV = float2(0.0,0.0); 174 | 175 | offset = -(float2(1.0 / ReShade::ScreenSize.x, 0.0)); //XY 176 | offset_inv = float2(1.0 / ReShade::ScreenSize.x,0.0); //ZW 177 | TEX1 = TEX0 + offset; 178 | TEX1_INV = TEX0 + offset_inv; 179 | 180 | offset = -(float2(0.0,(1.0 / ReShade::ScreenSize.y))); //XY 181 | offset_inv = float2(0.0, (1.0 / ReShade::ScreenSize.y)); //ZW 182 | 183 | TEX2 = TEX0.xy + offset; 184 | TEX2_INV = TEX0.xy + offset_inv; 185 | TEX3 = TEX1.xy + offset; 186 | TEX3_INV = TEX1.xy + offset_inv; 187 | 188 | float3 c0 = tex2D(RetroArchSRGB, TEX3.xy).rgb; 189 | float3 c1 = tex2D(RetroArchSRGB, TEX2.xy).rgb; 190 | float3 c2 = tex2D(RetroArchSRGB, float2(TEX3_INV.x,TEX3.y)).rgb; 191 | float3 c3 = tex2D(RetroArchSRGB, TEX1.xy).rgb; 192 | float3 c4 = tex2D(RetroArchSRGB, TEX0.xy).rgb; 193 | float3 c5 = tex2D(RetroArchSRGB, TEX1_INV.xy).rgb; 194 | float3 c6 = tex2D(RetroArchSRGB, float2(TEX3.x,TEX3_INV.y)).rgb; 195 | float3 c7 = tex2D(RetroArchSRGB, TEX2_INV).rgb; 196 | float3 c8 = tex2D(RetroArchSRGB, TEX3_INV).rgb; 197 | float3 c9 = ((c0 + c2 + c6 + c8) * 0.15 + (c1 + c3 + c5 + c7) * 0.25 + c4) / 2.6; 198 | 199 | float3 o = float3(1.0,1.0,1.0); 200 | float3 h = float3(0.05,0.05,0.05); 201 | float3 hz = h; 202 | float k = 0.005; 203 | float kz = 0.007; 204 | float i = 0.0; 205 | 206 | float3 cz = (c9 + h) / (dot(o, c9) + k); 207 | float3 col = float3(0.0,0.0,0.0); 208 | 209 | hz = (cz - ((c0 + h) / (dot(o, c0) + k))); i = kz / (dot(hz, hz) + kz); 210 | hz = (cz - ((c1 + h) / (dot(o, c1) + k))); i += kz / (dot(hz, hz) + kz); 211 | hz = (cz - ((c2 + h) / (dot(o, c2) + k))); i += kz / (dot(hz, hz) + kz); 212 | hz = (cz - ((c3 + h) / (dot(o, c3) + k))); i += kz / (dot(hz, hz) + kz); 213 | hz = (cz - ((c5 + h) / (dot(o, c5) + k))); i += kz / (dot(hz, hz) + kz); 214 | hz = (cz - ((c6 + h) / (dot(o, c6) + k))); i += kz / (dot(hz, hz) + kz); 215 | hz = (cz - ((c7 + h) / (dot(o, c7) + k))); i += kz / (dot(hz, hz) + kz); 216 | hz = (cz - ((c8 + h) / (dot(o, c8) + k))); i += kz / (dot(hz, hz) + kz); 217 | 218 | i /= 8.0; 219 | i = pow(i, 0.75); 220 | 221 | if(i < OtlModify) { i = OtlModify; } 222 | c9 = min(o, min(c9, c9 + dot(o, c9))); 223 | col = lerp(c4 * i, colorAdjust(c9 * i), ShdWeight); 224 | fragColor = float4(col,1.0); 225 | } 226 | 227 | technique MMJCelShader { 228 | pass MMJCelShader { 229 | VertexShader=PostProcessVS; 230 | PixelShader=PS_MMJCel; 231 | SRGBWriteEnable = true; 232 | } 233 | } -------------------------------------------------------------------------------- /Shaders/MattiasCRT.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | // Loosely based on postprocessing shader by inigo quilez, License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 4 | 5 | uniform float iGlobalTime < source = "timer"; >; 6 | 7 | #define mod(x,y) (x-y*floor(x/y)) 8 | 9 | float2 curve(float2 uv) 10 | { 11 | uv = (uv - 0.5) * 2.0; 12 | uv *= 1.1; 13 | uv.x *= 1.0 + pow((abs(uv.y) / 5.0), 2.0); 14 | uv.y *= 1.0 + pow((abs(uv.x) / 4.0), 2.0); 15 | uv = (uv / 2.0) + 0.5; 16 | uv = uv *0.92 + 0.04; 17 | return uv; 18 | } 19 | 20 | void PS_CRTMattias1(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 fragColor : COLOR0) 21 | { 22 | float2 fragCoord = txcoord * ReShade::ScreenSize; 23 | float2 q = fragCoord.xy / ReShade::ScreenSize.xy; 24 | float2 uv = q; 25 | uv = curve( uv ); 26 | float3 oricol = tex2D( ReShade::BackBuffer, float2(q.x,q.y) ).xyz; 27 | float3 col; 28 | float x = sin(0.3*iGlobalTime*0.001+uv.y*21.0)*sin(0.7*iGlobalTime*0.001+uv.y*29.0)*sin(0.3+0.33*iGlobalTime*0.001+uv.y*31.0)*0.0017; 29 | 30 | col.r = tex2D(ReShade::BackBuffer,float2(x+uv.x+0.001,uv.y+0.001)).x+0.05; 31 | col.g = tex2D(ReShade::BackBuffer,float2(x+uv.x+0.000,uv.y-0.002)).y+0.05; 32 | col.b = tex2D(ReShade::BackBuffer,float2(x+uv.x-0.002,uv.y+0.000)).z+0.05; 33 | col.r += 0.08*tex2D(ReShade::BackBuffer,0.75*float2(x+0.025, -0.027)+float2(uv.x+0.001,uv.y+0.001)).x; 34 | col.g += 0.05*tex2D(ReShade::BackBuffer,0.75*float2(x+-0.022, -0.02)+float2(uv.x+0.000,uv.y-0.002)).y; 35 | col.b += 0.08*tex2D(ReShade::BackBuffer,0.75*float2(x+-0.02, -0.018)+float2(uv.x-0.002,uv.y+0.000)).z; 36 | 37 | col = clamp(col*0.6+0.4*col*col*1.0,0.0,1.0); 38 | 39 | float vig = (0.0 + 1.0*16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y)); 40 | col *= float3(pow(vig,0.3),pow(vig,0.3),pow(vig,0.3)); 41 | 42 | col *= float3(0.95,1.05,0.95); 43 | col *= 2.8; 44 | 45 | float scans = clamp( 0.35+0.35*sin(3.5*iGlobalTime*0.001+uv.y*ReShade::ScreenSize.y*1.5), 0.0, 1.0); 46 | 47 | float s = pow(scans,1.7); 48 | col = col*float3( 0.4+0.7*s, 0.4+0.7*s, 0.4+0.7*s) ; 49 | 50 | col *= 1.0+0.01*sin(110.0*iGlobalTime*0.001); 51 | if (uv.x < 0.0 || uv.x > 1.0) 52 | col *= 0.0; 53 | if (uv.y < 0.0 || uv.y > 1.0) 54 | col *= 0.0; 55 | 56 | col*=1.0-0.65*float3(clamp((mod(fragCoord.x, 2.0)-1.0)*2.0,0.0,1.0),clamp((mod(fragCoord.x, 2.0)-1.0)*2.0,0.0,1.0),clamp((mod(fragCoord.x, 2.0)-1.0)*2.0,0.0,1.0)); 57 | 58 | float comp = smoothstep( 0.1, 0.9, sin(iGlobalTime*0.001) ); 59 | 60 | // Remove the next line to stop cross-fade between original and postprocess 61 | // col = mix( col, oricol, comp ); 62 | 63 | fragColor = float4(col,1.0); 64 | } 65 | 66 | technique CRTMattias { 67 | pass CRTMattias { 68 | VertexShader=PostProcessVS; 69 | PixelShader=PS_CRTMattias1; 70 | } 71 | } -------------------------------------------------------------------------------- /Shaders/N64_3Point.fx: -------------------------------------------------------------------------------- 1 | // to use on shadertoy.com 2 | // DKO's 3point GLSL shader 3 | // Ported to ReShade by Matsilagi 4 | 5 | #include "ReShade.fxh" 6 | 7 | uniform float texture_sizeX < 8 | ui_type = "drag"; 9 | ui_min = 1.0; 10 | ui_max = BUFFER_WIDTH; 11 | ui_label = "Screen Width [N64-3Point]"; 12 | > = 320.0; 13 | 14 | uniform float texture_sizeY < 15 | ui_type = "drag"; 16 | ui_min = 1.0; 17 | ui_max = BUFFER_HEIGHT; 18 | ui_label = "Screen Height [N64-3Point]"; 19 | > = 240.0; 20 | 21 | uniform bool FLIP_DIAGONAL < 22 | ui_type = "bool"; 23 | ui_label = "Flip Diagonal Axis [N64-3Point]"; 24 | > = true; 25 | 26 | float2 norm2denorm(sampler tex, float2 uv) 27 | { 28 | return uv * float2(texture_sizeX,texture_sizeY) - 0.5; 29 | } 30 | 31 | int2 denorm2idx(float2 d_uv) 32 | { 33 | return int2(floor(d_uv)); 34 | } 35 | 36 | int2 norm2idx(sampler tex, float2 uv) 37 | { 38 | return denorm2idx(norm2denorm(tex, uv)); 39 | } 40 | 41 | float2 idx2norm(sampler tex, int2 idx) 42 | { 43 | float2 denorm_uv = float2(idx) + 0.5; 44 | float2 size = float2(texture_sizeX,texture_sizeY); 45 | return denorm_uv / size; 46 | } 47 | 48 | float4 texel_fetch(sampler tex, int2 idx) 49 | { 50 | float2 uv = idx2norm(tex, idx); 51 | return tex2D(tex, uv); 52 | } 53 | 54 | #if 0 55 | float find_mipmap_level(in float2 texture_coordinate) // in texel units 56 | { 57 | float2 dx_vtc = dFdx(texture_coordinate); 58 | float2 dy_vtc = dFdy(texture_coordinate); 59 | float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)); 60 | float mml = 0.5 * log2(delta_max_sqr); 61 | return max( 0, mml ); // Thanks @Nims 62 | } 63 | #endif 64 | 65 | 66 | /* 67 | * Unlike Nintendo's documentation, the N64 does not use 68 | * the 3 closest texels. 69 | * The texel grid is triangulated: 70 | * 71 | * 0 .. 1 0 .. 1 72 | * 0 +----+ 0 +----+ 73 | * | /| |\ | 74 | * . | / | | \ | 75 | * . | / | | \ | 76 | * |/ | | \| 77 | * 1 +----+ 1 +----+ 78 | * 79 | * If the sampled point falls above the diagonal, 80 | * The top triangle is used; otherwise, it's the bottom. 81 | */ 82 | 83 | float4 texture_3point(sampler tex, float2 uv) 84 | { 85 | float2 denorm_uv = norm2denorm(tex, uv); 86 | int2 idx_low = denorm2idx(denorm_uv); 87 | float2 ratio = denorm_uv - float2(idx_low); 88 | 89 | int2 corner0 = int2(0,0); 90 | int2 corner1 = int2(0,0); 91 | int2 corner2 = int2(0,0); 92 | bool lower_flag = 0; 93 | 94 | if (FLIP_DIAGONAL == 0) { 95 | // using step() function, might be faster 96 | lower_flag = int(step(1.0, ratio.s + ratio.t)); 97 | corner0 = int2(lower_flag, lower_flag); 98 | corner1 = int2(0, 1); 99 | corner2 = int2(1, 0); 100 | } else { 101 | // orient the triangulated mesh diagonals the other way 102 | lower_flag = int(step(0.0, ratio.s - ratio.t)); 103 | corner0 = int2(lower_flag, 1 - lower_flag); 104 | corner1 = int2(0, 0); 105 | corner2 = int2(1, 1); 106 | } 107 | 108 | int2 idx0 = idx_low + corner0; 109 | int2 idx1 = idx_low + corner1; 110 | int2 idx2 = idx_low + corner2; 111 | 112 | float4 t0 = texel_fetch(tex, idx0); 113 | float4 t1 = texel_fetch(tex, idx1); 114 | float4 t2 = texel_fetch(tex, idx2); 115 | 116 | // This is standard (Crammer's rule) barycentric coordinates calculation. 117 | float2 v0 = float2(corner1 - corner0); 118 | float2 v1 = float2(corner2 - corner0); 119 | float2 v2 = ratio - float2(corner0); 120 | float den = v0.x * v1.y - v1.x * v0.y; 121 | /* 122 | * Note: the abs() here is necessary because we don't guarantee 123 | * the proper order of vertices, so some signed areas are negative. 124 | * But since we only interpolate inside the triangle, the areas 125 | * are guaranteed to be positive, if we did the math more carefully. 126 | */ 127 | float lambda1 = abs((v2.x * v1.y - v1.x * v2.y) / den); 128 | float lambda2 = abs((v0.x * v2.y - v2.x * v0.y) / den); 129 | float lambda0 = 1.0 - lambda1 - lambda2; 130 | 131 | return lambda0*t0 + lambda1*t1 + lambda2*t2; 132 | } 133 | 134 | 135 | void PS_N64Filter(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 fragColor : COLOR0) 136 | { 137 | float2 fragCoord = txcoord * ReShade::ScreenSize; //this is because the original shader uses OpenGL's fragCoord, which is in texels rather than pixels 138 | float2 uv = txcoord/ReShade::ScreenSize.y/2.0; 139 | // 3-point filtering 140 | float3 col = texture_3point(ReShade::BackBuffer, txcoord).rgb; 141 | fragColor = float4(col, 1.0); 142 | } 143 | 144 | technique N64Filter { 145 | pass N64Filter { 146 | VertexShader=PostProcessVS; 147 | PixelShader=PS_N64Filter; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /Shaders/NTSC_XOT.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | //NTSC-XOT by xot 4 | //Using Signal Modulation from Artifact Colors by Flyguy, with some specific options. 5 | //Works OK, as long as you don't tweak too much. 6 | //Debug mode for the filter included for fiddling purposes. 7 | 8 | #ifndef ENABLE_FILTER_KNOBS 9 | #define ENABLE_FILTER_KNOBS 0 //[0 or 1] Enables tweaking of the Filter Values (For debugging purposes) 10 | #endif 11 | 12 | uniform float display_sizeX < 13 | ui_type = "drag"; 14 | ui_min = 1.0; 15 | ui_max = BUFFER_WIDTH; 16 | ui_label = "Screen Width [NTSC-XOT]"; 17 | > = BUFFER_WIDTH; 18 | 19 | uniform float display_sizeY < 20 | ui_type = "drag"; 21 | ui_min = 1.0; 22 | ui_max = BUFFER_HEIGHT; 23 | ui_label = "Screen Height [NTSC-XOT]"; 24 | > = BUFFER_HEIGHT; 25 | 26 | // TV adjustments 27 | uniform float SAT < 28 | ui_type = "drag"; 29 | ui_min = 0.0; 30 | ui_max = 10.0; 31 | ui_step = 0.1; 32 | ui_label = "Saturation [NTSC-XOT]"; 33 | > = 8.0; 34 | 35 | uniform float HUE < 36 | ui_type = "drag"; 37 | ui_min = -255.0; 38 | ui_max = 255.0; 39 | ui_step = 0.1; 40 | ui_label = "Hue [NTSC-XOT]"; 41 | > = 67.7; 42 | 43 | uniform float BRI < 44 | ui_type = "drag"; 45 | ui_min = 0.0; 46 | ui_max = 1.0; 47 | ui_step = 0.1; 48 | ui_label = "Brightness [NTSC-XOT]"; 49 | > = 1.0; // Brightness (normally 1.0) 50 | 51 | //NTSC XOT 52 | #define PI 3.14159265358979323846 53 | #define TAU 6.28318530717958647693 54 | #define MUL(A, B) mul(A, B) 55 | #define mod(x,y) (x-y*floor(x/y)) 56 | #define display_size float2(display_sizeX,display_sizeY) 57 | 58 | texture XOT0_tex { 59 | Width = BUFFER_WIDTH; 60 | Height = BUFFER_HEIGHT; 61 | Format = RGBA32F; 62 | }; 63 | 64 | sampler sXOT0 { 65 | Texture = XOT0_tex; 66 | }; 67 | 68 | texture XOT1_tex { 69 | Width = BUFFER_WIDTH; 70 | Height = BUFFER_HEIGHT; 71 | Format = R16F; 72 | }; 73 | 74 | sampler sXOT1 { 75 | Texture = XOT1_tex; 76 | }; 77 | 78 | static const float3x3 rgb2yiq = float3x3( 79 | 0.299, 0.596, 0.211, 80 | 0.587,-0.274,-0.523, 81 | 0.114,-0.322, 0.312 82 | ); 83 | 84 | // Filter parameters 85 | #if (ENABLE_FILTER_KNOBS == 0) 86 | static const int N = 18; // Filter Width, was 15 87 | static const int M = (N-1)/2; // Filter Middle 88 | static const float FC = 0.30; // Frequency Cutoff, was 0.25 89 | static const float SCF = 0.25; // Subcarrier Frequency 90 | #else 91 | 92 | uniform int F_COL < 93 | ui_type = "drag"; 94 | ui_min = 1; 95 | ui_max = 255; 96 | ui_step = 1; 97 | ui_label = "Filter Color [NTSC-XOT]"; 98 | > = 4; 99 | 100 | static const int N_INT = 15; // Filter Width 101 | 102 | uniform int N < 103 | ui_type = "drag"; 104 | ui_min = 0; 105 | ui_max = 1024; 106 | ui_step = 1; 107 | ui_label = "Filter Width [NTSC-XOT]"; 108 | > = 15; 109 | 110 | uniform float FC < 111 | ui_type = "drag"; 112 | ui_min = 0.0; 113 | ui_max = 10.0; 114 | ui_step = 0.01; 115 | ui_label = "Frequency Cutoff [NTSC-XOT]"; 116 | > = 0.25; 117 | 118 | uniform float SCF < 119 | ui_type = "drag"; 120 | ui_min = 0.0; 121 | ui_max = 10.0; 122 | ui_step = 0.01; 123 | ui_label = "Subcarrier Frequency [NTSC-XOT]"; 124 | > = 0.25; 125 | #endif 126 | 127 | static const float3x3 rgb2yiq = float3x3( 128 | 0.299, 0.596, 0.211, 129 | 0.587,-0.274,-0.523, 130 | 0.114,-0.322, 0.312 131 | ); 132 | 133 | static const float3x3 YIQ2RGB = float3x3(1.000, 1.000, 1.000, 134 | 0.956,-0.272,-1.106, 135 | 0.621,-0.647, 1.703); 136 | 137 | float3 adjust(float3 YIQ, float H, float S, float B) { 138 | float3x3 M = float3x3( B, 0.0, 0.0, 139 | 0.0, S*cos(H), -sin(H), 140 | 0.0, sin(H), S*cos(H) ); 141 | return mul(M,YIQ); 142 | } 143 | 144 | float sinc(float x) { 145 | if (x == 0.0) return 1.0; 146 | return sin(PI*x) / (PI*x); 147 | } 148 | 149 | // Hann windowing function 150 | float hann(float n, float N) { 151 | return 0.5 * (1.0 - cos((TAU*n)/(N-1.0))); 152 | } 153 | 154 | float2 p_sh(float2 px){ 155 | 156 | float2 xx = float2(320.0, 240.0); //output screen res 157 | float2 ar = float2(1.0,1.0); //final aspect ratio (calculated) 158 | 159 | xx = display_size; 160 | 161 | ar = float(1.0).xx; 162 | 163 | return 0.5 * float2( 164 | step(0.0, 1.0 - ar.y) * (1.0 - 1.0 / ar.y), 165 | step(1.0, ar.y) * (1.0 - ar.y)); 166 | } 167 | 168 | //Complex oscillator, Fo = Oscillator freq., Fs = Sample freq., n = Sample index 169 | float2 Oscillator(float Fo, float Fs, float N) { 170 | float tau_osc = atan(1.0) * 8.0; 171 | float phase = (tau_osc * Fo * floor(N)) / Fs; 172 | return float2(cos(phase), sin(phase)); 173 | } 174 | 175 | //Shaders//////////////////////////////////////////////////////////////////////////////////////// 176 | 177 | float4 PS_Stock(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target 178 | { 179 | float2 px = texcoord.xy*float2((float)BUFFER_WIDTH,(float)BUFFER_HEIGHT); 180 | float2 xx = float2(320.0,240.0); 181 | float2 ar = float2(1.0,1.0); //final aspect ratio (calculated) 182 | 183 | xx = ReShade::ScreenSize.xy; 184 | ar = float(1.0).xx; 185 | 186 | xx = display_size; 187 | 188 | px = texcoord; 189 | px -= 0.5; 190 | px *= ar; 191 | px += 0.5; 192 | 193 | if(ar.y<1.0){px -= 0.5; px = px*(1.0/ar.y); px += 0.5; } 194 | 195 | px = floor(px*xx)/xx; 196 | px += p_sh(px); 197 | 198 | return tex2D(ReShade::BackBuffer, px).rgba; 199 | } 200 | 201 | float PS_Modulator( 202 | float4 pos : SV_POSITION, 203 | float2 uv : TEXCOORD 204 | ) : SV_TARGET { 205 | float Fs = BUFFER_WIDTH; 206 | float Fcol = Fs * (1.0 / 4.0); 207 | 208 | #if (ENABLE_FILTER_KNOBS == 1) 209 | Fcol = Fs* (1.0 / F_COL); 210 | #endif 211 | 212 | float n = floor(uv.x * BUFFER_WIDTH); 213 | 214 | float3 cRGB = tex2D(sXOT0, uv).rgb; 215 | float3 cYIQ = MUL(rgb2yiq, cRGB); 216 | 217 | float2 cOsc = Oscillator(Fcol, Fs, n); 218 | 219 | float sig = cYIQ.x + dot(cOsc, cYIQ.yz); 220 | 221 | return sig; 222 | } 223 | 224 | void PS_NTSCXOT(in float pos: SV_POSITION0, in float2 txcoord: TEXCOORD0, out float4 col : COLOR0) 225 | { 226 | float2 size = ReShade::ScreenSize.xy; 227 | float2 uv = txcoord.xy; 228 | 229 | #if (ENABLE_FILTER_KNOBS == 1) 230 | int M = (N-1)/2; 231 | #endif 232 | 233 | // Compute sampling weights 234 | #if (ENABLE_FILTER_KNOBS) 235 | float weights[N_INT]; 236 | #else 237 | float weights[N]; 238 | #endif 239 | 240 | float sum = 0.0; 241 | 242 | for (int n=0; n = 0.0; 11 | 12 | uniform float3 Phosphor < 13 | ui_type = "drag"; 14 | ui_min = 0.0; 15 | ui_max = 1.0; 16 | ui_step = 0.001; 17 | ui_label = "Phosphor Color [Phosphor]"; 18 | ui_tooltip = "Changes the RGB of the persistance color."; 19 | > = float3(0.45, 0.45, 0.45); 20 | 21 | static const float F = 30.0; 22 | uniform float FTimer < source = "frametime"; >; 23 | 24 | texture2D tPrevTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; 25 | sampler sPrevTex { Texture=tPrevTex; }; 26 | 27 | float3 PrevColor(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target 28 | { 29 | return tex2D(ReShade::BackBuffer, uv).rgb; 30 | } 31 | 32 | float4 PS_PhosphorMain(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target{ 33 | float4 CurrY = tex2D(ReShade::BackBuffer, uv); 34 | float3 PrevY = tex2D(sPrevTex, uv).rgb; 35 | 36 | PrevY[0] *= Phosphor[0] == 0.0 ? 0.0 : pow(Phosphor[0], F * FTimer); 37 | PrevY[1] *= Phosphor[1] == 0.0 ? 0.0 : pow(Phosphor[1], F * FTimer); 38 | PrevY[2] *= Phosphor[2] == 0.0 ? 0.0 : pow(Phosphor[2], F * FTimer); 39 | float a = max(PrevY[0], CurrY[0]); 40 | float b = max(PrevY[1], CurrY[1]); 41 | float c = max(PrevY[2], CurrY[2]); 42 | float3 col = lerp(float3(a,b,c).rgb,CurrY,PTime); //Intensity Toggle 43 | //float3 col = lerp(float3(a,b,c).rgb,CurrY,float3(a,b,c).rgb); //Intensity depends on color, 1 will make eternal burn. 44 | //float3 col = lerp(float3(a,b,c).rgb,CurrY,PrevY); //Best of both. 45 | return float4(col.rgb, CurrY.a); 46 | } 47 | 48 | technique PhosphorMAME 49 | { 50 | pass PS_PhosphorMain 51 | { 52 | VertexShader=PostProcessVS; 53 | PixelShader=PS_PhosphorMain; 54 | } 55 | 56 | pass SaveBuffer { 57 | VertexShader=PostProcessVS; 58 | PixelShader=PrevColor; 59 | RenderTarget = tPrevTex; 60 | } 61 | } -------------------------------------------------------------------------------- /Shaders/PowerVR2.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | PowerVR2 buffer shader 5 | 6 | Authors: leilei 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | */ 13 | 14 | uniform float texture_sizeX < 15 | ui_type = "drag"; 16 | ui_min = 1.0; 17 | ui_max = BUFFER_WIDTH; 18 | ui_label = "Screen Width [PowerVR2]"; 19 | ui_step = 1.0; 20 | > = 320.0; 21 | 22 | uniform float texture_sizeY < 23 | ui_type = "drag"; 24 | ui_min = 1.0; 25 | ui_max = BUFFER_HEIGHT; 26 | ui_label = "Screen Height [PowerVR2]"; 27 | ui_step = 1.0; 28 | > = 240.0; 29 | 30 | uniform bool INTERLACED < 31 | ui_type = "boolean"; 32 | ui_label = "PVR - Interlace smoothing [PowerVR2]"; 33 | > = true; 34 | 35 | uniform bool VGASIGNAL < 36 | ui_type = "boolean"; 37 | ui_label = "PVR - VGA signal loss [PowerVR2]"; 38 | > = false; 39 | 40 | #define HW 1.00 41 | #define LUM_R (76.0f/255.0f) 42 | #define LUM_G (150.0f/255.0f) 43 | #define LUM_B (28.0f/255.0f) 44 | 45 | static const float dithertable[16] = { 46 | 16.0,4.0,13.0,1.0, 47 | 8.0,12.0,5.0,9.0, 48 | 14.0,2.0,15.0,3.0, 49 | 6.0,10.0,7.0,11.0 50 | }; 51 | 52 | #define mod(x,y) (x-y*floor(x/y)) 53 | uniform int FCount < source = "framecount"; >; 54 | #define texture_size float2(texture_sizeX, texture_sizeY) 55 | 56 | float4 PS_PowerVR2(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target 57 | { 58 | 59 | float blue; 60 | 61 | float2 texcoord = uv; 62 | float2 texcoord2 = uv; 63 | texcoord2.x *= texture_size.x; 64 | texcoord2.y *= texture_size.y; 65 | float4 color = tex2D(ReShade::BackBuffer, texcoord); 66 | float fc = mod(float(FCount), 2.0); 67 | 68 | // Blend vertically for composite mode 69 | if (INTERLACED) 70 | { 71 | int taps = int(3); 72 | 73 | float tap = 2.0f/taps; 74 | float2 texcoord4 = uv; 75 | texcoord4.x = texcoord4.x; 76 | texcoord4.y = texcoord4.y + ((tap*(taps/2))/480.0f); 77 | float4 blur1 = tex2D(ReShade::BackBuffer, texcoord4); 78 | int bl; 79 | float4 ble; 80 | 81 | ble.r = 0.00f; 82 | ble.g = 0.00f; 83 | ble.b = 0.00f; 84 | 85 | for (bl=0;bl0) color.r -= 0.023; 120 | if (mod(color.g*64, 2.0)>0) color.g -= 0.01; 121 | if (mod(color.b*32, 2.0)>0) color.b -= 0.023; 122 | } 123 | 124 | 125 | // RGB565 clamp 126 | 127 | color.rb = round(color.rb * 32)/32; 128 | color.g = round(color.g * 64)/64; 129 | 130 | // VGA Signal Loss, which probably is very wrong but i tried my best 131 | if (VGASIGNAL) 132 | { 133 | 134 | int taps = 32; 135 | float tap = 12.0f/taps; 136 | float2 texcoord4 = uv; 137 | texcoord4.x = texcoord4.x + (2.0f/640.0f); 138 | texcoord4.y = texcoord4.y; 139 | float4 blur1 = tex2D(ReShade::BackBuffer, texcoord4); 140 | int bl; 141 | float4 ble; 142 | for (bl=0;bl=3) 146 | e=0.35f; 147 | texcoord4.x -= (tap / 640); 148 | ble.rgb += (tex2D(ReShade::BackBuffer, texcoord4).rgb * e) / (taps/(bl+1)); 149 | } 150 | 151 | color.rgb += ble.rgb * 0.015; 152 | 153 | //color.rb += (4.0f/255.0f); 154 | color.g += (9.0f/255.0f); 155 | } 156 | 157 | return color; 158 | 159 | } 160 | 161 | technique PowerVR2 { 162 | pass PowerVR2 { 163 | VertexShader=PostProcessVS; 164 | PixelShader=PS_PowerVR2; 165 | } 166 | } -------------------------------------------------------------------------------- /Shaders/R57_PAL.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | // NES CRT simulation 4 | // by r57shell 5 | // thanks to feos & HardWareMan 6 | // Ported to ReShade by Matsilagi 7 | 8 | uniform float texture_sizeX < 9 | ui_type = "drag"; 10 | ui_min = 1.0; 11 | ui_max = BUFFER_WIDTH; 12 | ui_label = "Screen Width [PAL-R57]"; 13 | > = 320.0; 14 | 15 | uniform float texture_sizeY < 16 | ui_type = "drag"; 17 | ui_min = 1.0; 18 | ui_max = BUFFER_HEIGHT; 19 | ui_label = "Screen Height [PAL-R57]"; 20 | > = 240.0; 21 | 22 | #define texture_size float2(texture_sizeX, texture_sizeY) 23 | 24 | static const float pi = 3.142; 25 | 26 | #define mod(x,y) (x-y*floor(x/y)) 27 | 28 | float3 monitor(sampler text, float2 p) 29 | { 30 | float2 size = texture_size; 31 | float2 pos = floor(p*size); 32 | float2 uv = floor(pos)/size; 33 | float4 res = tex2D(text, uv); 34 | float3 yuv = mul(float3x3( 35 | 0.2126, 0.7152, 0.0722, 36 | -0.09991, -0.33609, 0.436, 37 | 0.615, -0.55861, -0.05639), res.xyz); 38 | float alpha = (floor(p.x*size.x*4.)/2.0)*pi; 39 | float2 sincv = float2(cos(alpha), sin(alpha)); 40 | if (mod(pos.y + 5.,4.) < 2.) 41 | sincv.x = -sincv.x; 42 | if (mod(pos.y, 4.) >= 2.) 43 | sincv.y = -sincv.y; 44 | float mc = 1.+dot(sincv, yuv.zy)/yuv.x; 45 | 46 | /*float3 rgb = float3( 47 | yuv.x + 1.28033 * yuv.z, 48 | yuv.x - 0.21482 * yuv.y - 0.38059 * yuv.z, 49 | yuv.x + 2.12798 * yuv.y);*/ 50 | return res.xyz*mc; 51 | } 52 | 53 | // pos (left corner, sample size) 54 | float4 monitor_sample(sampler text, float2 p, float2 samp) 55 | { 56 | // linear interpolation was... 57 | // now other thing. 58 | // http://imgur.com/m8Z8trV 59 | // AT LAST IT WORKS!!!! 60 | // going to check in retroarch... 61 | float2 size = texture_size; 62 | float2 next = float2(.25,1.)/size; 63 | float2 f = frac(float2(4.,1.)*size*p); 64 | samp *= float2(4.,1.)*size; 65 | float2 l; 66 | float2 r; 67 | if (f.x+samp.x < 1.) 68 | { 69 | l.x = f.x+samp.x; 70 | r.x = 0.; 71 | } 72 | else 73 | { 74 | l.x = 1.-f.x; 75 | r.x = min(1.,f.x+samp.x-1.); 76 | } 77 | if (f.y+samp.y < 1.) 78 | { 79 | l.y = f.y+samp.y; 80 | r.y = 0.; 81 | } 82 | else 83 | { 84 | l.y = 1.-f.y; 85 | r.y = min(1.,f.y+samp.y-1.); 86 | } 87 | float3 top = lerp(monitor(text, p), monitor(text, p+float2(next.x,0.)), r.x/(l.x+r.x)); 88 | float3 bottom = lerp(monitor(text, p+float2(0.,next.y)), monitor(text, p+next), r.x/(l.x+r.x)); 89 | return float4(lerp(top,bottom, r.y/(l.y+r.y)),1.0); 90 | } 91 | 92 | float4 PS_PALR57(float4 pos : SV_Position, float2 coords : TEXCOORD0) : SV_Target 93 | { 94 | return monitor_sample(ReShade::BackBuffer, coords, 1./ReShade::ScreenSize); 95 | } 96 | 97 | technique PAL_R57 98 | { 99 | pass PAL_R57_1 100 | { 101 | //RenderTarget = iChannel0_Tex; 102 | VertexShader = PostProcessVS; 103 | PixelShader = PS_PALR57; 104 | } 105 | } -------------------------------------------------------------------------------- /Shaders/RGBLCD.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform int2 RES < 4 | ui_type = "drag"; 5 | ui_min = 1; 6 | ui_max = BUFFER_WIDTH; 7 | ui_step = 1; 8 | ui_label = "Resolution [RGB-LCD]"; 9 | > = int2(200, 100); 10 | 11 | uniform float2 BORDER < 12 | ui_type = "drag"; 13 | ui_min = 0.001; 14 | ui_max = 5.0; 15 | ui_step = 0.001; 16 | ui_label = "Border [RGB-LCD]"; 17 | > = float2(0.1, 0.1); 18 | 19 | float4 PS_RGBLCD(float4 position:SV_Position,float2 texcoord:TEXCOORD):SV_Target 20 | { 21 | float2 fragCrd = texcoord * ReShade::ScreenSize; 22 | float4 frgCol; 23 | float2 uv = fragCrd / ReShade::ScreenSize.xy * RES; 24 | float2 p = frac(uv); 25 | float barW = (1.0 - 2.0 * BORDER.x) / 3.0; 26 | float3 rgb = step( 27 | float3(p.x, BORDER.x + barW, BORDER.x + 2.0 * barW), 28 | float3(BORDER.x + barW, p.x, p.x) 29 | ); 30 | rgb.g -= rgb.b; 31 | float3 tex = tex2D(ReShade::BackBuffer, floor(uv) / RES).rgb; 32 | float2 mask = step(BORDER, p) * step(p, 1.0 - BORDER); 33 | frgCol = float4(rgb * tex * mask.x * mask.y,1.0); 34 | return frgCol; 35 | } 36 | 37 | technique RGBLCD { 38 | pass RGBLCD { 39 | VertexShader=PostProcessVS; 40 | PixelShader=PS_RGBLCD; 41 | } 42 | } -------------------------------------------------------------------------------- /Shaders/RetroCRT.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | Retro (CRT) shader, created for use in PPSSPP by KillaMaaki and ported to ReShade 4 by Marot Satil. 5 | 6 | Source: https://github.com/hrydgard/ppsspp/blob/master/assets/shaders/crt.fsh 7 | 8 | PSPSDK BSD-compatible copyright notice (Some parts of the PSPSDK were used in this emulator (defines, constants, headers)) 9 | 10 | Copyright (c) 2005 adresd 11 | Copyright (c) 2005 Marcus R. Brown 12 | Copyright (c) 2005 James Forshaw 13 | Copyright (c) 2005 John Kelley 14 | Copyright (c) 2005 Jesper Svennevid 15 | All rights reserved. 16 | 17 | Redistribution and use in source and binary forms, with or without 18 | modification, are permitted provided that the following conditions 19 | are met: 20 | 1. Redistributions of source code must retain the above copyright 21 | notice, this list of conditions and the following disclaimer. 22 | 2. Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in the 24 | documentation and/or other materials provided with the distribution. 25 | 3. The names of the authors may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 29 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 32 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | 39 | This program is free software; you can redistribute it and/or modify 40 | it under the terms of the GNU General Public License as published by 41 | the Free Software Foundation; either version 2 of the License, or 42 | (at your option) any later version. 43 | 44 | This program is distributed in the hope that it will be useful, 45 | but WITHOUT ANY WARRANTY; without even the implied warranty of 46 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 47 | GNU General Public License for more details. 48 | 49 | You should have received a copy of the GNU General Public License along 50 | with this program; if not, write to the Free Software Foundation, Inc., 51 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 52 | */ 53 | 54 | uniform float Timer < source = "timer"; >; 55 | 56 | float4 RetroCRTPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target 57 | { 58 | const float GLTimer = Timer * 0.0001; 59 | 60 | const float vPos = float( ( texcoord.y + GLTimer * 0.5 ) * 272.0 ); 61 | const float line_intensity = vPos - 2.0 * floor(vPos / 2.0); 62 | 63 | // color shift 64 | const float2 shift = float2( line_intensity * 0.0005, 0 ); 65 | 66 | // shift R and G channels to simulate NTSC color bleed 67 | const float2 colorShift = float2( 0.001, 0 ); 68 | 69 | const float4 c = float4( tex2D( ReShade::BackBuffer, texcoord + colorShift + shift ).x, // Red 70 | tex2D( ReShade::BackBuffer, texcoord - colorShift + shift ).y * 0.99, // Green 71 | tex2D( ReShade::BackBuffer, texcoord ).z, // Blue 72 | 1.0) * clamp( line_intensity, 0.85, 1.0 ); 73 | 74 | return c + (sin( ( texcoord.y + GLTimer ) * 4.0 ) * 0.02); 75 | } 76 | 77 | technique RetroCRT 78 | { 79 | pass 80 | { 81 | VertexShader = PostProcessVS; 82 | PixelShader = RetroCRTPass; 83 | } 84 | } -------------------------------------------------------------------------------- /Shaders/TVCRTPixels.fx: -------------------------------------------------------------------------------- 1 | /* 2 | TV CRT Pixels from https://www.shadertoy.com/view/XsfGDl 3 | Ported by luluco250 4 | 5 | LICENSE: 6 | Same license as the original shader: CC BY-NC-SA 3.0 7 | https://creativecommons.org/licenses/by-nc-sa/3.0/ 8 | */ 9 | 10 | #include "ReShade.fxh" 11 | 12 | uniform float fTVCRTPixels_PixelSize < 13 | ui_label = "Pixel Size [TV CRT Pixels]"; 14 | ui_type = "drag"; 15 | ui_min = 1.0; 16 | ui_max = 10.0; 17 | ui_step = 0.001; 18 | > = 3.0; 19 | 20 | uniform float fTVCRTPixels_Gamma < 21 | ui_label = "Gamma [TV CRT Pixels]"; 22 | ui_type = "drag"; 23 | ui_min = 1.0; 24 | ui_max = 2.2; 25 | ui_step = 0.001; 26 | > = 1.2; 27 | 28 | void TVCRTPixels(in float4 pos : SV_POSITION, in float2 uv : TEXCOORD0, out float4 col : COLOR0) { 29 | float2 texcoord = uv * ReShade::ScreenSize; //this is because the original shader uses OpenGL's fragCoord, which is in texels rather than pixels 30 | float2 coord; 31 | coord.x = texcoord.x / fTVCRTPixels_PixelSize; 32 | coord.y = (texcoord.y + fTVCRTPixels_PixelSize * 1.5 * (floor(coord.x) % 2.0)) / (fTVCRTPixels_PixelSize * 3.0); 33 | 34 | float2 iCoord = floor(coord); 35 | float2 fCoord = frac(coord); 36 | 37 | float3 pixel = step(1.5, (float3(0.0, 1.0, 2.0) + iCoord.x) % 3.0); 38 | float3 image = tex2D(ReShade::BackBuffer, fTVCRTPixels_PixelSize * iCoord * float2(1.0, 3.0) * ReShade::PixelSize).rgb; 39 | 40 | col.rgb = pixel * dot(pixel, image); 41 | 42 | col.rgb *= step(abs(fCoord.x - 0.5), 0.4); 43 | col.rgb *= step(abs(fCoord.y - 0.5), 0.4); 44 | 45 | col.rgb *= fTVCRTPixels_Gamma; 46 | col.a = 1.0; 47 | } 48 | 49 | technique TVCRTPixels { 50 | pass TVCRTPixels { 51 | VertexShader=PostProcessVS; 52 | PixelShader=TVCRTPixels; 53 | } 54 | } -------------------------------------------------------------------------------- /Shaders/Technicolor.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float x_off_r < 4 | ui_type = "drag"; 5 | ui_min = -1.0; 6 | ui_max = 1.0; 7 | ui_step = 0.01; 8 | ui_label = "X Offset Red [Technicolor]"; 9 | > = 0.05; 10 | 11 | uniform float y_off_r < 12 | ui_type = "drag"; 13 | ui_min = -1.0; 14 | ui_max = 1.0; 15 | ui_step = 0.01; 16 | ui_label = "Y Offset Red [Technicolor]"; 17 | > = 0.05; 18 | 19 | uniform float x_off_g < 20 | ui_type = "drag"; 21 | ui_min = -1.0; 22 | ui_max = 1.0; 23 | ui_step = 0.01; 24 | ui_label = "X Offset Green [Technicolor]"; 25 | > = -0.05; 26 | 27 | uniform float y_off_g < 28 | ui_type = "drag"; 29 | ui_min = -1.0; 30 | ui_max = 1.0; 31 | ui_step = 0.01; 32 | ui_label = "Y Offset Green [Technicolor]"; 33 | > = -0.05; 34 | 35 | uniform float x_off_b < 36 | ui_type = "drag"; 37 | ui_min = -1.0; 38 | ui_max = 1.0; 39 | ui_step = 0.01; 40 | ui_label = "X Offset Blue [Technicolor]"; 41 | > = -0.05; 42 | 43 | uniform float y_off_b < 44 | ui_type = "drag"; 45 | ui_min = -1.0; 46 | ui_max = 1.0; 47 | ui_step = 0.01; 48 | ui_label = "Y Offset Blue [Technicolor]"; 49 | > = 0.05; 50 | 51 | uniform float grain_str < 52 | ui_type = "drag"; 53 | ui_min = 0.0; 54 | ui_max = 16.0; 55 | ui_step = 1.0; 56 | ui_label = "Grain Strength [Technicolor]"; 57 | > = 12.0; 58 | 59 | uniform bool lut_toggle < 60 | ui_type = "boolean"; 61 | ui_label = "LUT Toggle [Technicolor]"; 62 | > = true; 63 | 64 | uniform bool hotspot < 65 | ui_type = "boolean"; 66 | ui_label = "Hotspot Toggle [Technicolor]"; 67 | > = true; 68 | 69 | uniform bool vignette < 70 | ui_type = "boolean"; 71 | ui_label = "Vignette Toggle [Technicolor]"; 72 | > = true; 73 | 74 | uniform bool noise_toggle < 75 | ui_type = "boolean"; 76 | ui_label = "Film Scratches"; 77 | > = true; 78 | 79 | uniform int FrameCount < source = "framecount"; >; 80 | 81 | texture texCMYKLUT < source = "CMYK.png"; > { Width = 256; Height = 16; Format = RGBA8; }; 82 | sampler SamplerCMYKLUT { Texture = texCMYKLUT; }; 83 | 84 | texture texFilmNoise < source = "film_noise1.png"; > { Width = 910; Height = 480; Format = RGBA8; }; 85 | sampler SamplerFilmNoise {Texture = texFilmNoise;}; 86 | 87 | #define mod(x,y) (x-y*floor(x/y)) 88 | 89 | //https://www.shadertoy.com/view/4sXSWs strength= 16.0 90 | float filmGrain(float2 uv, float strength, float timer ){ 91 | float x = (uv.x + 4.0 ) * (uv.y + 4.0 ) * ((mod(timer, 800.0) + 10.0) * 10.0); 92 | return (mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)-0.005) * strength; 93 | } 94 | 95 | float hash( float n ){ 96 | return frac(sin(n)*43758.5453123); 97 | } 98 | 99 | void PS_CMYK_LUT(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0) 100 | { 101 | 102 | float4 color = tex2D(ReShade::BackBuffer, texcoord.xy); 103 | float2 texelsize = 1.0 / 16; 104 | texelsize.x /= 16; 105 | 106 | float3 lutcoord = float3((color.xy*16-color.xy+0.5)*texelsize.xy,color.z*16-color.z); 107 | 108 | float lerpfact = frac(lutcoord.z); 109 | lutcoord.x += (lutcoord.z-lerpfact)*texelsize.y; 110 | 111 | float3 lutcolor = lerp(tex2D(SamplerCMYKLUT, lutcoord.xy).xyz, tex2D(SamplerCMYKLUT, float2(lutcoord.x+texelsize.y,lutcoord.y)).xyz,lerpfact); 112 | 113 | if (lut_toggle){ 114 | color.xyz = lerp(normalize(color.xyz), normalize(lutcolor.xyz), 1.0) * 115 | lerp(length(color.xyz), length(lutcolor.xyz), 1.0); 116 | } else { 117 | color.xyz = lerp(normalize(color.xyz), normalize(lutcolor.xyz), 0.0) * 118 | lerp(length(color.xyz), length(lutcolor.xyz), 0.0); 119 | } 120 | 121 | res.xyz = color.xyz; 122 | res.w = 1.0; 123 | } 124 | 125 | void PS_Technicolor_Noise(in float4 pos : SV_POSITION, in float2 texcoord : TEXCOORD0, out float4 gl_FragCol : COLOR0) 126 | { 127 | // a simple calculation for the vignette/hotspot effects 128 | float2 middle = texcoord.xy - 0.5; 129 | float len = length(middle); 130 | float vig = smoothstep(0.0, 1.0, len); 131 | 132 | // create the noise effects from a LUT of actual film noise 133 | float4 film_noise1 = tex2D(SamplerFilmNoise, texcoord.xx * 134 | sin(hash(mod(float(FrameCount), 47.0)))); 135 | float4 film_noise2 = tex2D(SamplerFilmNoise, texcoord.xy * 136 | cos(hash(mod(float(FrameCount), 92.0)))); 137 | 138 | float2 red_coord = texcoord + 0.01 * float2(x_off_r, y_off_r); 139 | float3 red_light = tex2D(ReShade::BackBuffer, red_coord).rgb; 140 | float2 green_coord = texcoord + 0.01 * float2(x_off_g, y_off_g); 141 | float3 green_light = tex2D(ReShade::BackBuffer, green_coord).rgb; 142 | float2 blue_coord = texcoord + 0.01 * float2(x_off_r, y_off_r); 143 | float3 blue_light = tex2D(ReShade::BackBuffer, blue_coord).rgb; 144 | 145 | float3 film = float3(red_light.r, green_light.g, blue_light.b); 146 | film += filmGrain(texcoord.xy, grain_str, float(FrameCount)); // Film grain 147 | 148 | film *= (vignette > 0.5) ? (1.0 - vig) : 1.0; // Vignette 149 | film += ((1.0 - vig) * 0.2) * hotspot; // Hotspot 150 | 151 | // Apply noise effects (or not) 152 | if (hash(float(FrameCount)) > 0.99 && noise_toggle > 0.5) 153 | gl_FragCol = float4(lerp(film, film_noise1.rgb, film_noise1.a), 1.0); 154 | else if (hash(float(FrameCount)) < 0.01 && noise_toggle > 0.5) 155 | gl_FragCol = float4(lerp(film, film_noise2.rgb, film_noise2.a), 1.0); 156 | else 157 | gl_FragCol = float4(film, 1.0); 158 | } 159 | 160 | technique Technicolor 161 | { 162 | pass Technicolor_P1 163 | { 164 | VertexShader = PostProcessVS; 165 | PixelShader = PS_CMYK_LUT; 166 | } 167 | pass Technicolor_P2 168 | { 169 | VertexShader = PostProcessVS; 170 | PixelShader = PS_Technicolor_Noise; 171 | } 172 | } -------------------------------------------------------------------------------- /Shaders/VHS_RA.fx: -------------------------------------------------------------------------------- 1 | // VHS shader 2 | // by hunterk 3 | // adapted from ompuco's more AVdistortion shadertoy: 4 | // https://www.shadertoy.com/view/XlsczN 5 | // Ported to ReShade by Matsilagi 6 | 7 | #include "ReShade.fxh" 8 | 9 | uniform float wiggle < 10 | ui_type = "drag"; 11 | ui_min = 0.0; 12 | ui_max = 10.0; 13 | ui_step = 0.001; 14 | ui_label = "Wiggle [VHS-RA]"; 15 | > = 0.0; 16 | 17 | uniform float smear < 18 | ui_type = "drag"; 19 | ui_min = 0.0; 20 | ui_max = 1.0; 21 | ui_step = 0.05; 22 | ui_label = "Chroma Smear [VHS-RA]"; 23 | > = 0.5; 24 | 25 | uniform int FrameCount < source = "framecount"; >; 26 | 27 | #define mod(x,y) (x-y*floor(x/y)) 28 | #define iTime mod(float(FrameCount), 7.0) 29 | 30 | //YIQ/RGB shit 31 | float3 rgb2yiq(float3 c){ 32 | return float3( 33 | (0.2989*c.x + 0.5959*c.y + 0.2115*c.z), 34 | (0.5870*c.x - 0.2744*c.y - 0.5229*c.z), 35 | (0.1140*c.x - 0.3216*c.y + 0.3114*c.z) 36 | ); 37 | } 38 | 39 | float3 yiq2rgb(float3 c){ 40 | return float3( 41 | (1.0*c.x + 1.0*c.y + 1.0*c.z), 42 | (0.956*c.x - 0.2720*c.y - 1.1060*c.z), 43 | (0.6210*c.x - 0.6474*c.y + 1.7046*c.z) 44 | ); 45 | } 46 | 47 | float2 Circle(float Start, float Points, float Point) 48 | { 49 | float Rad = (3.141592 * 2.0 * (1.0 / Points)) * (Point + Start); 50 | //return float2(sin(Rad), cos(Rad)); 51 | return float2(-(.3+Rad), cos(Rad)); 52 | 53 | } 54 | 55 | float3 Blur(float2 uv, float d){ 56 | float t = (sin(iTime*5.0+uv.y*5.0))/10.0; 57 | float b = 1.0; 58 | t=0.0; 59 | float2 PixelOffset=float2(d+.0005*t,0); 60 | 61 | float Start = 2.0 / 14.0; 62 | float2 Scale = 0.66 * 4.0 * 2.0 * PixelOffset.xy; 63 | 64 | float3 N0 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 0.0) * Scale).rgb; 65 | float3 N1 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 1.0) * Scale).rgb; 66 | float3 N2 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 2.0) * Scale).rgb; 67 | float3 N3 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 3.0) * Scale).rgb; 68 | float3 N4 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 4.0) * Scale).rgb; 69 | float3 N5 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 5.0) * Scale).rgb; 70 | float3 N6 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 6.0) * Scale).rgb; 71 | float3 N7 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 7.0) * Scale).rgb; 72 | float3 N8 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 8.0) * Scale).rgb; 73 | float3 N9 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 9.0) * Scale).rgb; 74 | float3 N10 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 10.0) * Scale).rgb; 75 | float3 N11 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 11.0) * Scale).rgb; 76 | float3 N12 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 12.0) * Scale).rgb; 77 | float3 N13 = tex2D(ReShade::BackBuffer, uv + Circle(Start, 14.0, 13.0) * Scale).rgb; 78 | float3 N14 = tex2D(ReShade::BackBuffer, uv).rgb; 79 | 80 | float4 clr = tex2D(ReShade::BackBuffer, uv); 81 | float W = 1.0 / 15.0; 82 | 83 | clr.rgb= 84 | (N0 * W) + 85 | (N1 * W) + 86 | (N2 * W) + 87 | (N3 * W) + 88 | (N4 * W) + 89 | (N5 * W) + 90 | (N6 * W) + 91 | (N7 * W) + 92 | (N8 * W) + 93 | (N9 * W) + 94 | (N10 * W) + 95 | (N11 * W) + 96 | (N12 * W) + 97 | (N13 * W) + 98 | (N14 * W); 99 | return float3(clr.xyz)*b; 100 | } 101 | 102 | float onOff(float a, float b, float c, float fc) 103 | { 104 | return step(c, sin((fc * 0.001) + a*cos((fc * 0.001)*b))); 105 | } 106 | 107 | float2 jumpy(float2 uv, float fc) 108 | { 109 | float2 look = uv; 110 | float window = 1./(1.+80.*(look.y-mod(fc/4.,1.))*(look.y-mod(fc/4.,1.))); 111 | look.x += 0.05 * sin(look.y*10. + fc)/20.*onOff(4.,4.,.3, fc)*(0.5+cos(fc*20.))*window; 112 | float vShift = (0.1*wiggle) * 0.4*onOff(2.,3.,.9, fc)*(sin(fc)*sin(fc*20.) + 113 | (0.5 + 0.1*sin(fc*200.)*cos(fc))); 114 | look.y = mod(look.y - 0.01 * vShift, 1.); 115 | return look; 116 | } 117 | 118 | void VHS_RA(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 color : COLOR0) 119 | { 120 | float d = .1-round(mod(iTime/3.0,1.0))*.1; 121 | float2 uv = jumpy(txcoord.xy, iTime); 122 | float2 uv2 = uv; 123 | 124 | float s = 0.0001 * wiggle * -d + 0.0001 * wiggle * sin(iTime); 125 | 126 | float e = min(.30,pow(max(0.0,cos(uv.y*4.0+.3)-.75)*(s+0.5)*1.0,3.0))*25.0; 127 | float r = (iTime*(2.0*s)); 128 | uv.x += abs(r*pow(min(.003,(-uv.y+(.01*mod(iTime, 17.0))))*3.0,2.0)); 129 | 130 | d = .051+abs(sin(s/4.0)); 131 | float c = max(0.0001,.002*d) * smear; 132 | float2 uvo = uv; 133 | float4 final; 134 | final.xyz =Blur(uv,c+c*(uv.x)); 135 | float y = rgb2yiq(final.xyz).r; 136 | 137 | uv.x += .01*d; 138 | c *= 6.0; 139 | final.xyz =Blur(uv,c); 140 | float i = rgb2yiq(final.xyz).g; 141 | 142 | uv.x += .005*d; 143 | 144 | c *= 2.50; 145 | final.xyz =Blur(uv,c); 146 | float q = rgb2yiq(final.xyz).b; 147 | final = float4(yiq2rgb(float3(y,i,q))-pow(s+e*2.0,3.0), 1.0); 148 | 149 | color = final; 150 | } 151 | 152 | technique VHS_RA { 153 | pass VHS_RA1 { 154 | VertexShader = PostProcessVS; 155 | PixelShader = VHS_RA; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /Shaders/cmyk_halftone_dot.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | 4 | /* 5 | CMYK Halftone Dot Shader 6 | 7 | Adapted from Stefan Gustavson's GLSL shader demo for WebGL: 8 | http://webstaff.itn.liu.se/~stegu/OpenGLinsights/shadertutorial.html 9 | 10 | Ported to Cg shader language by hunterk 11 | 12 | This shader is licensed in the public domain, as per S. Gustavson's original license. 13 | Note: the MIT-licensed noise functions have been purposely removed. 14 | */ 15 | 16 | uniform float frequency < 17 | ui_type = "drag"; 18 | ui_min = 50.0; 19 | ui_max = 1000.0; 20 | ui_step = 50.0; 21 | ui_label = "HalfTone Dot Density [CMYK HalfTone]"; 22 | > = 550.0; 23 | 24 | sampler2D SamplerColorPoint 25 | { 26 | Texture = ReShade::BackBufferTex; 27 | MinFilter = POINT; 28 | MagFilter = POINT; 29 | MipFilter = POINT; 30 | AddressU = Clamp; 31 | AddressV = Clamp; 32 | }; 33 | 34 | float4 PS_cymk_halftone_dot(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target 35 | { 36 | // Distance to nearest point in a grid of 37 | // (frequency x frequency) points over the unit square 38 | float2x2 rotation_matrix = float2x2(0.707, 0.707, -0.707, 0.707); 39 | float2 st2 = mul(rotation_matrix , texcoord); 40 | float2 nearest = 2.0 * frac(frequency * st2) - 1.0; 41 | float dist = length(nearest); 42 | float3 texcolor = tex2D(SamplerColorPoint, texcoord).rgb; // Unrotated coords 43 | float3 black = float3(0,0,0); 44 | 45 | // Perform a rough RGB-to-CMYK conversion 46 | float4 cmyk; 47 | cmyk.xyz = 1.0 - texcolor; 48 | cmyk.w = min(cmyk.x, min(cmyk.y, cmyk.z)); // Create K 49 | 50 | float2x2 k_matrix = float2x2(0.707, 0.707, -0.707, 0.707); 51 | float2 Kst = frequency * (0.48 * (ReShade::ScreenSize / ReShade::ScreenSize)) * mul(k_matrix , texcoord); 52 | float2 Kuv = 2.0 * frac(Kst) - 1.0; 53 | float k = step(0.0, sqrt(cmyk.w) - length(Kuv)); 54 | float2x2 c_matrix = float2x2(0.966, 0.259, -0.259, 0.966); 55 | float2 Cst = frequency * (0.48 * (ReShade::ScreenSize / ReShade::ScreenSize)) * mul(c_matrix , texcoord); 56 | float2 Cuv = 2.0 * frac(Cst) - 1.0; 57 | float c = step(0.0, sqrt(cmyk.x) - length(Cuv)); 58 | float2x2 m_matrix = float2x2(0.966, -0.259, 0.259, 0.966); 59 | float2 Mst = frequency * (0.48 * (ReShade::ScreenSize / ReShade::ScreenSize)) * mul(m_matrix , texcoord); 60 | float2 Muv = 2.0 * frac(Mst) - 1.0; 61 | float m = step(0.0, sqrt(cmyk.y) - length(Muv)); 62 | float2 Yst = frequency * (0.48 * (ReShade::ScreenSize / ReShade::ScreenSize)) * texcoord; // 0 deg 63 | float2 Yuv = 2.0 * frac(Yst) - 1.0; 64 | float y = step(0.0, sqrt(cmyk.z) - length(Yuv)); 65 | 66 | float3 rgbscreen = 1.0 - 0.9 * float3(c,m,y); 67 | rgbscreen = lerp(rgbscreen, black, 0.85 * k); 68 | 69 | float afwidth = 2.0 * frequency * max(length(ReShade::ScreenSize / (ReShade::ScreenSize * ReShade::ScreenSize)), length(ReShade::ScreenSize / (ReShade::ScreenSize * ReShade::ScreenSize))); 70 | float blend = smoothstep(0.0, 1.0, afwidth); 71 | 72 | float4 color = float4(lerp(rgbscreen , texcolor, blend), 1.0); 73 | color = (max(texcolor.r, max(texcolor.g, texcolor.b)) < 0.01) ? float4(0,0,0,0) : color; // make blacks actually black 74 | 75 | return color; 76 | } 77 | 78 | technique CMYK_Halftone 79 | { 80 | pass CMYK 81 | { 82 | VertexShader = PostProcessVS; 83 | PixelShader = PS_cymk_halftone_dot; 84 | } 85 | } -------------------------------------------------------------------------------- /Shaders/crt-nes-mini.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float texture_sizeY < 4 | ui_type = "drag"; 5 | ui_min = 1.0; 6 | ui_max = BUFFER_HEIGHT; 7 | ui_label = "Scanlines Height [NES-MINI CRT]"; 8 | > = 240.0; 9 | 10 | #define mod(x,y) (x-y*floor(x/y)) 11 | 12 | float4 PS_CRT_NESMINI(float4 vpos : SV_POSITION, float2 texcoord : TEXCOORD0) : SV_Target 13 | { 14 | float3 texel = tex2D(ReShade::BackBuffer, texcoord).rgb; 15 | float3 pixelHigh = (1.2 - (0.2 * texel)) * texel; 16 | float3 pixelLow = (0.85 + (0.1 * texel)) * texel; 17 | float selectY = mod(texcoord.y * 2 * texture_sizeY, 2.0); 18 | float selectHigh = step(1.0, selectY); 19 | float selectLow = 1.0 - selectHigh; 20 | float3 pixelColor = (selectLow * pixelLow) + (selectHigh * pixelHigh); 21 | 22 | return float4(pixelColor, 1.0); 23 | } 24 | 25 | technique CRT_NES_MINI { 26 | pass NESMINI{ 27 | VertexShader = PostProcessVS; 28 | PixelShader = PS_CRT_NESMINI; 29 | } 30 | } -------------------------------------------------------------------------------- /Shaders/lcd-grid.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float display_sizeX < 4 | ui_type = "drag"; 5 | ui_min = 1.0; 6 | ui_max = BUFFER_WIDTH; 7 | ui_step = 1.0; 8 | ui_label = "Screen Width [LCD-Grid]"; 9 | > = 320.0; 10 | 11 | uniform float display_sizeY < 12 | ui_type = "drag"; 13 | ui_min = 1.0; 14 | ui_max = BUFFER_HEIGHT; 15 | ui_step = 1.0; 16 | ui_label = "Screen Height [LCD-Grid]"; 17 | > = 240.0; 18 | 19 | uniform float GRID_STRENGTH < 20 | ui_type = "drag"; 21 | ui_min = 0.0; 22 | ui_max = 1.0; 23 | ui_step = 0.01; 24 | ui_label = "LCD Grid Strength [LCD-Grid]"; 25 | > = 0.05; 26 | 27 | uniform float gamma < 28 | ui_type = "drag"; 29 | ui_min = 1.0; 30 | ui_max = 5.0; 31 | ui_step = 0.1; 32 | ui_label = "LCD Gamma [LCD-Grid]"; 33 | > = 2.2; 34 | 35 | #define display_size float2(display_sizeX,display_sizeY) 36 | #define TX2D(c) pow(tex2D(ReShade::BackBuffer, (c)), float4(gamma,gamma,gamma,gamma)) 37 | #define round(x) floor( (x) + 0.5 ) 38 | #define mod(x,y) ((x)-(y)*floor((x)/(y))) 39 | 40 | float intsmear_func(float z) 41 | { 42 | float z2 = z*z; 43 | float z4 = z2*z2; 44 | float z8 = z4*z4; 45 | return z - 2.0/3.0*z*z2 - 1.0/5.0*z*z4 + 4.0/7.0*z*z2*z4 - 1.0/9.0*z*z8 46 | - 2.0/11.0*z*z2*z8 + 1.0/13.0*z*z4*z8; 47 | } 48 | 49 | float intsmear(float x, float dx) 50 | { 51 | const float d = 1.5; 52 | float zl = clamp((x-dx)/d,-1.0,1.0); 53 | float zh = clamp((x+dx)/d,-1.0,1.0); 54 | return d * ( intsmear_func(zh) - intsmear_func(zl) )/(2.0*dx); 55 | } 56 | 57 | float4 PS_LCDGrid(float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 58 | { 59 | float4 frgCol; 60 | float2 SourceSizeZW = 1.0 / display_size.xy; 61 | float2 texelSize = SourceSizeZW; 62 | float2 subtexelSize = texelSize / float2(3.0,1.0); 63 | float2 range; 64 | range = display_size.xy / (ReShade::ScreenSize.xy * display_size.xy); 65 | 66 | float left = texcoord.x - texelSize.x*0.5; 67 | float top = texcoord.y + range.y; 68 | float right = texcoord.x + texelSize.x*0.5; 69 | float bottom = texcoord.y - range.y; 70 | 71 | float4 lcol, rcol; 72 | float subpix = mod(texcoord.x/subtexelSize.x+1.5,3.0); 73 | float rsubpix = range.x/subtexelSize.x; 74 | lcol = float4(intsmear(subpix+1.0,rsubpix),intsmear(subpix ,rsubpix), 75 | intsmear(subpix-1.0,rsubpix),0.0); 76 | rcol = float4(intsmear(subpix-2.0,rsubpix),intsmear(subpix-3.0,rsubpix), 77 | intsmear(subpix-4.0,rsubpix),0.0); 78 | 79 | float4 topLeftColor = TX2D((floor(float2(left, top) / texelSize) + 0.5) * texelSize) * lcol; 80 | float4 bottomRightColor = TX2D((floor(float2(right, bottom) / texelSize) + 0.5) * texelSize) * rcol; 81 | float4 bottomLeftColor = TX2D((floor(float2(left, bottom) / texelSize) + 0.5) * texelSize) * lcol; 82 | float4 topRightColor = TX2D((floor(float2(right, top) / texelSize) + 0.5) * texelSize) * rcol; 83 | 84 | float2 border = round(texcoord.xy/subtexelSize); 85 | float2 bordert = clamp((border+float2(0.0,+GRID_STRENGTH)) * subtexelSize, 86 | float2(left, bottom), float2(right, top)); 87 | float2 borderb = clamp((border+float2(0.0,-GRID_STRENGTH)) * subtexelSize, 88 | float2(left, bottom), float2(right, top)); 89 | float totalArea = 2.0 * range.y; 90 | 91 | float4 averageColor; 92 | averageColor = ((top - bordert.y) / totalArea) * topLeftColor; 93 | averageColor += ((borderb.y - bottom) / totalArea) * bottomRightColor; 94 | averageColor += ((borderb.y - bottom) / totalArea) * bottomLeftColor; 95 | averageColor += ((top - bordert.y) / totalArea) * topRightColor; 96 | 97 | frgCol = pow(averageColor,float4(1.0/gamma,1.0/gamma,1.0/gamma,1.0/gamma)); 98 | return frgCol; 99 | } 100 | 101 | technique LCDGrid 102 | { 103 | pass LCDGrid { 104 | VertexShader = PostProcessVS; 105 | PixelShader = PS_LCDGrid; 106 | } 107 | } -------------------------------------------------------------------------------- /Shaders/nGlide_3DFX.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float f3DFX_Gamma < 4 | ui_type = "drag"; 5 | ui_min = 0.1; 6 | ui_max = 10.0; 7 | ui_step = 0.01; 8 | ui_label = "Gamma [3DFX Dither]"; 9 | > = 1.3; 10 | 11 | uniform int i3DFX_Filter < 12 | ui_type = "combo"; 13 | ui_items = "None\0Voodoo Graphics\0Voodoo 2\0"; 14 | ui_label = "RAMDAC Filter Type [3DFX Dither]"; 15 | > = 0; 16 | 17 | static const int4x4 dithmat = int4x4(int4(0,12,3,15), 18 | int4(8,4,11,7), 19 | int4(2,14,1,13), 20 | int4(10,6,9,5) 21 | ); 22 | 23 | static const int line_offset[4] = { 1,-1,1,1 }; //Borrowed from LeiLei's PCem 3DFX filter. 24 | 25 | int4 Dither(float2 inpos, float4 incolor) 26 | { 27 | // DITHER 4x4 28 | int3 outcolor = int3(incolor.rgb * 255.0); 29 | 30 | #if (__RENDERER__ == 0x9000) 31 | outcolor.r = floor(outcolor.r * 2) + floor(outcolor.r / 128) - floor(outcolor.r / 16); 32 | outcolor.g = floor(outcolor.g * 4) + floor(outcolor.g / 64) - floor(outcolor.g / 16); 33 | outcolor.b = floor(outcolor.b * 2) + floor(outcolor.b / 128) - floor(outcolor.b / 16); 34 | #else 35 | outcolor.r = (outcolor.r << 1) + (outcolor.r >> 7) - (outcolor.r >> 4); 36 | outcolor.g = (outcolor.g << 2) + (outcolor.g >> 6) - (outcolor.g >> 4); 37 | outcolor.b = (outcolor.b << 1) + (outcolor.b >> 7) - (outcolor.b >> 4); 38 | #endif 39 | 40 | int2 dithpos = int2(inpos * tex2Dsize(ReShade::BackBuffer,0)); 41 | 42 | outcolor += dithmat[dithpos.x % 4][dithpos.y % 4]; //outcolor += dithmat[dithpos.x & 3][dithpos.y & 3]; 43 | 44 | #if (__RENDERER__ == 0x9000) 45 | outcolor.r = floor(outcolor.r / 16) * 8; 46 | outcolor.g = floor(outcolor.g / 16) * 4; 47 | outcolor.b = floor(outcolor.r / 16) * 8; 48 | #else 49 | outcolor.r = ((outcolor.r >> 4) << 3); 50 | outcolor.g = ((outcolor.g >> 4) << 2); 51 | outcolor.b = ((outcolor.b >> 4) << 3); 52 | #endif 53 | 54 | return int4(clamp(outcolor, 0, 255), 0); 55 | } 56 | 57 | void PS_n3DFX(in float4 pos : SV_POSITION, in float2 uv : TEXCOORD0, out float4 col : COLOR0) 58 | { 59 | // DITHER 4x4 60 | float2 texelsize = 1.0/tex2Dsize(ReShade::BackBuffer,0); 61 | float4 color_out; 62 | 63 | float4 tex_lmf = tex2Dlod(ReShade::BackBuffer, float4(uv - float2(texelsize.x*2,0.0),0.0,0.0)); 64 | float4 tex_lnf = tex2Dlod(ReShade::BackBuffer, float4(uv - float2(texelsize.x,0.0),0.0,0.0)); 65 | float4 tex_ctf = tex2Dlod(ReShade::BackBuffer, float4(uv,0.0,0.0)); 66 | float4 tex_rnf = tex2Dlod(ReShade::BackBuffer, float4(uv + float2(texelsize.x,0.0),0.0,0.0)); 67 | 68 | int4 tex_lm = Dither(uv - float2(texelsize.x*2, 0), tex_lmf); 69 | int4 tex_ln = Dither(uv - float2(texelsize.x, 0), tex_lnf); 70 | int4 tex_ct = Dither(uv, tex_ctf); 71 | int4 tex_rn = Dither(uv + float2(texelsize.x, 0), tex_rnf); 72 | 73 | // VIDEO FILTER 4x1 - Option 1 is Mine, Option 2 is nGlide Untouched. 74 | if (i3DFX_Filter == 1) 75 | { 76 | for (int i = 0; i < 4; i ++) //Maybe this mimics the 4 pass? I don't know 77 | { 78 | int4 thresh = int4(0x18, 0x0C, 0x18, 0); 79 | int4 dif_rn = line_offset[i] * (tex_rn - tex_ct); 80 | int4 dif_lm = line_offset[i] * (tex_lm - tex_ct); 81 | int4 dif_ln = line_offset[i] * (tex_ln - tex_ct); 82 | 83 | tex_ct *= 4; 84 | 85 | if(dif_rn.r >= -thresh.r && dif_rn.r <= thresh.r) tex_ct.r += dif_rn.r; 86 | if(dif_rn.g >= -thresh.g && dif_rn.g <= thresh.g) tex_ct.g += dif_rn.g; 87 | if(dif_rn.b >= -thresh.b && dif_rn.b <= thresh.b) tex_ct.b += dif_rn.b; 88 | 89 | if(dif_lm.r >= -thresh.r && dif_lm.r <= thresh.r) tex_ct.r += dif_lm.r; 90 | if(dif_lm.g >= -thresh.g && dif_lm.g <= thresh.g) tex_ct.g += dif_lm.g; 91 | if(dif_lm.b >= -thresh.b && dif_lm.b <= thresh.b) tex_ct.b += dif_lm.b; 92 | 93 | if(dif_ln.r >= -thresh.r && dif_ln.r <= thresh.r) tex_ct.r += dif_ln.r; 94 | if(dif_ln.g >= -thresh.g && dif_ln.g <= thresh.g) tex_ct.g += dif_ln.g; 95 | if(dif_ln.b >= -thresh.b && dif_ln.b <= thresh.b) tex_ct.b += dif_ln.b; 96 | 97 | tex_ct /= 4; 98 | } 99 | } else if (i3DFX_Filter == 2) { 100 | int4 thresh = int4(0x18, 0x0C, 0x18, 0); 101 | int4 dif_rn = tex_rn - tex_ct; 102 | int4 dif_lm = tex_lm - tex_ct; 103 | int4 dif_ln = tex_ln - tex_ct; 104 | 105 | tex_ct *= 4; 106 | 107 | if(dif_rn.r >= -thresh.r && dif_rn.r <= thresh.r) tex_ct.r += dif_rn.r; 108 | if(dif_rn.g >= -thresh.g && dif_rn.g <= thresh.g) tex_ct.g += dif_rn.g; 109 | if(dif_rn.b >= -thresh.b && dif_rn.b <= thresh.b) tex_ct.b += dif_rn.b; 110 | 111 | if(dif_lm.r >= -thresh.r && dif_lm.r <= thresh.r) tex_ct.r += dif_lm.r; 112 | if(dif_lm.g >= -thresh.g && dif_lm.g <= thresh.g) tex_ct.g += dif_lm.g; 113 | if(dif_lm.b >= -thresh.b && dif_lm.b <= thresh.b) tex_ct.b += dif_lm.b; 114 | 115 | if(dif_ln.r >= -thresh.r && dif_ln.r <= thresh.r) tex_ct.r += dif_ln.r; 116 | if(dif_ln.g >= -thresh.g && dif_ln.g <= thresh.g) tex_ct.g += dif_ln.g; 117 | if(dif_ln.b >= -thresh.b && dif_ln.b <= thresh.b) tex_ct.b += dif_ln.b; 118 | 119 | tex_ct /= 4; 120 | } 121 | 122 | tex_ctf.rgb = float3(tex_ct.rgb / 255.0); 123 | tex_ctf.a = 1.0; 124 | 125 | color_out = tex_ctf; 126 | 127 | // GAMMA CORRECTION 128 | float gamma = f3DFX_Gamma; 129 | color_out.rgb = pow(color_out.rgb, 1.0/gamma.xxx); 130 | col = color_out; 131 | } 132 | 133 | technique nGlide_3DFX 134 | { 135 | pass nGlide_3DFX 136 | { 137 | VertexShader = PostProcessVS; 138 | PixelShader = PS_n3DFX; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Shaders/ntsc.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | //----------------------------------------------------------------------------- 4 | // NTSC Pixel Shader 5 | //----------------------------------------------------------------------------- 6 | 7 | uniform float AValue = 0.5f; 8 | uniform float BValue = 0.5f; 9 | uniform float CCValue = 3.5795454f; 10 | uniform float OValue = 0.0f; 11 | uniform float PValue = 1.0f; 12 | uniform float ScanTime = 52.6f; 13 | 14 | uniform float NotchHalfWidth = 1.0f; 15 | uniform float YFreqResponse = 6.0f; 16 | uniform float IFreqResponse = 1.2f; 17 | uniform float QFreqResponse = 0.6f; 18 | 19 | uniform float SignalOffset = 0.0f; 20 | 21 | //----------------------------------------------------------------------------- 22 | // Constants 23 | //----------------------------------------------------------------------------- 24 | 25 | static const float PI = 3.1415927f; 26 | static const float PI2 = PI * 2.0f; 27 | 28 | static const float4 YDot = float4(0.299f, 0.587f, 0.114f, 0.0f); 29 | static const float4 IDot = float4(0.595716f, -0.274453f, -0.321263f, 0.0f); 30 | static const float4 QDot = float4(0.211456f, -0.522591f, 0.311135f, 0.0f); 31 | 32 | static const float3 RDot = float3(1.0f, 0.956f, 0.621f); 33 | static const float3 GDot = float3(1.0f, -0.272f, -0.647f); 34 | static const float3 BDot = float3(1.0f, -1.106f, 1.703f); 35 | 36 | static const float4 OffsetX = float4(0.0f, 0.25f, 0.50f, 0.75f); 37 | static const float4 NotchOffset = float4(0.0f, 1.0f, 2.0f, 3.0f); 38 | 39 | static const int SampleCount = 64; 40 | static const int HalfSampleCount = SampleCount / 2; 41 | 42 | float4 GetCompositeYIQ(float2 TexCoord) 43 | { 44 | float2 PValueSourceTexel = float2(PValue / ReShade::ScreenSize.x, 0.0f); 45 | 46 | float2 C0 = TexCoord + PValueSourceTexel * OffsetX.x; 47 | float2 C1 = TexCoord + PValueSourceTexel * OffsetX.y; 48 | float2 C2 = TexCoord + PValueSourceTexel * OffsetX.z; 49 | float2 C3 = TexCoord + PValueSourceTexel * OffsetX.w; 50 | float4 Cx = float4(C0.x, C1.x, C2.x, C3.x); 51 | float4 Cy = float4(C0.y, C1.y, C2.y, C3.y); 52 | float4 Texel0 = tex2D(ReShade::BackBuffer, C0); 53 | float4 Texel1 = tex2D(ReShade::BackBuffer, C1); 54 | float4 Texel2 = tex2D(ReShade::BackBuffer, C2); 55 | float4 Texel3 = tex2D(ReShade::BackBuffer, C3); 56 | 57 | float4 HPosition = Cx; 58 | float4 VPosition = Cy; 59 | 60 | float4 Y = float4(dot(Texel0, YDot), dot(Texel1, YDot), dot(Texel2, YDot), dot(Texel3, YDot)); 61 | float4 I = float4(dot(Texel0, IDot), dot(Texel1, IDot), dot(Texel2, IDot), dot(Texel3, IDot)); 62 | float4 Q = float4(dot(Texel0, QDot), dot(Texel1, QDot), dot(Texel2, QDot), dot(Texel3, QDot)); 63 | 64 | float W = PI2 * CCValue * ScanTime; 65 | float WoPI = W / PI; 66 | 67 | float HOffset = (BValue + SignalOffset) / WoPI; 68 | float VScale = (AValue * ReShade::ScreenSize.y) / WoPI; 69 | 70 | float4 T = HPosition + HOffset + VPosition * VScale; 71 | float4 TW = T * W; 72 | 73 | float4 CompositeYIQ = Y + I * cos(TW) + Q * sin(TW); 74 | 75 | return CompositeYIQ; 76 | } 77 | 78 | float4 PS_NTSC(float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 79 | { 80 | float4 BaseTexel = tex2D(ReShade::BackBuffer, texcoord); 81 | 82 | float TimePerSample = ScanTime / (ReShade::ScreenSize.x * 4.0f); 83 | 84 | float Fc_y1 = (CCValue - NotchHalfWidth) * TimePerSample; 85 | float Fc_y2 = (CCValue + NotchHalfWidth) * TimePerSample; 86 | float Fc_y3 = YFreqResponse * TimePerSample; 87 | float Fc_i = IFreqResponse * TimePerSample; 88 | float Fc_q = QFreqResponse * TimePerSample; 89 | float Fc_i_2 = Fc_i * 2.0f; 90 | float Fc_q_2 = Fc_q * 2.0f; 91 | float Fc_y1_2 = Fc_y1 * 2.0f; 92 | float Fc_y2_2 = Fc_y2 * 2.0f; 93 | float Fc_y3_2 = Fc_y3 * 2.0f; 94 | float Fc_i_pi2 = Fc_i * PI2; 95 | float Fc_q_pi2 = Fc_q * PI2; 96 | float Fc_y1_pi2 = Fc_y1 * PI2; 97 | float Fc_y2_pi2 = Fc_y2 * PI2; 98 | float Fc_y3_pi2 = Fc_y3 * PI2; 99 | float PI2Length = PI2 / SampleCount; 100 | 101 | float W = PI2 * CCValue * ScanTime; 102 | float WoPI = W / PI; 103 | 104 | float HOffset = (BValue + SignalOffset) / WoPI; 105 | float VScale = (AValue * ReShade::ScreenSize.y) / WoPI; 106 | 107 | float4 YAccum = 0.0f; 108 | float4 IAccum = 0.0f; 109 | float4 QAccum = 0.0f; 110 | 111 | float4 Cy = texcoord.y; 112 | float4 VPosition = Cy; 113 | 114 | for (float i = 0; i < SampleCount; i += 4.0f) 115 | { 116 | float n = i - HalfSampleCount; 117 | float4 n4 = n + NotchOffset; 118 | 119 | float4 Cx = texcoord.x + (n4 * 0.25f) / ReShade::ScreenSize.x; 120 | float4 HPosition = Cx; 121 | 122 | float4 C = GetCompositeYIQ(float2(Cx.r, Cy.r)); 123 | 124 | float4 T = HPosition + HOffset + VPosition * VScale; 125 | float4 WT = W * T + OValue; 126 | 127 | float4 SincKernel = 0.54f + 0.46f * cos(PI2Length * n4); 128 | 129 | float4 SincYIn1 = Fc_y1_pi2 * n4; 130 | float4 SincYIn2 = Fc_y2_pi2 * n4; 131 | float4 SincYIn3 = Fc_y3_pi2 * n4; 132 | float4 SincIIn = Fc_i_pi2 * n4; 133 | float4 SincQIn = Fc_q_pi2 * n4; 134 | 135 | float4 SincY1 = SincYIn1 != 0.0f ? sin(SincYIn1) / SincYIn1 : 1.0f; 136 | float4 SincY2 = SincYIn2 != 0.0f ? sin(SincYIn2) / SincYIn2 : 1.0f; 137 | float4 SincY3 = SincYIn3 != 0.0f ? sin(SincYIn3) / SincYIn3 : 1.0f; 138 | 139 | float4 IdealY = (Fc_y1_2 * SincY1 - Fc_y2_2 * SincY2) + Fc_y3_2 * SincY3; 140 | float4 IdealI = Fc_i_2 * (SincIIn != 0.0f ? sin(SincIIn) / SincIIn : 1.0f); 141 | float4 IdealQ = Fc_q_2 * (SincQIn != 0.0f ? sin(SincQIn) / SincQIn : 1.0f); 142 | 143 | float4 FilterY = SincKernel * IdealY; 144 | float4 FilterI = SincKernel * IdealI; 145 | float4 FilterQ = SincKernel * IdealQ; 146 | 147 | YAccum = YAccum + C * FilterY; 148 | IAccum = IAccum + C * cos(WT) * FilterI; 149 | QAccum = QAccum + C * sin(WT) * FilterQ; 150 | } 151 | 152 | float3 YIQ = float3( 153 | (YAccum.r + YAccum.g + YAccum.b + YAccum.a), 154 | (IAccum.r + IAccum.g + IAccum.b + IAccum.a) * 2.0f, 155 | (QAccum.r + QAccum.g + QAccum.b + QAccum.a) * 2.0f); 156 | 157 | float3 RGB = float3( 158 | dot(YIQ, RDot), 159 | dot(YIQ, GDot), 160 | dot(YIQ, BDot)); 161 | 162 | return float4(RGB, BaseTexel.a); 163 | } 164 | 165 | 166 | technique NTSC_MAME 167 | { 168 | pass NTSCMame 169 | { 170 | VertexShader = PostProcessVS; 171 | PixelShader = PS_NTSC; 172 | } 173 | } -------------------------------------------------------------------------------- /Shaders/scanlines-abs.fx: -------------------------------------------------------------------------------- 1 | /* 2 | Scanlines Sine Absolute Value 3 | An ultra light scanline shader 4 | by RiskyJumps 5 | license: public domain 6 | */ 7 | 8 | #include "ReShade.fxh" 9 | 10 | uniform float texture_sizeY < 11 | ui_type = "drag"; 12 | ui_min = 1.0; 13 | ui_max = BUFFER_HEIGHT; 14 | ui_label = "Scanlines Height [Scanlines-Absolute]"; 15 | > = 240.0; 16 | 17 | uniform float amp < 18 | ui_type = "drag"; 19 | ui_min = 0.0; 20 | ui_max = 2.0; 21 | ui_step = 0.05; 22 | ui_label = "Amplitude [Scanlines-Absolute]"; 23 | > = 1.25; 24 | 25 | uniform float phase < 26 | ui_type = "drag"; 27 | ui_min = 0.0; 28 | ui_max = 2.0; 29 | ui_step = 0.05; 30 | ui_label = "Phase [Scanlines-Absolute]"; 31 | > = 0.0; 32 | 33 | uniform float lines_black < 34 | ui_type = "drag"; 35 | ui_min = 0.0; 36 | ui_max = 1.0; 37 | ui_step = 0.05; 38 | ui_label = "Lines Blacks [Scanlines-Absolute]"; 39 | > = 0.0; 40 | 41 | uniform float lines_white < 42 | ui_type = "drag"; 43 | ui_min = 0.0; 44 | ui_max = 2.0; 45 | ui_step = 0.05; 46 | ui_label = "Lines Whites [Scanlines-Absolute]"; 47 | > = 1.0; 48 | 49 | #define freq 0.500000 50 | #define offset 0.000000 51 | #define pi 3.141592654 52 | 53 | float4 PS_ScanlinesAbs(float4 pos : SV_POSITION, float2 tex : TEXCOORD0, float angle : TEXCOORD2) : SV_TARGET 54 | { 55 | float3 color = tex2D(ReShade::BackBuffer, tex).xyz; 56 | float grid; 57 | 58 | float lines; 59 | 60 | float omega = 2.0 * pi * freq; // Angular frequency 61 | angle = tex.y * omega * texture_sizeY + phase; 62 | 63 | lines = sin(angle); 64 | lines *= amp; 65 | lines += offset; 66 | lines = abs(lines) * (lines_white - lines_black) + lines_black; 67 | color *= lines; 68 | 69 | return color.xyzz; 70 | } 71 | 72 | technique ScanlinesAbs { 73 | pass ScanlinesAbsolute{ 74 | VertexShader = PostProcessVS; 75 | PixelShader = PS_ScanlinesAbs; 76 | } 77 | } -------------------------------------------------------------------------------- /Shaders/scanlines-fract.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float video_sizeX < 4 | ui_type = "drag"; 5 | ui_min = 1.0; 6 | ui_max = BUFFER_WIDTH; 7 | ui_label = "Frame Width [Scanlines-fract]"; 8 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 9 | > = 320.0; 10 | 11 | uniform float video_sizeY < 12 | ui_type = "drag"; 13 | ui_min = 1.0; 14 | ui_max = BUFFER_HEIGHT; 15 | ui_label = "Frame Height [Scanlines-fract]"; 16 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 17 | > = 240.0; 18 | 19 | #define video_size float2(video_sizeX,video_sizeY) 20 | 21 | // Super-basic scanline shader 22 | // (looks bad at non-integer scales) 23 | // by hunterk 24 | // license: public domain 25 | 26 | // Parameter lines go here: 27 | uniform float THICKNESS < 28 | ui_type = "drag"; 29 | ui_min = 1.0; 30 | ui_max = 12.0; 31 | ui_step = 1.0; 32 | ui_label = "Scanline Thickness [Scanlines-fract]"; 33 | > = 2.0; 34 | 35 | uniform float DARKNESS < 36 | ui_type = "drag"; 37 | ui_min = 0.0; 38 | ui_max = 1.0; 39 | ui_step = 0.05; 40 | ui_label = "Scanline Darkness [Scanlines-fract]"; 41 | > = 0.50; 42 | 43 | uniform float BRIGHTBOOST < 44 | ui_type = "drag"; 45 | ui_min = 1.0; 46 | ui_max = 1.2; 47 | ui_step = 0.1; 48 | ui_label = "Scanline Boost Bright [Scanlines-fract]"; 49 | > = 1.1; 50 | 51 | float3 RGBtoYIQ(float3 RGB){ 52 | float3x3 yiqmat = float3x3( 53 | 0.2989, 0.5870, 0.1140, 54 | 0.5959, -0.2744, -0.3216, 55 | 0.2115, -0.5229, 0.3114); 56 | return mul(RGB,yiqmat); 57 | } 58 | 59 | float3 YIQtoRGB(float3 YIQ){ 60 | float3x3 rgbmat = float3x3( 61 | 1.0, 0.956, 0.6210, 62 | 1.0, -0.2720, -0.6474, 63 | 1.0, -1.1060, 1.7046); 64 | return mul(YIQ,rgbmat); 65 | } 66 | 67 | float4 PS_ScanlinesAbs(float4 pos : SV_POSITION, float2 tex : TEXCOORD0) : SV_TARGET 68 | { 69 | float lines = frac(tex.y * video_size.y); 70 | float scale_factor = floor((ReShade::ScreenSize.y / video_size.y) + 0.4999); 71 | float4 screen = tex2D(ReShade::BackBuffer, tex); 72 | screen.rgb = RGBtoYIQ(screen.rgb); 73 | screen.r *= BRIGHTBOOST; 74 | screen.rgb = YIQtoRGB(screen.rgb); 75 | 76 | return (lines > (1.0 / scale_factor * THICKNESS)) ? screen : screen * float4(1.0 - DARKNESS,1.0 - DARKNESS,1.0 - DARKNESS,1.0 - DARKNESS); 77 | } 78 | 79 | technique Scanlinesfract { 80 | pass Scanlinesfract { 81 | VertexShader=PostProcessVS; 82 | PixelShader=PS_ScanlinesAbs; 83 | } 84 | } -------------------------------------------------------------------------------- /Shaders/sgenpt-mix.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | /* 4 | SGENPT-mul - Sega Genesis Pseudo Transparency muler Shader - v8b 5 | 6 | 2011-2020 Hyllian - sergiogdb@gmail.com 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | */ 27 | 28 | uniform float display_sizeX < 29 | ui_type = "drag"; 30 | ui_min = 1.0; 31 | ui_max = BUFFER_WIDTH; 32 | ui_label = "Screen Width [ArtifactColors]"; 33 | > = 320.0; 34 | 35 | uniform float display_sizeY < 36 | ui_type = "drag"; 37 | ui_min = 1.0; 38 | ui_max = BUFFER_HEIGHT; 39 | ui_label = "Screen Height [ArtifactColors]"; 40 | > = 240.0; 41 | 42 | uniform int SGPT_BLEND_OPTION < 43 | ui_type = "combo"; 44 | ui_items = "OFF\0VL\0CB\0CB-S\0Both\0Both 2\0Both-S"; 45 | ui_label = "Blend Option [SGENPT-mul]"; 46 | > = 0; 47 | 48 | uniform float SGPT_BLEND_LEVEL < 49 | ui_type = "drag"; 50 | ui_min = 0.0; 51 | ui_max = 1.0; 52 | ui_step = 0.1; 53 | ui_label = "Both Blend Level [SGENPT-mul]"; 54 | > = 1.0; 55 | 56 | uniform int SGPT_ADJUST_VIEW < 57 | ui_type = "drag"; 58 | ui_min = 0; 59 | ui_max = 1; 60 | ui_step = 1; 61 | ui_label = "Adjust View [SGENPT-mul]"; 62 | > = 0; 63 | 64 | uniform int SGPT_LINEAR_GAMMA < 65 | ui_type = "drag"; 66 | ui_min = 0; 67 | ui_max = 1; 68 | ui_step = 1; 69 | ui_label = "Use Linear Gamma [SGENPT-mul]"; 70 | > = 1; 71 | 72 | #define display_size float2(display_sizeX,display_sizeY) 73 | 74 | #define display_size_pixel float2(1.0/display_sizeX,1.0/display_sizeY) 75 | 76 | #define GAMMA_EXP (SGPT_LINEAR_GAMMA+1.0) 77 | #define GAMMA_IN(color) pow(color, float3(GAMMA_EXP, GAMMA_EXP, GAMMA_EXP)) 78 | #define GAMMA_OUT(color) pow(color, float3(1.0 / GAMMA_EXP, 1.0 / GAMMA_EXP, 1.0 / GAMMA_EXP)) 79 | 80 | static const float3 Y = float3(0.2126, 0.7152, 0.0722); 81 | 82 | float3 min_s(float3 central, float3 adj1, float3 adj2) {return min(central, max(adj1, adj2));} 83 | float3 max_s(float3 central, float3 adj1, float3 adj2) {return max(central, min(adj1, adj2));} 84 | 85 | float4 PS_SGENPT(float4 pos : SV_Position, float2 txcoord : TEXCOORD0) : SV_Target { 86 | float4 outp; 87 | 88 | float2 dx = float2(1.0, 0.0)*display_size_pixel; 89 | float2 dy = float2(0.0, 1.0)*display_size_pixel; 90 | 91 | // Reading the texels. 92 | float3 C = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord ).xyz); 93 | float3 L = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord -dx).xyz); 94 | float3 R = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord +dx).xyz); 95 | float3 U = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord -dy).xyz); 96 | float3 D = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord +dy).xyz); 97 | float3 UL = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord -dx -dy).xyz); 98 | float3 UR = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord +dx -dy).xyz); 99 | float3 DL = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord -dx +dy).xyz); 100 | float3 DR = GAMMA_IN(tex2D(ReShade::BackBuffer, txcoord +dx +dy).xyz); 101 | 102 | float3 color = C; 103 | 104 | // Get min/max samples 105 | float3 min_sample = min_s(C, L, R); 106 | float3 max_sample = max_s(C, L, R); 107 | 108 | float diff = dot(max(max(C, L), max(C, R)) - min(min(C, L), min(C, R)), Y); 109 | 110 | if (SGPT_BLEND_OPTION == 1) // Only Vertical Lines 111 | { 112 | min_sample = max_s(min_sample, min_s(C, DL, DR), min_s(C, UL, UR)); 113 | max_sample = min_s(max_sample, max_s(C, DL, DR), max_s(C, UL, UR)); 114 | 115 | diff *= (1.0 - SGPT_BLEND_LEVEL); 116 | 117 | color = 0.5*( 1.0 + diff )*C + 0.25*( 1.0 - diff )*(L + R); 118 | } 119 | else if (SGPT_BLEND_OPTION == 2) // Only Checkerboard 120 | { 121 | min_sample = max(min_sample, min_s(C, U, D)); 122 | max_sample = min(max_sample, max_s(C, U, D)); 123 | 124 | diff *= (1.0 - SGPT_BLEND_LEVEL); 125 | 126 | color = 0.5*( 1.0 + diff )*C + 0.125*( 1.0 - diff )*(L + R + U + D); 127 | } 128 | else if (SGPT_BLEND_OPTION == 3) // Only Checkerboard - Soft 129 | { 130 | min_sample = min_s(min_sample, U, D); 131 | max_sample = max_s(max_sample, U, D); 132 | 133 | diff *= (1.0 - SGPT_BLEND_LEVEL); 134 | 135 | color = 0.5*( 1.0 + diff )*C + 0.125*( 1.0 - diff )*(L + R + U + D); 136 | } 137 | else if (SGPT_BLEND_OPTION == 4) // VL-CB 138 | { 139 | diff *= (1.0 - SGPT_BLEND_LEVEL); 140 | 141 | color = 0.5*( 1.0 + diff )*C + 0.25*( 1.0 - diff )*(L + R); 142 | } 143 | else if (SGPT_BLEND_OPTION == 5) // VL-CB-2 144 | { 145 | min_sample = min_s(min_sample, U, D); 146 | max_sample = max_s(max_sample, U, D); 147 | 148 | diff *= (1.0 - SGPT_BLEND_LEVEL); 149 | 150 | color = 0.5*( 1.0 + diff )*C + 0.25*( 1.0 - diff )*(L + R); 151 | } 152 | else if (SGPT_BLEND_OPTION == 6) // VL-CB-Soft 153 | { 154 | min_sample = min(min_sample, min(min_s(D, DL, DR), min_s(U, UL, UR))); 155 | max_sample = max(max_sample, max(max_s(D, DL, DR), max_s(U, UL, UR))); 156 | 157 | diff *= (1.0 - SGPT_BLEND_LEVEL); 158 | 159 | color = 0.5*( 1.0 + diff )*C + 0.25*( 1.0 - diff )*(L + R); 160 | } 161 | 162 | color = clamp(color, min_sample, max_sample); 163 | 164 | color = lerp(color, float3(dot(abs(C-color), float3(1.0, 1.0, 1.0)),dot(abs(C-color), float3(1.0, 1.0, 1.0)),dot(abs(C-color), float3(1.0, 1.0, 1.0))), SGPT_ADJUST_VIEW); 165 | 166 | return float4(GAMMA_OUT(color), 1.0); 167 | } 168 | 169 | technique SGENPT_MUL { 170 | 171 | pass SGENPT_MUL { 172 | VertexShader=PostProcessVS; 173 | PixelShader=PS_SGENPT; 174 | } 175 | } -------------------------------------------------------------------------------- /Shaders/vt220.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform int charX < 4 | ui_type = "drag"; 5 | ui_min = 1; 6 | ui_max = BUFFER_WIDTH; 7 | ui_step = 1; 8 | ui_label = "Character Width [VT220 Term]"; 9 | > = 80; 10 | 11 | uniform int charY < 12 | ui_type = "drag"; 13 | ui_min = 1; 14 | ui_max = BUFFER_HEIGHT; 15 | ui_step = 1; 16 | ui_label = "Character Height [VT220 Term]"; 17 | > = 24; 18 | 19 | uniform float WIDTH < 20 | ui_type = "drag"; 21 | ui_min = 0.0; 22 | ui_max = 5.0; 23 | ui_step = 0.001; 24 | ui_label = "Width [VT220 Term]"; 25 | > = 0.48; 26 | 27 | uniform float HEIGHT < 28 | ui_type = "drag"; 29 | ui_min = 0.1; 30 | ui_max = 5.0; 31 | ui_step = "0.001"; 32 | ui_label = "Height [VT220 Term]"; 33 | > = 0.3; 34 | 35 | uniform float CURVE < 36 | ui_type = "drag"; 37 | ui_min = 0.0; 38 | ui_max = 30.0; 39 | ui_step = 0.001; 40 | ui_label = "Curvature [VT220 Term]"; 41 | > = 3.0; 42 | 43 | uniform float3 BEZEL_COL < 44 | ui_type = "color"; 45 | ui_label = "Bezel Color [VT220 Term]"; 46 | > = float3(0.8, 0.8, 0.6); 47 | 48 | uniform float3 PHOSPHOR_COL < 49 | ui_type = "color"; 50 | ui_label = "Phosphor Color [VT220 Term]"; 51 | > = float3(0.2, 1.0, 0.2); 52 | 53 | uniform float SHINE < 54 | ui_type = "drag"; 55 | ui_min = 0.0; 56 | ui_max = 2.0; 57 | ui_step = 0.001; 58 | ui_label = "Brightness [VT220 Term]"; 59 | > = 0.66; 60 | 61 | uniform float AMBIENT < 62 | ui_type = "drag"; 63 | ui_min = 0.0; 64 | ui_max = 2.0; 65 | ui_step = 0.001; 66 | ui_label = "Ambient Light [VT220 Term]"; 67 | > = 0.33; 68 | 69 | #define NO_OF_LINES ReShade::ScreenSize.y*HEIGHT 70 | 71 | uniform float SMOOTH < 72 | ui_type = "drag"; 73 | ui_min = 0.001; 74 | ui_max = 0.1; 75 | ui_step = 0.001; 76 | ui_label = "Smoothness [VT220 Term]"; 77 | > = 0.004; 78 | 79 | // using normal floattors of a sphere with radius r 80 | float2 crtCurve(float2 uv, float r) 81 | { 82 | uv = (uv - 0.5) * 2.0;// uv is now -1 to 1 83 | uv = r*uv/sqrt(r*r -dot(uv, uv)); 84 | uv = (uv / 2.0) + 0.5;// back to 0-1 coords 85 | return uv; 86 | } 87 | 88 | float roundSquare(float2 p, float2 b, float r) 89 | { 90 | return length(max(abs(p)-b,0.0))-r; 91 | } 92 | 93 | float rand(float2 co){ 94 | return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); 95 | } 96 | 97 | float colorFetch(float2 uv) 98 | { 99 | if(uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 0.0; 100 | 101 | float scln = 0.5 - 0.5*cos(uv.y*3.14*NO_OF_LINES); // scanlines 102 | uv *= float2(charX, charY); // 80 by 24 characters 103 | uv = ceil(uv); 104 | uv /= float2(charX, charY); 105 | 106 | float3 color = tex2D(ReShade::BackBuffer, uv); 107 | float col = (color.x+color.y+color.z).xxx/3.0; 108 | return scln*floor(3.0*(0.5+0.499*sin(color)))/3.0; // vt220 has 2 intensitiy levels 109 | } 110 | 111 | void PS_VT220(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 fColor : COLOR0) 112 | { 113 | float4 c = float4(0.0, 0.0, 0.0, 0.0); 114 | 115 | float2 pixel = txcoord * ReShade::ScreenSize.xy; 116 | float2 uv = pixel / ReShade::ScreenSize.xy; 117 | // aspect-ratio correction 118 | float2 aspect = float2(1.,ReShade::ScreenSize.y/ReShade::ScreenSize.x); 119 | uv = 0.5 + (uv -0.5)/ aspect.yx; 120 | 121 | float r = CURVE; 122 | 123 | // Screen Layer 124 | float2 uvS = crtCurve(uv, r); 125 | 126 | // Screen Content 127 | float2 uvC = (uvS - 0.5)* 2.0; // screen content coordinate system 128 | uvC *= float2(0.5/WIDTH, 0.5/HEIGHT); 129 | uvC = (uvC / 2.0) + 0.5; 130 | 131 | float val = colorFetch(uvC); 132 | 133 | c += float4(PHOSPHOR_COL,0.0) * val * 2.0 * 134 | smoothstep(SMOOTH/2.0, -SMOOTH/2.0, roundSquare(uvS-float2(0.5, 0.5), float2(WIDTH-1E-3, HEIGHT-1E-3), 1.0E-10)); 135 | 136 | // Shine 137 | c += max(0.0, SHINE - distance(uv, float2(0.5, 1.0))) * 138 | smoothstep(SMOOTH/2.0, -SMOOTH/2.0, roundSquare(uvS-float2(0.5, 0.47), float2(WIDTH, HEIGHT), 0.05)); 139 | 140 | // Ambient 141 | c += max(0.0, AMBIENT - 0.5*distance(uvS, float2(0.5,0.5))) * 142 | smoothstep(SMOOTH, -SMOOTH, roundSquare(uvS-float2(0.5, 0.5), float2(WIDTH, HEIGHT), 0.05)); 143 | 144 | 145 | // Enclosure Layer 146 | float2 uvE = crtCurve(uv, r+0.25); 147 | 148 | float4 b = float4(0.0, 0.0, 0.0,0.0); 149 | for(int i=0; i<12; i++) 150 | b += (clamp(float4(BEZEL_COL,0.0) + rand(uvE+float(i))*0.05-0.025, 0., 1.) + 151 | rand(uvE+1.0+float(i))*0.25 * cos((uv.x-0.5)*3.1415*1.5))/12.; 152 | 153 | // Inner Border 154 | c += b/3.*( 1. + smoothstep(0.5*HEIGHT/WIDTH-0.025, 0.5*HEIGHT/WIDTH+0.025, abs(atan2(uvS.x-0.5, uvS.y-0.5))/3.1415) 155 | + smoothstep(0.5*HEIGHT/WIDTH+0.025, 0.5*HEIGHT/WIDTH-0.025, abs(atan2(uvS.x-0.5, 0.5-uvS.y))/3.1415) )* 156 | smoothstep(-SMOOTH, SMOOTH, roundSquare(uvS-float2(0.5, 0.5), float2(WIDTH, HEIGHT), 0.05)) * 157 | smoothstep(SMOOTH, -SMOOTH, roundSquare(uvE-float2(0.5, 0.5), float2(WIDTH, HEIGHT) + 0.05, 0.05)); 158 | // Shine 159 | c += (b - 0.4)* 160 | smoothstep(-SMOOTH*2.0, SMOOTH*2.0, roundSquare(uvE-float2(0.5, 0.505), float2(WIDTH, HEIGHT) + 0.05, 0.05)) * 161 | smoothstep(SMOOTH*2.0, -SMOOTH*2.0, roundSquare(uvE-float2(0.5, 0.495), float2(WIDTH, HEIGHT) + 0.05, 0.05)); 162 | 163 | // Outer Border 164 | c += b * 165 | smoothstep(-SMOOTH, SMOOTH, roundSquare(uvE-float2(0.5, 0.5), float2(WIDTH, HEIGHT) + 0.05, 0.05)) * 166 | smoothstep(SMOOTH, -SMOOTH, roundSquare(uvE-float2(0.5, 0.5), float2(WIDTH, HEIGHT) + 0.15, 0.05)); 167 | 168 | // Shine 169 | c += (b - 0.4)* 170 | smoothstep(-SMOOTH*2.0, SMOOTH*2.0, roundSquare(uvE-float2(0.5, 0.495), float2(WIDTH, HEIGHT) + 0.15, 0.05)) * 171 | smoothstep(SMOOTH*2.0, -SMOOTH*2.0, roundSquare(uvE-float2(0.5, 0.505), float2(WIDTH, HEIGHT) + 0.15, 0.05)); 172 | 173 | fColor = c; 174 | } 175 | 176 | technique VT220Term { 177 | pass VT220 { 178 | VertexShader=PostProcessVS; 179 | PixelShader=PS_VT220; 180 | } 181 | } -------------------------------------------------------------------------------- /Shaders/vt220_frame.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | uniform float WIDTH < 4 | ui_type = "drag"; 5 | ui_min = 0.0; 6 | ui_max = 5.0; 7 | ui_step = 0.001; 8 | ui_label = "Width [VT220 Term]"; 9 | > = 0.48; 10 | 11 | uniform float HEIGHT < 12 | ui_type = "drag"; 13 | ui_min = 0.1; 14 | ui_max = 5.0; 15 | ui_step = "0.001"; 16 | ui_label = "Height [VT220 Term]"; 17 | > = 0.3; 18 | 19 | uniform float CURVE < 20 | ui_type = "drag"; 21 | ui_min = 0.0; 22 | ui_max = 30.0; 23 | ui_step = 0.001; 24 | ui_label = "Curvature [VT220 Term]"; 25 | > = 3.0; 26 | 27 | uniform float3 BEZEL_COL < 28 | ui_type = "color"; 29 | ui_label = "Bezel Color [VT220 Term]"; 30 | > = float3(0.8, 0.8, 0.6); 31 | 32 | uniform float SHINE < 33 | ui_type = "drag"; 34 | ui_min = 0.0; 35 | ui_max = 2.0; 36 | ui_step = 0.001; 37 | ui_label = "Brightness [VT220 Term]"; 38 | > = 0.66; 39 | 40 | uniform float AMBIENT < 41 | ui_type = "drag"; 42 | ui_min = 0.0; 43 | ui_max = 2.0; 44 | ui_step = 0.001; 45 | ui_label = "Ambient Light [VT220 Term]"; 46 | > = 0.33; 47 | 48 | #define NO_OF_LINES ReShade::ScreenSize.y*HEIGHT 49 | 50 | uniform float SMOOTH < 51 | ui_type = "drag"; 52 | ui_min = 0.001; 53 | ui_max = 0.1; 54 | ui_step = 0.001; 55 | ui_label = "Smoothness [VT220 Term]"; 56 | > = 0.004; 57 | 58 | // using normal floattors of a sphere with radius r 59 | float2 crtCurve(float2 uv, float r) 60 | { 61 | uv = (uv - 0.5) * 2.0;// uv is now -1 to 1 62 | uv = r*uv/sqrt(r*r -dot(uv, uv)); 63 | uv = (uv / 2.0) + 0.5;// back to 0-1 coords 64 | return uv; 65 | } 66 | 67 | float roundSquare(float2 p, float2 b, float r) 68 | { 69 | return length(max(abs(p)-b,0.0))-r; 70 | } 71 | 72 | float rand(float2 co){ 73 | return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); 74 | } 75 | 76 | float3 colorFetch(float2 uv) 77 | { 78 | if(uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 0.0; 79 | 80 | float3 color = tex2D(ReShade::BackBuffer, uv); 81 | return color; // vt220 has 2 intensitiy levels 82 | } 83 | 84 | void PS_VT220(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 fColor : COLOR0) 85 | { 86 | float4 c = float4(0.0, 0.0, 0.0, 0.0); 87 | 88 | float2 pixel = txcoord * ReShade::ScreenSize.xy; 89 | float2 uv = pixel / ReShade::ScreenSize.xy; 90 | // aspect-ratio correction 91 | float2 aspect = float2(1.,ReShade::ScreenSize.y/ReShade::ScreenSize.x); 92 | uv = 0.5 + (uv -0.5)/ aspect.yx; 93 | 94 | float r = CURVE; 95 | 96 | // Screen Layer 97 | float2 uvS = crtCurve(uv, r); 98 | 99 | // Screen Content 100 | float2 uvC = (uvS - 0.5)* 2.0; // screen content coordinate system 101 | uvC *= float2(0.5/WIDTH, 0.5/HEIGHT); 102 | uvC = (uvC / 2.0) + 0.5; 103 | 104 | float4 col = tex2D(ReShade::BackBuffer, uvC); 105 | 106 | c += col * 2.0 * 107 | smoothstep(SMOOTH/2.0, -SMOOTH/2.0, roundSquare(uvS-float2(0.5, 0.5), float2(WIDTH-1E-3, HEIGHT-1E-3), 1.0E-10)); 108 | 109 | // Shine 110 | c += max(0.0, SHINE - distance(uv, float2(0.5, 1.0))) * 111 | smoothstep(SMOOTH/2.0, -SMOOTH/2.0, roundSquare(uvS-float2(0.5, 0.47), float2(WIDTH, HEIGHT), 0.05)); 112 | 113 | // Ambient 114 | c += max(0.0, AMBIENT - 0.5*distance(uvS, float2(0.5,0.5))) * 115 | smoothstep(SMOOTH, -SMOOTH, roundSquare(uvS-float2(0.5, 0.5), float2(WIDTH, HEIGHT), 0.05)); 116 | 117 | 118 | // Enclosure Layer 119 | float2 uvE = crtCurve(uv, r+0.25); 120 | 121 | float4 b = float4(0.0, 0.0, 0.0,0.0); 122 | for(int i=0; i<12; i++) 123 | b += (clamp(float4(BEZEL_COL,0.0) + rand(uvE+float(i))*0.05-0.025, 0., 1.) + 124 | rand(uvE+1.0+float(i))*0.25 * cos((uv.x-0.5)*3.1415*1.5))/12.; 125 | 126 | // Inner Border 127 | c += b/3.*( 1. + smoothstep(0.5*HEIGHT/WIDTH-0.025, 0.5*HEIGHT/WIDTH+0.025, abs(atan2(uvS.x-0.5, uvS.y-0.5))/3.1415) 128 | + smoothstep(0.5*HEIGHT/WIDTH+0.025, 0.5*HEIGHT/WIDTH-0.025, abs(atan2(uvS.x-0.5, 0.5-uvS.y))/3.1415) )* 129 | smoothstep(-SMOOTH, SMOOTH, roundSquare(uvS-float2(0.5, 0.5), float2(WIDTH, HEIGHT), 0.05)) * 130 | smoothstep(SMOOTH, -SMOOTH, roundSquare(uvE-float2(0.5, 0.5), float2(WIDTH, HEIGHT) + 0.05, 0.05)); 131 | // Shine 132 | c += (b - 0.4)* 133 | smoothstep(-SMOOTH*2.0, SMOOTH*2.0, roundSquare(uvE-float2(0.5, 0.505), float2(WIDTH, HEIGHT) + 0.05, 0.05)) * 134 | smoothstep(SMOOTH*2.0, -SMOOTH*2.0, roundSquare(uvE-float2(0.5, 0.495), float2(WIDTH, HEIGHT) + 0.05, 0.05)); 135 | 136 | // Outer Border 137 | c += b * 138 | smoothstep(-SMOOTH, SMOOTH, roundSquare(uvE-float2(0.5, 0.5), float2(WIDTH, HEIGHT) + 0.05, 0.05)) * 139 | smoothstep(SMOOTH, -SMOOTH, roundSquare(uvE-float2(0.5, 0.5), float2(WIDTH, HEIGHT) + 0.15, 0.05)); 140 | 141 | // Shine 142 | c += (b - 0.4)* 143 | smoothstep(-SMOOTH*2.0, SMOOTH*2.0, roundSquare(uvE-float2(0.5, 0.495), float2(WIDTH, HEIGHT) + 0.15, 0.05)) * 144 | smoothstep(SMOOTH*2.0, -SMOOTH*2.0, roundSquare(uvE-float2(0.5, 0.505), float2(WIDTH, HEIGHT) + 0.15, 0.05)); 145 | 146 | fColor = c; 147 | } 148 | 149 | technique VT220Term { 150 | pass VT220 { 151 | VertexShader=PostProcessVS; 152 | PixelShader=PS_VT220; 153 | } 154 | } -------------------------------------------------------------------------------- /Shaders/vt220_night.fx: -------------------------------------------------------------------------------- 1 | #include "ReShade.fxh" 2 | 3 | #ifndef MAIN_BLOOM_ITERATIONS_DX9 4 | #define MAIN_BLOOM_ITERATIONS_DX9 10 5 | #endif 6 | 7 | #ifndef REFLECTION_BLUR_ITERATIONS_DX9 8 | #define REFLECTION_BLUR_ITERATIONS_DX9 10 9 | #endif 10 | 11 | uniform int charX < 12 | ui_type = "drag"; 13 | ui_min = 1; 14 | ui_max = BUFFER_WIDTH; 15 | ui_step = 1; 16 | ui_label = "Character Width [VT220 Term Night]"; 17 | > = 80; 18 | 19 | uniform int charY < 20 | ui_type = "drag"; 21 | ui_min = 1; 22 | ui_max = BUFFER_HEIGHT; 23 | ui_step = 1; 24 | ui_label = "Character Height [VT220 Term Night]"; 25 | > = 24; 26 | 27 | uniform int MAIN_BLOOM_ITERATIONS < 28 | ui_type = "drag"; 29 | ui_min = 2; 30 | ui_max = 255; 31 | ui_step = 1; 32 | ui_label = "Bloom Iterations [VT220 Term Night]"; 33 | > = 10; 34 | 35 | uniform float MAIN_BLOOM_SIZE < 36 | ui_type = "drag"; 37 | ui_min = 0.001; 38 | ui_max = 1.0; 39 | ui_step = 0.001; 40 | ui_label = "Bloom Size [VT220 Term Night]"; 41 | > = 0.01; 42 | 43 | uniform int REFLECTION_BLUR_ITERATIONS < 44 | ui_type = "drag"; 45 | ui_min = 2; 46 | ui_max = 255; 47 | ui_step = 1; 48 | ui_label = "Reflection Blur Iterations [VT220 Term Night]"; 49 | > = 10; 50 | 51 | uniform float REFLECTION_BLUR_SIZE< 52 | ui_type = "drag"; 53 | ui_min = 0.001; 54 | ui_max = 1.0; 55 | ui_step = 0.001; 56 | ui_label = "Reflection Blur Size [VT220 Term Night]"; 57 | > = 0.05; 58 | 59 | uniform float WIDTH < 60 | ui_type = "drag"; 61 | ui_min = 0.0; 62 | ui_max = 5.0; 63 | ui_step = 0.001; 64 | ui_label = "Width [VT220 Term Night]"; 65 | > = 0.48; 66 | 67 | uniform float HEIGHT < 68 | ui_type = "drag"; 69 | ui_min = 0.1; 70 | ui_max = 5.0; 71 | ui_step = "0.001"; 72 | ui_label = "Height [VT220 Term Night]"; 73 | > = 0.3; 74 | 75 | uniform float CURVE < 76 | ui_type = "drag"; 77 | ui_min = 0.0; 78 | ui_max = 30.0; 79 | ui_step = 0.001; 80 | ui_label = "Curvature [VT220 Term Night]"; 81 | > = 3.0; 82 | 83 | uniform float3 BEZEL_COL < 84 | ui_type = "color"; 85 | ui_label = "Bezel Color [VT220 Term Night]"; 86 | > = float3(0.8, 0.8, 0.6); 87 | 88 | uniform float3 PHOSPHOR_COL < 89 | ui_type = "color"; 90 | ui_label = "Phosphor Color [VT220 Term Night]"; 91 | > = float3(0.2, 1.0, 0.2); 92 | 93 | uniform float SHINE < 94 | ui_type = "drag"; 95 | ui_min = 0.0; 96 | ui_max = 2.0; 97 | ui_step = 0.001; 98 | ui_label = "Brightness [VT220 Term Night]"; 99 | > = 0.66; 100 | 101 | uniform float AMBIENT < 102 | ui_type = "drag"; 103 | ui_min = 0.0; 104 | ui_max = 2.0; 105 | ui_step = 0.001; 106 | ui_label = "Ambient Light [VT220 Term Night]"; 107 | > = 0.33; 108 | 109 | #define NO_OF_LINES ReShade::ScreenSize.y*HEIGHT 110 | 111 | uniform float SMOOTH < 112 | ui_type = "drag"; 113 | ui_min = 0.001; 114 | ui_max = 0.1; 115 | ui_step = 0.001; 116 | ui_label = "Smoothness [VT220 Term Night]"; 117 | > = 0.004; 118 | 119 | // using normal floattors of a sphere with radius r 120 | float2 crtCurve(float2 uv, float r) 121 | { 122 | uv = (uv - 0.5) * 2.0;// uv is now -1 to 1 123 | uv = r*uv/sqrt(r*r -dot(uv, uv)); 124 | uv = (uv / 2.0) + 0.5;// back to 0-1 coords 125 | return uv; 126 | } 127 | 128 | float roundSquare(float2 p, float2 b, float r) 129 | { 130 | return length(max(abs(p)-b,0.0))-r; 131 | } 132 | 133 | float rand(float2 co){ 134 | return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); 135 | } 136 | 137 | // Calculate normal to distance function and move along 138 | // normal with distance to get point of reflection 139 | float2 borderReflect(float2 p, float r) 140 | { 141 | float eps = 0.0001; 142 | float2 epsx = float2(eps,0.0); 143 | float2 epsy = float2(0.0,eps); 144 | float2 b = (1.+float2(r,r))* 0.5; 145 | r /= 3.0; 146 | 147 | p -= 0.5; 148 | float2 normal = float2(roundSquare(p-epsx,b,r)-roundSquare(p+epsx,b,r), 149 | roundSquare(p-epsy,b,r)-roundSquare(p+epsy,b,r))/eps; 150 | float d = roundSquare(p, b, r); 151 | p += 0.5; 152 | return p + d*normal; 153 | } 154 | 155 | float colorFetch(float2 uv) 156 | { 157 | if(uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) return 0.0; 158 | 159 | float scln = 0.5 - 0.5*cos(uv.y*3.14*NO_OF_LINES); // scanlines 160 | uv *= float2(charX, charY); // 80 by 24 characters 161 | uv = ceil(uv); 162 | uv /= float2(charX, charY); 163 | 164 | float3 color = tex2D(ReShade::BackBuffer, uv); 165 | float col = (color.x+color.y+color.z).xxx/3.0; 166 | return scln*floor(3.0*(0.5+0.499*sin(color)))/3.0; // vt220 has 2 intensitiy levels 167 | } 168 | 169 | void PS_VT220_Night(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 fColor : COLOR0) 170 | { 171 | float4 c = float4(0.0, 0.0, 0.0, 0.0); 172 | 173 | int Bloom_Loop = MAIN_BLOOM_ITERATIONS; 174 | int Reflection_Loop = REFLECTION_BLUR_ITERATIONS; 175 | 176 | if (__RENDERER__ == 0x09300 ){ 177 | Bloom_Loop = MAIN_BLOOM_ITERATIONS_DX9; 178 | Reflection_Loop = REFLECTION_BLUR_ITERATIONS_DX9; 179 | } 180 | 181 | float2 pixel = txcoord * ReShade::ScreenSize.xy; 182 | float2 uv = pixel / ReShade::ScreenSize.xy; 183 | // aspect-ratio correction 184 | float2 aspect = float2(1.,ReShade::ScreenSize.y/ReShade::ScreenSize.x); 185 | uv = 0.5 + (uv -0.5)/ aspect.yx; 186 | 187 | float r = CURVE; 188 | 189 | // Screen Layer 190 | float2 uvS = crtCurve(uv, r); 191 | float dx; 192 | float dy; 193 | 194 | // Screen Content 195 | float2 uvC = (uvS - 0.5)* 2.0; // screen content coordinate system 196 | uvC *= float2(0.5/WIDTH, 0.5/HEIGHT); 197 | uvC = (uvC / 2.0) + 0.5; 198 | 199 | //Simple Bloom 200 | float B = float(MAIN_BLOOM_ITERATIONS*MAIN_BLOOM_ITERATIONS); 201 | for(int i=0; i = true; 23 | 24 | uniform bool BLACK_OUT_BORDER < 25 | ui_type = "boolean"; 26 | ui_label = "Enable Black Border [CRT-ZFast]"; 27 | > = false; 28 | 29 | 30 | // Parameter lines go here: 31 | uniform float BLURSCALEX < 32 | ui_type = "drag"; 33 | ui_min = 0.0; 34 | ui_max = 1.0; 35 | ui_step = 0.05; 36 | ui_label = "Blur Amount X-Axis [CRT-ZFast]"; 37 | > = 0.30; 38 | 39 | uniform float LOWLUMSCAN < 40 | ui_type = "drag"; 41 | ui_min = 0.0; 42 | ui_max = 10.0; 43 | ui_step = 0.5; 44 | ui_label = "Scanline Darkness - Low [CRT-ZFast]"; 45 | > = 6.0; 46 | 47 | uniform float HILUMSCAN < 48 | ui_type = "drag"; 49 | ui_min = 0.0; 50 | ui_max = 50.0; 51 | ui_step = 1.0; 52 | ui_label = "Scanline Darkness - High [CRT-ZFast]"; 53 | > = 8.0; 54 | 55 | uniform float BRIGHTBOOST < 56 | ui_type = "drag"; 57 | ui_min = 0.5; 58 | ui_max = 1.5; 59 | ui_step = 0.05; 60 | ui_label = "Dark Pixel Brightness Boost [CRT-ZFast]"; 61 | > = 1.25; 62 | 63 | uniform float MASK_DARK < 64 | ui_type = "drag"; 65 | ui_min = 0.0; 66 | ui_max = 1.0; 67 | ui_step = 0.05; 68 | ui_label = "Mask Effect Amount [CRT-ZFast]"; 69 | > = 0.25; 70 | 71 | uniform float MASK_FADE < 72 | ui_type = "drag"; 73 | ui_min = 0.0; 74 | ui_max = 1.0; 75 | ui_step = 0.05; 76 | ui_label = "Mask/Scanline Fade [CRT-ZFast]"; 77 | > = 0.8; 78 | 79 | uniform float video_sizeX < 80 | ui_type = "drag"; 81 | ui_min = 1.0; 82 | ui_max = BUFFER_WIDTH; 83 | ui_label = "Screen Width [CRT-ZFast]"; 84 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 85 | > = 320.0; 86 | 87 | uniform float video_sizeY < 88 | ui_type = "drag"; 89 | ui_min = 1.0; 90 | ui_max = BUFFER_HEIGHT; 91 | ui_label = "Screen Height [CRT-ZFast]"; 92 | ui_tooltip = "This should be sized according to the video data in the texture (If you're using emulators, set this to the Emu video frame size, otherwise, keep it the same as Screen Width/Height or Fullscreen res.)"; 93 | > = 240.0; 94 | 95 | void PS_ZFastCRT(in float4 pos : SV_POSITION, in float2 txcoord : TEXCOORD0, out float4 fragColor : COLOR0) 96 | { 97 | 98 | float maskFade; 99 | float2 invDims = float2(0.0,0.0); 100 | float2 TextureSize = float2(video_sizeX,video_sizeY); 101 | 102 | float2 texcoord = txcoord; 103 | float2 tc = txcoord * ReShade::ScreenSize; 104 | 105 | maskFade = 0.3333*MASK_FADE; 106 | invDims = 1.0/TextureSize.xy; 107 | 108 | //This is just like "Quilez Scaling" but sharper 109 | float2 p = texcoord * TextureSize; 110 | float2 i = floor(p) + 0.50; 111 | float2 f = p - i; 112 | p = (i + 4.0*f*f*f)*invDims; 113 | p.x = lerp( p.x , texcoord.x, BLURSCALEX); 114 | float Y = f.y*f.y; 115 | float YY = Y*Y; 116 | 117 | float whichmask; 118 | float mask; 119 | 120 | if(FINEMASK != 0){ 121 | whichmask = frac( txcoord.x*-0.4999); 122 | mask = 1.0 + float(whichmask < 0.5) * -MASK_DARK; 123 | } else { 124 | whichmask = frac(txcoord.x * -0.3333); 125 | mask = 1.0 + float(whichmask <= 0.33333) * -MASK_DARK; 126 | } 127 | 128 | float3 colour = tex2D(ReShade::BackBuffer, p).rgb; 129 | float3 finalColor = float3(0.0,0.0,0.0); 130 | 131 | float scanLineWeight = (BRIGHTBOOST - LOWLUMSCAN*(Y - 2.05*YY)); 132 | float scanLineWeightB = 1.0 - HILUMSCAN*(YY-2.8*YY*Y); 133 | 134 | if (BLACK_OUT_BORDER) { 135 | colour.rgb*=float(texcoord.x > 0.0)*float(texcoord.y > 0.0); //why doesn't the driver do the right thing? 136 | } 137 | 138 | fragColor = float4(colour.rgb*lerp(scanLineWeight*mask, scanLineWeightB, dot(colour.rgb,float3(maskFade,maskFade,maskFade))),1.0); 139 | 140 | } 141 | 142 | technique CRTZFast { 143 | pass CRTZFast { 144 | VertexShader=PostProcessVS; 145 | PixelShader=PS_ZFastCRT; 146 | } 147 | } -------------------------------------------------------------------------------- /Textures/CMYK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/CMYK.png -------------------------------------------------------------------------------- /Textures/allNoise512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/allNoise512.png -------------------------------------------------------------------------------- /Textures/crt-cx/tvscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/crt-cx/tvscreen.png -------------------------------------------------------------------------------- /Textures/crt-newpixie/crtframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/crt-newpixie/crtframe.png -------------------------------------------------------------------------------- /Textures/crt_potato/crt-potato-thick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/crt_potato/crt-potato-thick.png -------------------------------------------------------------------------------- /Textures/crt_potato/crt-potato-thin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/crt_potato/crt-potato-thin.png -------------------------------------------------------------------------------- /Textures/crtsim/artifacts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/crtsim/artifacts.png -------------------------------------------------------------------------------- /Textures/crtsim/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/crtsim/mask.png -------------------------------------------------------------------------------- /Textures/film_noise1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matsilagi/RSRetroArch/b27eb2dd05d3ebf8a1ce2760b51b26caa0e54bbe/Textures/film_noise1.png --------------------------------------------------------------------------------