Guest User

NTSC_RetroArch.fx

a guest
Mar 8th, 2017
408
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "ReShade.fxh"
  2.  
  3. uniform int2 display_size <
  4. ui_type = "input";
  5. ui_label = "Display Size";
  6. ui_tooltip = "The virtual screen size in pixels";
  7. > = int2(320, 240);
  8.  
  9. uniform bool bUseTwoPhase <
  10. ui_label = "Use Two-Phase";
  11. > = false;
  12.  
  13. uniform bool bUseSVideo <
  14. ui_label = "Use S-Video";
  15. ui_tooltip = "Uses S-Video Cables instead of Composite.";
  16. > = false;
  17.  
  18. uniform float NTSC_DISPLAY_GAMMA <
  19. ui_type = "drag";
  20. ui_min = 1.0;
  21. ui_max = 10.0;
  22. ui_step = 0.1;
  23. ui_label = "NTSC Display Gamma";
  24. > = 2.1;
  25.  
  26. uniform float NTSC_CRT_GAMMA <
  27. ui_type = "drag";
  28. ui_min = 1.0;
  29. ui_max = 10.0;
  30. ui_step = 0.1;
  31. ui_label = "NTSC CRT Gamma";
  32. > = 2.5;
  33.  
  34. #define PI 3.14159265
  35.  
  36. #define CHROMA_MOD_FREQ (PI / 3.0)
  37. #define CHROMA_MOD_FREQ_TWO (4.0 * PI / 15.0)
  38.  
  39. #define SATURATION 1.0
  40. #define BRIGHTNESS 1.0
  41. #define ARTIFACTING 1.0
  42. #define FRINGING 1.0
  43.  
  44. #define ARTIFACTING_SV 0.0
  45. #define FRINGING_SV 0.0
  46.  
  47. static const float3x3 mix_mat = float3x3(
  48. BRIGHTNESS, ARTIFACTING, ARTIFACTING,
  49. FRINGING, 2.0 * SATURATION, 0.0,
  50. FRINGING, 0.0, 2.0 * SATURATION
  51. );
  52.  
  53. static const float3x3 mix_mat_sv = float3x3(
  54. BRIGHTNESS, ARTIFACTING_SV, ARTIFACTING_SV,
  55. FRINGING_SV, 2.0 * SATURATION, 0.0,
  56. FRINGING_SV, 0.0, 2.0 * SATURATION
  57. );
  58.  
  59. static const float3x3 yiq2rgb_mat = float3x3(
  60. 1.0, 0.956, 0.6210,
  61. 1.0, -0.2720, -0.6474,
  62. 1.0, -1.1060, 1.7046);
  63.  
  64. float3 yiq2rgb(float3 yiq)
  65. {
  66. return mul(yiq2rgb_mat, yiq);
  67. }
  68.  
  69. static const float3x3 yiq_mat = float3x3(
  70. 0.2989, 0.5870, 0.1140,
  71. 0.5959, -0.2744, -0.3216,
  72. 0.2115, -0.5229, 0.3114
  73. );
  74.  
  75. float3 rgb2yiq(float3 col)
  76. {
  77. return mul(yiq_mat, col);
  78. };
  79.  
  80. float fmod(float a, float b) {
  81. float c = frac(abs(a / b)) * abs(b);
  82. return (a < 0) ? -c : c;
  83. };
  84.  
  85. texture target0
  86. {
  87. Width = BUFFER_WIDTH;
  88. Height = BUFFER_HEIGHT;
  89. Format = RGBA32F;
  90. };
  91. sampler s0 { Texture = target0; };
  92.  
  93. uniform int framecount < source = "framecount"; >;
  94.  
  95. float4 NTSCStartPS( float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target
  96. {
  97. return tex2D(s0,texcoord);
  98. }
  99.  
  100. float4 NTSCEncodePS( float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target
  101. {
  102. float3 col = tex2D(ReShade::BackBuffer, texcoord).rgb;
  103. float3 yiq = rgb2yiq(col);
  104.  
  105. float2 pix_no = texcoord * display_size * float2( 4.0, 1.0 );
  106. float2 one = 1.0 / ReShade::ScreenSize;
  107.  
  108. float chroma_phase = 0.6667 * PI * (fmod(pix_no.y, 3.0) + framecount);
  109. float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ;
  110.  
  111. if (bUseTwoPhase){
  112. chroma_phase = PI * (fmod(pix_no.y, 2.0) + framecount);
  113. mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ_TWO;
  114. }
  115.  
  116. float i_mod = cos(mod_phase);
  117. float q_mod = sin(mod_phase);
  118.  
  119.  
  120. if(bUseSVideo){
  121. yiq.yz *= float2(i_mod, q_mod); // Modulate.
  122. yiq = mul(mix_mat_sv,yiq); // Cross-talk.
  123. yiq.yz *= float2(i_mod, q_mod); // Demodulate.
  124. } else {
  125. yiq.yz *= float2(i_mod, q_mod); // Modulate.
  126. yiq = mul(mix_mat,yiq); // Cross-talk.
  127. yiq.yz *= float2(i_mod, q_mod); // Demodulate.
  128. }
  129.  
  130. return float4(yiq, 1.0);
  131. }
  132.  
  133. float3 t2d(float2 texcoord)
  134. {
  135. return tex2D(s0,texcoord);
  136. }
  137.  
  138. #define fixCoord (texcoord - float2( 0.5 * one_x, 0.0))
  139. #define fetch_offset(offset, one_x) t2d(fixCoord + float2( (offset) * (one_x), 0.0))
  140.  
  141. float4 NTSCDecodePS( float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target
  142. {
  143.  
  144. float2 pix_no = texcoord * display_size * float2( 4.0, 1.0 );
  145. float2 one = 1.0 / ReShade::ScreenSize;
  146.  
  147. int TAPS = 24;
  148.  
  149. float luma_filter[33] = {
  150. 0.000000000,
  151. 0.000000000,
  152. 0.000000000,
  153. 0.000000000,
  154. 0.000000000,
  155. 0.000000000,
  156. 0.000000000,
  157. 0.000000000,
  158. 0.000000000,
  159. 0.000000000,
  160. 0.000000000,
  161. 0.000000000,
  162. 0.000000000,
  163. 0.000000000,
  164. 0.000000000,
  165. 0.000000000,
  166. 0.000000000,
  167. 0.000000000,
  168. 0.000000000,
  169. 0.000000000,
  170. 0.000000000,
  171. 0.000000000,
  172. 0.000000000,
  173. 0.000000000,
  174. 0.000000000,
  175. 0.000000000,
  176. 0.000000000,
  177. 0.000000000,
  178. 0.000000000,
  179. 0.000000000,
  180. 0.000000000,
  181. 0.000000000,
  182. 0.000000000
  183. };
  184.  
  185. float chroma_filter[33] = {
  186. 0.000000000,
  187. 0.000000000,
  188. 0.000000000,
  189. 0.000000000,
  190. 0.000000000,
  191. 0.000000000,
  192. 0.000000000,
  193. 0.000000000,
  194. 0.000000000,
  195. 0.000000000,
  196. 0.000000000,
  197. 0.000000000,
  198. 0.000000000,
  199. 0.000000000,
  200. 0.000000000,
  201. 0.000000000,
  202. 0.000000000,
  203. 0.000000000,
  204. 0.000000000,
  205. 0.000000000,
  206. 0.000000000,
  207. 0.000000000,
  208. 0.000000000,
  209. 0.000000000,
  210. 0.000000000,
  211. 0.000000000,
  212. 0.000000000,
  213. 0.000000000,
  214. 0.000000000,
  215. 0.000000000,
  216. 0.000000000,
  217. 0.000000000,
  218. 0.000000000
  219. };
  220.  
  221. luma_filter[0] = -0.000012020;
  222. luma_filter[1] = -0.000022146;
  223. luma_filter[2] = -0.000013155;
  224. luma_filter[3] = -0.000012020;
  225. luma_filter[4] = -0.000049979;
  226. luma_filter[5] = -0.000113940;
  227. luma_filter[6] = -0.000122150;
  228. luma_filter[7] = -0.000005612;
  229. luma_filter[8] = 0.000170516;
  230. luma_filter[9] = 0.000237199;
  231. luma_filter[10] = 0.000169640;
  232. luma_filter[11] = 0.000285688;
  233. luma_filter[12] = 0.000984574;
  234. luma_filter[13] = 0.002018683;
  235. luma_filter[14] = 0.002002275;
  236. luma_filter[15] = -0.000909882;
  237. luma_filter[16] = -0.007049081;
  238. luma_filter[17] = -0.013222860;
  239. luma_filter[18] = -0.012606931;
  240. luma_filter[19] = 0.002460860;
  241. luma_filter[20] = 0.035868225;
  242. luma_filter[21] = 0.084016453;
  243. luma_filter[22] = 0.135563500;
  244. luma_filter[23] = 0.175261268;
  245. luma_filter[24] = 0.190176552;
  246.  
  247. chroma_filter[0] = -0.000118847;
  248. chroma_filter[1] = -0.000271306;
  249. chroma_filter[2] = -0.000502642;
  250. chroma_filter[3] = -0.000930833;
  251. chroma_filter[4] = -0.001451013;
  252. chroma_filter[5] = -0.002064744;
  253. chroma_filter[6] = -0.002700432;
  254. chroma_filter[7] = -0.003241276;
  255. chroma_filter[8] = -0.003524948;
  256. chroma_filter[9] = -0.003350284;
  257. chroma_filter[10] = -0.002491729;
  258. chroma_filter[11] = -0.000721149;
  259. chroma_filter[12] = 0.002164659;
  260. chroma_filter[13] = 0.006313635;
  261. chroma_filter[14] = 0.011789103;
  262. chroma_filter[15] = 0.018545660;
  263. chroma_filter[16] = 0.026414396;
  264. chroma_filter[17] = 0.035100710;
  265. chroma_filter[18] = 0.044196567;
  266. chroma_filter[19] = 0.053207202;
  267. chroma_filter[20] = 0.061590275;
  268. chroma_filter[21] = 0.068803602;
  269. chroma_filter[22] = 0.074356193;
  270. chroma_filter[23] = 0.077856564;
  271. chroma_filter[24] = 0.079052396;
  272.  
  273. if (bUseTwoPhase){
  274.  
  275. TAPS = 32;
  276.  
  277. luma_filter[0] = -0.000205844;
  278. luma_filter[1] = -0.000149453;
  279. luma_filter[2] = -0.000051693;
  280. luma_filter[3] = 0.000000000;
  281. luma_filter[4] = -0.000066171;
  282. luma_filter[5] = -0.000245058;
  283. luma_filter[6] = -0.000432928;
  284. luma_filter[7] = -0.000472644;
  285. luma_filter[8] = -0.000252236;
  286. luma_filter[9] = 0.000198929;
  287. luma_filter[10] = 0.000687058;
  288. luma_filter[11] = 0.000944112;
  289. luma_filter[12] = 0.000803467;
  290. luma_filter[13] = 0.000363199;
  291. luma_filter[14] = 0.000013422;
  292. luma_filter[15] = 0.000253402;
  293. luma_filter[16] = 0.001339461;
  294. luma_filter[17] = 0.002932972;
  295. luma_filter[18] = 0.003983485;
  296. luma_filter[19] = 0.003026683;
  297. luma_filter[20] = -0.001102056;
  298. luma_filter[21] = -0.008373026;
  299. luma_filter[22] = -0.016897700;
  300. luma_filter[23] = -0.022914480;
  301. luma_filter[24] = -0.021642347;
  302. luma_filter[25] = -0.008863273;
  303. luma_filter[26] = 0.017271957;
  304. luma_filter[27] = 0.054921920;
  305. luma_filter[28] = 0.098342579;
  306. luma_filter[29] = 0.139044281;
  307. luma_filter[30] = 0.168055832;
  308. luma_filter[31] = 0.178571429;
  309.  
  310. chroma_filter[0] = 0.001384762;
  311. chroma_filter[1] = 0.001678312;
  312. chroma_filter[2] = 0.002021715;
  313. chroma_filter[3] = 0.002420562;
  314. chroma_filter[4] = 0.002880460;
  315. chroma_filter[5] = 0.003406879;
  316. chroma_filter[6] = 0.004004985;
  317. chroma_filter[7] = 0.004679445;
  318. chroma_filter[8] = 0.005434218;
  319. chroma_filter[9] = 0.006272332;
  320. chroma_filter[10] = 0.007195654;
  321. chroma_filter[11] = 0.008204665;
  322. chroma_filter[12] = 0.009298238;
  323. chroma_filter[13] = 0.010473450;
  324. chroma_filter[14] = 0.011725413;
  325. chroma_filter[15] = 0.013047155;
  326. chroma_filter[16] = 0.014429548;
  327. chroma_filter[17] = 0.015861306;
  328. chroma_filter[18] = 0.017329037;
  329. chroma_filter[19] = 0.018817382;
  330. chroma_filter[20] = 0.020309220;
  331. chroma_filter[21] = 0.021785952;
  332. chroma_filter[22] = 0.023227857;
  333. chroma_filter[23] = 0.024614500;
  334. chroma_filter[24] = 0.025925203;
  335. chroma_filter[25] = 0.027139546;
  336. chroma_filter[26] = 0.028237893;
  337. chroma_filter[27] = 0.029201910;
  338. chroma_filter[28] = 0.030015081;
  339. chroma_filter[29] = 0.030663170;
  340. chroma_filter[30] = 0.031134640;
  341. chroma_filter[31] = 0.031420995;
  342. chroma_filter[32] = 0.031517031;
  343. }
  344.  
  345. float one_x = 1.0 / ReShade::ScreenSize.x;
  346. float3 signal = float3(0.0,0.0,0.0);
  347. for (int i = 0; i < TAPS; i++)
  348. {
  349. float offset = float(i);
  350.  
  351. float3 sums = fetch_offset(offset - float(TAPS), one_x) +
  352. fetch_offset(float(TAPS) - offset, one_x);
  353.  
  354. signal += sums * float3(luma_filter[i], chroma_filter[i], chroma_filter[i]);
  355. }
  356. signal += tex2D(s0, texcoord).xyz *
  357. float3(luma_filter[TAPS], chroma_filter[TAPS], chroma_filter[TAPS]);
  358.  
  359. float3 rgb = yiq2rgb(signal);
  360. return float4(rgb, 1.0);
  361. }
  362.  
  363. float4 NTSCGaussPS( float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target
  364. {
  365.  
  366. float2 pix_no = texcoord * display_size * float2( 4.0, 1.0 );
  367. float2 one = 1.0 / ReShade::ScreenSize;
  368.  
  369. #define TEX(off) pow(tex2D(ReShade::BackBuffer, texcoord + float2(0.0, (off) * one.y)).rgb, float3(NTSC_CRT_GAMMA,NTSC_CRT_GAMMA,NTSC_CRT_GAMMA))
  370.  
  371. float3 frame0 = TEX(-2.0);
  372. float3 frame1 = TEX(-1.0);
  373. float3 frame2 = TEX(0.0);
  374. float3 frame3 = TEX(1.0);
  375. float3 frame4 = TEX(2.0);
  376.  
  377. float offset_dist = frac(pix_no.y) - 0.5;
  378. float dist0 = 2.0 + offset_dist;
  379. float dist1 = 1.0 + offset_dist;
  380. float dist2 = 0.0 + offset_dist;
  381. float dist3 = -1.0 + offset_dist;
  382. float dist4 = -2.0 + offset_dist;
  383.  
  384. float3 scanline = frame0 * exp(-5.0 * dist0 * dist0);
  385. scanline += frame1 * exp(-5.0 * dist1 * dist1);
  386. scanline += frame2 * exp(-5.0 * dist2 * dist2);
  387. scanline += frame3 * exp(-5.0 * dist3 * dist3);
  388. scanline += frame4 * exp(-5.0 * dist4 * dist4);
  389.  
  390. return float4(pow(1.15 * scanline, float3(1.0 / NTSC_DISPLAY_GAMMA, 1.0 / NTSC_DISPLAY_GAMMA, 1.0 / NTSC_DISPLAY_GAMMA)), 1.0);
  391. }
  392.  
  393. float4 NTSCFinalPS( float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target
  394. {
  395. return tex2D(ReShade::BackBuffer,texcoord);
  396. }
  397.  
  398.  
  399. technique NTSC_RetroArch
  400. {
  401. // second pass: encode s-video signal
  402. pass p1
  403. {
  404. RenderTarget = target0;
  405.  
  406. VertexShader = PostProcessVS;
  407. PixelShader = NTSCEncodePS;
  408. }
  409.  
  410. // third pass: decode composite signal
  411. pass p2
  412. {
  413. VertexShader = PostProcessVS;
  414. PixelShader = NTSCDecodePS;
  415. }
  416. pass p3
  417. {
  418. VertexShader = PostProcessVS;
  419. PixelShader = NTSCGaussPS;
  420. }
  421. // final pass: decode composite signal
  422. pass p4
  423. {
  424. VertexShader = PostProcessVS;
  425. PixelShader = NTSCFinalPS;
  426. }
  427. }
RAW Paste Data