Advertisement
Guest User

Untitled

a guest
Jun 15th, 2021
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.31 KB | None | 0 0
  1. // NES PAL composite signal simulation for RetroArch
  2. // shader by r57shell
  3. // thanks to feos & HardWareMan & NewRisingSun
  4.  
  5. // also TV subpixels and scanlines
  6.  
  7. // LICENSE: PUBLIC DOMAIN
  8.  
  9. // NOTE: for nice TV subpixels and scanlines I recommend to
  10. // disable this features here and apply CRT-specialized shader.
  11.  
  12. // Quality considerations
  13.  
  14. // there are three main options:
  15. // USE_RAW (R), USE_DELAY_LINE (D), USE_COLORIMETRY (C)
  16. // here is table of quality in decreasing order:
  17. // RDC, RD, RC, DC, D, C
  18.  
  19. // compatibility macros
  20. #define float2 vec2
  21. #define float3 vec3
  22. #define float4 vec4
  23. #define frac(c) fract(c)
  24. #define saturate(c) clamp(c, 0.0, 1.0)
  25. #define fmod(x,y) mod(x,y)
  26. #define mul(x,y) (y*x)
  27. #define float2x2 mat2
  28. #define float3x3 mat3
  29. #define float4x4 mat4
  30. #define bool2 bvec2
  31. #define bool3 bvec3
  32. #define bool4 bvec4
  33. #define static
  34.  
  35. // TWEAKS start
  36.  
  37. // uncomment this to disable dynamic settings, and use static.
  38. // if you unable to compile shader with dynamic settings,
  39. // and you want to tune parameters in menu, then
  40. // try to reduce somewhere below Mwidth from 32 to lower,
  41. // or disable USE_DELAY_LINE or USE_RAW, or all at once.
  42. //#undef PARAMETER_UNIFORM
  43.  
  44. // use delay line technique
  45. // without delay line technique, color would interleave
  46. // to avoid this, set HueRotation to zero.
  47. #define USE_DELAY_LINE
  48.  
  49. // use this if you need to swap even/odd V sign.
  50. // sign of V changes each scanline
  51. // so if some scanline is positive, then next is negative
  52. // and if you want to match picture
  53. // to actual running PAL NES on TV
  54. // you may want to have this option, to change signs
  55. // if they don't match
  56. //#define SWAP_VSIGN
  57.  
  58. // phase shift from frame to frame as NTSC NES does.
  59. // but PAL NES doesn't
  60. //#define ANIMATE_PHASE
  61.  
  62. // rough simulation of scanlines
  63. // better if you use additional shader instead
  64. // if you still use it, make sure that SizeY
  65. // is at least twice lower than output height
  66. //#define USE_SCANLINES
  67.  
  68. // this option changes active visible fields.
  69. // this is not how actual NES works
  70. // it does not alter fields.
  71. //#define ANIMATE_SCANLINE
  72.  
  73. // simulate CRT TV subpixels
  74. // better if you use CRT-specialized shader instead
  75. //#define USE_SUBPIXELS
  76.  
  77. // to change gamma of virtual TV from 2.2 to something else
  78. //#define USE_GAMMA
  79.  
  80. // use core size. for NES use this, for other cores turn off
  81. // for other cores use "size" tweak.
  82. //#define USE_CORE_SIZE
  83.  
  84. // use raw palette, turn it on if you
  85. // have nestopia and having using raw palette
  86. //#define USE_RAW
  87.  
  88. // use lookup texture, faster but less accuracy
  89. // it's working only if USE_RAW enabled.
  90. //#define USE_LUT
  91.  
  92. // compensate filter width
  93. // it will make width of picture shorter
  94. // to make picture right border visible
  95. #define COMPENSATE_WIDTH
  96.  
  97. // use sampled version. it's much more slower version of shader.
  98. // because it is computing x4 more values. NOT RECOMMENDED.
  99. //#define USE_SAMPLED
  100.  
  101. // this is using following matrixes.
  102. // it provides more scientific approach
  103. // by conversion into linear XYZ space
  104. // and back to sRGB.
  105. // it's using Gamma setting too.
  106. // define USE_GAMMA is not required.
  107. #define USE_COLORIMETRY
  108.  
  109. // TWEAKS end
  110.  
  111. #pragma parameter USE_RAW_param "(NES ONLY) Decode RAW Colors" 0.0 0.0 1.0 1.0
  112. #pragma parameter USE_LUT_param "(NES ONLY) Use RAW LUT For Speed" 0.0 0.0 1.0 1.0
  113.  
  114. #pragma parameter Gamma "PAL Gamma" 2.5 0.0 10.0 0.03125
  115. #pragma parameter Brightness "PAL Brightness" 0.0 -1.0 2.0 0.03125
  116. #pragma parameter Contrast "PAL Contrast" 1.0 -1.0 2.0 0.03125
  117. #pragma parameter Saturation "PAL Saturation" 1.0 -1.0 2.0 0.03125
  118. #pragma parameter HueShift "PAL Hue Shift" -2.5 -6.0 6.0 0.015625
  119. #pragma parameter HueRotation "PAL Hue Rotation" 2.0 -5.0 5.0 0.015625
  120. #pragma parameter Ywidth "PAL Y Width" 12.0 1.0 32.0 1.0
  121. #pragma parameter Uwidth "PAL U Width" 23.0 1.0 32.0 1.0
  122. #pragma parameter Vwidth "PAL V Width" 23.0 1.0 32.0 1.0
  123. #pragma parameter SizeX "Active Width" 256.0 1.0 4096.0 1.0
  124. #pragma parameter SizeY "Active Height" 240.0 1.0 4096.0 1.0
  125. #pragma parameter TV_Pixels "PAL TV Pixels" 200.0 1.0 2400.0 1.0
  126. #pragma parameter dark_scanline "PAL Scanline" 0.5 0.0 1.0 0.025
  127. #pragma parameter Phase_Y "PAL Phase Y" 2.0 0.0 12.0 0.025
  128. #pragma parameter Phase_One "PAL Phase One" 0.0 0.0 12.0 0.025
  129. #pragma parameter Phase_Two "PAL Phase Two" 8.0 0.0 12.0 0.025
  130.  
  131. #if defined(VERTEX)
  132.  
  133. #if __VERSION__ >= 130
  134. #define COMPAT_VARYING out
  135. #define COMPAT_ATTRIBUTE in
  136. #define COMPAT_TEXTURE texture
  137. #else
  138. #define COMPAT_VARYING varying
  139. #define COMPAT_ATTRIBUTE attribute
  140. #define COMPAT_TEXTURE texture2D
  141. #endif
  142.  
  143. #ifdef GL_ES
  144. #define COMPAT_PRECISION mediump
  145. #else
  146. #define COMPAT_PRECISION
  147. #endif
  148.  
  149. // have to duplicate these in both stages...
  150. #ifdef PARAMETER_UNIFORM
  151. uniform COMPAT_PRECISION float Gamma;
  152. uniform COMPAT_PRECISION float Brightness;
  153. uniform COMPAT_PRECISION float Contrast;
  154. uniform COMPAT_PRECISION float Saturation;
  155. uniform COMPAT_PRECISION float HueShift;
  156. uniform COMPAT_PRECISION float HueRotation;
  157. uniform COMPAT_PRECISION float Ywidth;
  158. uniform COMPAT_PRECISION float Uwidth;
  159. uniform COMPAT_PRECISION float Vwidth;
  160. uniform COMPAT_PRECISION float TV_Pixels;
  161. uniform COMPAT_PRECISION float SizeX;
  162. uniform COMPAT_PRECISION float SizeY;
  163. uniform COMPAT_PRECISION float dark_scanline;
  164. uniform COMPAT_PRECISION float Phase_Y;
  165. uniform COMPAT_PRECISION float Phase_One;
  166. uniform COMPAT_PRECISION float Phase_Two;
  167. uniform COMPAT_PRECISION float USE_RAW_param;
  168. uniform COMPAT_PRECISION float USE_LUT_param;
  169.  
  170. bool USE_RAW = bool(USE_RAW_param);
  171. bool USE_LUT = bool(USE_LUT_param);
  172.  
  173. static const float Mwidth = 24.;
  174.  
  175. static const int Ywidth_static = 1;
  176. static const int Uwidth_static = 1;
  177. static const int Vwidth_static = 1;
  178.  
  179. static const float Contrast_static = 1.;
  180. static const float Saturation_static = 1.;
  181.  
  182. #else
  183.  
  184. #define Brightness Brightness_static
  185. #define Gamma Gamma_static
  186.  
  187. #define Ywidth Ywidth_static
  188. #define Uwidth Uwidth_static
  189. #define Vwidth Vwidth_static
  190.  
  191. static const int Mwidth = max(float(Ywidth), max(float(Uwidth), float(Vwidth)));
  192.  
  193. #ifdef USE_CORE_SIZE
  194. // just use core output size.
  195. #define size (InputSize.xy)
  196. #else
  197. static const float2 size = float2(SizeX,SizeY);
  198. #endif
  199.  
  200. #endif
  201.  
  202. #ifndef PARAMETER_UNIFORM
  203.  
  204. // use true/false to toggle
  205. bool USE_RAW = false;
  206. bool USE_LUT = false;
  207.  
  208. // NTSC standard gamma = 2.2
  209. // PAL standard gamma = 2.8
  210. // according to many sources, very unlikely gamma of TV is 2.8
  211. // most likely gamma of PAL TV is in range 2.4-2.5
  212. static const float Gamma_static = 2.5; // gamma of virtual TV
  213.  
  214. static const float Brightness_static = 0.0;
  215. static const float Contrast_static = 1.0;
  216. static const float Saturation_static = 1.0;
  217.  
  218. static const int
  219. Ywidth_static = 12,
  220. Uwidth_static = 23,
  221. Vwidth_static = 23;
  222.  
  223. // correct one is -2.5
  224. // works only with USE_RAW
  225. static const float HueShift = -2.5;
  226.  
  227. // rotation of hue due to luma level.
  228. static const float HueRotation = 2.;
  229.  
  230. // touch this only if you know what you doing
  231. static const float Phase_Y = 2.; // fmod(341*10,12)
  232. static const float Phase_One = 0.; // alternating phases.
  233. static const float Phase_Two = 8.;
  234.  
  235. // screen size, scanlines = y*2; y one field, and y other field.
  236. static const int SizeX = 256;
  237. static const int SizeY = 240;
  238.  
  239. // count of pixels of virtual TV.
  240. // value close to 1000 produce small artifacts
  241. static const int TV_Pixels = 400;
  242.  
  243. static const float dark_scanline = 0.5; // half
  244.  
  245. #endif
  246.  
  247. COMPAT_ATTRIBUTE vec4 VertexCoord;
  248. COMPAT_ATTRIBUTE vec4 COLOR;
  249. COMPAT_ATTRIBUTE vec4 TexCoord;
  250. COMPAT_VARYING vec4 COL0;
  251. COMPAT_VARYING vec4 TEX0;
  252. COMPAT_VARYING float DeltaV;
  253. COMPAT_VARYING float Voltage_0;
  254. COMPAT_VARYING float Voltage_1;
  255.  
  256. vec4 _oPosition1;
  257. uniform mat4 MVPMatrix;
  258. uniform COMPAT_PRECISION int FrameDirection;
  259. uniform COMPAT_PRECISION int FrameCount;
  260. uniform COMPAT_PRECISION vec2 OutputSize;
  261. uniform COMPAT_PRECISION vec2 TextureSize;
  262. uniform COMPAT_PRECISION vec2 InputSize;
  263.  
  264. // compatibility #defines
  265. #define vTexCoord TEX0.xy
  266. #define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
  267. #define OutSize vec4(OutputSize, 1.0 / OutputSize)
  268.  
  269. void main()
  270. {
  271. gl_Position = MVPMatrix * VertexCoord;
  272. TEX0.xy = TexCoord.xy;
  273.  
  274. if(USE_RAW)
  275. {
  276. Voltage_0 = (!USE_LUT) ? 0.518 : 0.15103768593097774;
  277. Voltage_1 = (!USE_LUT) ? 1.962 : 1.;
  278. DeltaV = (Voltage_1-Voltage_0);
  279. }
  280. else DeltaV = 1.;
  281. }
  282.  
  283. #elif defined(FRAGMENT)
  284.  
  285. #ifdef GL_ES
  286. #ifdef GL_FRAGMENT_PRECISION_HIGH
  287. precision highp float;
  288. #else
  289. precision mediump float;
  290. #endif
  291. #define COMPAT_PRECISION mediump
  292. #else
  293. #define COMPAT_PRECISION
  294. #endif
  295.  
  296. #if __VERSION__ >= 130
  297. #define COMPAT_VARYING in
  298. #define COMPAT_TEXTURE texture
  299. out COMPAT_PRECISION vec4 FragColor;
  300. #else
  301. #define COMPAT_VARYING varying
  302. #define FragColor gl_FragColor
  303. #define COMPAT_TEXTURE texture2D
  304. #endif
  305.  
  306. #ifdef PARAMETER_UNIFORM
  307. uniform COMPAT_PRECISION float Gamma;
  308. uniform COMPAT_PRECISION float Brightness;
  309. uniform COMPAT_PRECISION float Contrast;
  310. uniform COMPAT_PRECISION float Saturation;
  311. uniform COMPAT_PRECISION float HueShift;
  312. uniform COMPAT_PRECISION float HueRotation;
  313. uniform COMPAT_PRECISION float Ywidth;
  314. uniform COMPAT_PRECISION float Uwidth;
  315. uniform COMPAT_PRECISION float Vwidth;
  316. uniform COMPAT_PRECISION float TV_Pixels;
  317. uniform COMPAT_PRECISION float SizeX;
  318. uniform COMPAT_PRECISION float SizeY;
  319. uniform COMPAT_PRECISION float dark_scanline;
  320. uniform COMPAT_PRECISION float Phase_Y;
  321. uniform COMPAT_PRECISION float Phase_One;
  322. uniform COMPAT_PRECISION float Phase_Two;
  323. uniform COMPAT_PRECISION float USE_RAW_param;
  324. uniform COMPAT_PRECISION float USE_LUT_param;
  325.  
  326. bool USE_RAW = bool(USE_RAW_param);
  327. bool USE_LUT = bool(USE_LUT_param);
  328.  
  329. static const float Mwidth = 24.;
  330.  
  331. static const int Ywidth_static = 1;
  332. static const int Uwidth_static = 1;
  333. static const int Vwidth_static = 1;
  334.  
  335. static const float Contrast_static = 1.;
  336. static const float Saturation_static = 1.;
  337.  
  338. #else
  339.  
  340. #define Brightness Brightness_static
  341. #define Gamma Gamma_static
  342.  
  343. #define Ywidth Ywidth_static
  344. #define Uwidth Uwidth_static
  345. #define Vwidth Vwidth_static
  346.  
  347. static const int Mwidth = max(float(Ywidth), max(float(Uwidth), float(Vwidth)));
  348.  
  349. #ifdef USE_CORE_SIZE
  350. // just use core output size.
  351. #define size (InputSize.xy)
  352. #else
  353. static const float2 size = float2(SizeX,SizeY);
  354. #endif
  355.  
  356. #endif
  357.  
  358. #ifndef PARAMETER_UNIFORM
  359.  
  360. // use true/false to toggle
  361. bool USE_RAW = false;
  362. bool USE_LUT = false;
  363.  
  364. // NTSC standard gamma = 2.2
  365. // PAL standard gamma = 2.8
  366. // according to many sources, very unlikely gamma of TV is 2.8
  367. // most likely gamma of PAL TV is in range 2.4-2.5
  368. static const float Gamma_static = 2.5; // gamma of virtual TV
  369.  
  370. static const float Brightness_static = 0.0;
  371. static const float Contrast_static = 1.0;
  372. static const float Saturation_static = 1.0;
  373.  
  374. static const int
  375. Ywidth_static = 12,
  376. Uwidth_static = 23,
  377. Vwidth_static = 23;
  378.  
  379. // correct one is -2.5
  380. // works only with USE_RAW
  381. static const float HueShift = -2.5;
  382.  
  383. // rotation of hue due to luma level.
  384. static const float HueRotation = 2.;
  385.  
  386. // touch this only if you know what you doing
  387. static const float Phase_Y = 2.; // fmod(341*10,12)
  388. static const float Phase_One = 0.; // alternating phases.
  389. static const float Phase_Two = 8.;
  390.  
  391. // screen size, scanlines = y*2; y one field, and y other field.
  392. static const int SizeX = 256;
  393. static const int SizeY = 240;
  394.  
  395. // count of pixels of virtual TV.
  396. // value close to 1000 produce small artifacts
  397. static const int TV_Pixels = 400;
  398.  
  399. static const float dark_scanline = 0.5; // half
  400.  
  401. #endif
  402.  
  403. uniform COMPAT_PRECISION int FrameDirection;
  404. uniform COMPAT_PRECISION int FrameCount;
  405. uniform COMPAT_PRECISION vec2 OutputSize;
  406. uniform COMPAT_PRECISION vec2 TextureSize;
  407. uniform COMPAT_PRECISION vec2 InputSize;
  408. uniform sampler2D Texture;
  409. uniform sampler2D nes_lut;
  410. COMPAT_VARYING vec4 TEX0;
  411. COMPAT_VARYING float DeltaV;
  412. COMPAT_VARYING float Voltage_0;
  413. COMPAT_VARYING float Voltage_1;
  414.  
  415. // compatibility #defines
  416. #define Source Texture
  417. #define vTexCoord TEX0.xy
  418.  
  419. #define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
  420. #define OutSize vec4(OutputSize, 1.0 / OutputSize)
  421.  
  422. static const mat3 RGB_to_XYZ =
  423. mat3(
  424. 0.4306190, 0.3415419, 0.1783091,
  425. 0.2220379, 0.7066384, 0.0713236,
  426. 0.0201853, 0.1295504, 0.9390944
  427. );
  428.  
  429. static const mat3 XYZ_to_sRGB =
  430. mat3(
  431. 3.2406, -1.5372, -0.4986,
  432. -0.9689, 1.8758, 0.0415,
  433. 0.0557, -0.2040, 1.0570
  434. );
  435.  
  436. static const float YUV_u = 0.492;
  437. static const float YUV_v = 0.877;
  438.  
  439. static const mat3 RGB_to_YUV =
  440. mat3(
  441. float3( 0.299, 0.587, 0.114), //Y
  442. float3(-0.299,-0.587, 0.886)*YUV_u, //B-Y
  443. float3( 0.701,-0.587,-0.114)*YUV_v //R-Y
  444. );
  445.  
  446. #ifdef USE_DELAY_LINE
  447. static const float comb_line = 1.;
  448. #else
  449. static const float comb_line = 2.;
  450. #endif
  451.  
  452. static float RGB_y = Contrast_static/float(Ywidth_static)/DeltaV;
  453. static float RGB_u = comb_line*Contrast_static*Saturation_static/YUV_u/float(Uwidth_static)/DeltaV;
  454. static float RGB_v = comb_line*Contrast_static*Saturation_static/YUV_v/float(Vwidth_static)/DeltaV;
  455.  
  456. static const float pi = 3.1415926535897932384626433832795;
  457.  
  458. bool InColorPhase(int color, float phase)
  459. {
  460. return fmod((float(color)*2. + phase),24.) < 12.;
  461. }
  462.  
  463. // signal low
  464. const float levels_0 = 0.350;
  465. const float levels_1 = 0.518;
  466. const float levels_2 = 0.962;
  467. const float levels_3 = 1.550;
  468. // signal high
  469. const float levels_4 = 1.094;
  470. const float levels_5 = 1.506;
  471. const float levels_6 = 1.962;
  472. const float levels_7 = 1.962;
  473.  
  474. // from nesdev wiki page NTSC_video
  475. float NTSCsignal(float3 pixel, float phase)
  476. {
  477. // use LUT for RAW palette decoding for speed vs quality and return early
  478. if(USE_LUT) return COMPAT_TEXTURE(nes_lut,float2(dot(pixel,float3(
  479. 15.*(8.)/512.,
  480. 3.*(16.*8.)/512.,
  481. 7./512.)
  482. ) + 0.5/(4.*16.*8.), frac(phase/24.))).r;
  483.  
  484. // Voltage levels, relative to synch voltage
  485. static const float black=.518, white=1.962, attenuation=.746;
  486.  
  487. // Decode the NES color.
  488. int color = int(pixel.r*15.); // 0..15 "cccc"
  489. int level = int(pixel.g*3.); // 0..3 "ll"
  490. int emphasis = int(pixel.b*7.+0.1); // 0..7 "eee"
  491. if (color > 13) { level = 1; } // For colors 14..15, level 1 is forced.
  492.  
  493. // The square wave for this color alternates between these two voltages:
  494. float low = levels_0, high = levels_4;
  495. if (level == 1) { low = levels_1, high = levels_5; }
  496. if (level == 2) { low = levels_2, high = levels_6; }
  497. if (level == 3) { low = levels_3, high = levels_7; }
  498. if(color == 0) { low = high; } // For color 0, only high level is emitted
  499. if(color > 12) { high = low; } // For colors 13..15, only low level is emitted
  500.  
  501.  
  502. // Generate the square wave
  503. // When de-emphasis bits are set, some parts of the signal are attenuated:
  504. float2 e = fmod(float2(emphasis,emphasis), float2(2.,4.));
  505. float signal = InColorPhase(color,phase) ? high : low;
  506.  
  507. if( ((int(e.x) != 0) && InColorPhase(0,phase))
  508. || ((int(e.y-e.x) != 0) && InColorPhase(4,phase))
  509. || ((emphasis-int(e.y) != 0) && InColorPhase(8,phase)) )
  510. return signal * attenuation;
  511. else
  512. return signal;
  513. }
  514.  
  515. float sinn(float x)
  516. {
  517. return sin(/*fmod(x,24)*/x*(pi*2./24.));
  518. }
  519.  
  520. float coss(float x)
  521. {
  522. return cos(/*fmod(x,24)*/x*(pi*2./24.));
  523. }
  524.  
  525. float3 monitor(sampler2D tex, float2 p)
  526. {
  527. mat3 YUV_to_RGB = mat3(
  528. float3(1., 1., 1.)*RGB_y,
  529. float3(0., -0.114/0.587, 1.)*RGB_u,
  530. float3(1., -0.299/0.587, 0.)*RGB_v
  531. );
  532. #ifdef PARAMETER_UNIFORM
  533. float2 size = float2(SizeX,SizeY);
  534. #endif
  535. // align vertical coord to center of texel
  536. float2 uv = float2(
  537. #ifdef COMPENSATE_WIDTH
  538. p.x+p.x*(Ywidth/8.)/size.x,
  539. #else
  540. p.x,
  541. #endif
  542. (floor(p.y*TextureSize.y)+0.5)/TextureSize.y);
  543. #ifdef USE_DELAY_LINE
  544. float2 sh = (InputSize/TextureSize/size)*float2(14./10.,-1.0);
  545. #endif
  546. float2 pc = uv*TextureSize/InputSize*size*float2(10.,1.);
  547. float alpha = dot(floor(float2(pc.x,pc.y)),float2(2.,Phase_Y*2.));
  548. alpha += Phase_One*2.;
  549. #ifdef ANIMATE_PHASE
  550. if (fmod(FrameCount,2) > 1.)
  551. alpha += (Phase_Two-Phase_One)*2.;
  552. #endif
  553.  
  554. // 1/size.x of screen in uv coords = InputSize.x/TextureSize.x/size.x;
  555. // then 1/10*size.x of screen:
  556. float ustep = InputSize.x/TextureSize.x/size.x/10.;
  557.  
  558. float border = InputSize.x/TextureSize.x;
  559. float ss = 2.0;
  560. #ifdef SWAP_VSIGN
  561. #define PAL_SWITCH(A) A < 1.
  562. #else
  563. #define PAL_SWITCH(A) A > 1.
  564. #endif
  565. if (PAL_SWITCH(fmod(uv.y*TextureSize.y/InputSize.y*size.y,2.0)))
  566. {
  567. // cos(pi-alpha) = -cos(alpha)
  568. // sin(pi-alpha) = sin(alpha)
  569. // pi - alpha
  570. alpha = -alpha+12012.0;
  571. ss = -2.0;
  572. }
  573.  
  574. float ysum = 0., usum = 0., vsum = 0., sig = 0., sig1 = 0.;
  575. for (int i=0; i<int(Mwidth); ++i)
  576. {
  577. float4 res = COMPAT_TEXTURE(tex, uv);
  578.  
  579. if(USE_RAW)
  580. {
  581. sig = NTSCsignal(res.xyz,HueShift*2.+alpha-res.g*ss*HueRotation)-Voltage_0;
  582. // outside of texture is 0,0,0 which is white instead of black
  583. if (uv.x <= 0.0 || uv.x >= border)
  584. sig = 0.;
  585. #ifdef USE_DELAY_LINE
  586. float4 res1 = COMPAT_TEXTURE(tex, uv+sh);
  587. sig1 = NTSCsignal(res1.xyz,HueShift*2.+12012.0-alpha+res.g*ss*HueRotation)-Voltage_0;
  588. if (uv.x + sh.x <= 0.0 || uv.x + sh.x >= border)
  589. sig1 = 0.;
  590. #endif
  591. }
  592. else
  593. {
  594. float3 yuv = mul(RGB_to_YUV, res.xyz);
  595. float a1 = alpha+(HueShift+2.5)*2.-yuv.x*ss*HueRotation;
  596. sig = yuv.x+dot(yuv.yz,sign(float2(sinn(a1),coss(a1))));
  597. #ifdef USE_DELAY_LINE
  598. float4 res1 = COMPAT_TEXTURE(tex, uv+sh);
  599. float3 yuv1 = mul(RGB_to_YUV, res1.xyz);
  600. float a2 = (HueShift+2.5)*2.+12012.0-alpha+yuv.x*ss*HueRotation;
  601. sig1 = yuv1.x+dot(yuv1.yz,sign(float2(sinn(a2),coss(a2))));
  602. #endif
  603. }
  604. if (i < int(Ywidth))
  605. ysum += sig;
  606.  
  607. #ifdef USE_DELAY_LINE
  608. if (i < int(Uwidth))
  609. usum += (sig+sig1)*sinn(alpha);
  610. if (i < int(Vwidth))
  611. vsum += (sig-sig1)*coss(alpha);
  612. #else
  613. if (i < int(Uwidth))
  614. usum += sig*sinn(alpha);
  615. if (i < int(Vwidth))
  616. vsum += sig*coss(alpha);
  617. #endif
  618. alpha -= ss;
  619. uv.x -= ustep;
  620. }
  621.  
  622. #ifdef PARAMETER_UNIFORM
  623. ysum *= Contrast/Ywidth;
  624. usum *= Contrast*Saturation/Uwidth;
  625. vsum *= Contrast*Saturation/Vwidth;
  626. #endif
  627.  
  628. float3 rgb = mul(float3(ysum+Brightness*float(Ywidth_static),usum,vsum), YUV_to_RGB);
  629. #if defined(USE_GAMMA) && !defined(USE_COLORIMETRY)
  630. float3 rgb1 = saturate(rgb);
  631. rgb = pow(rgb1, float3(Gamma/2.2,Gamma/2.2,Gamma/2.2));
  632. #endif
  633.  
  634. #ifdef USE_COLORIMETRY
  635. float3 rgb1 = saturate(rgb);
  636. rgb = pow(rgb1, float3(Gamma,Gamma,Gamma));
  637. #endif
  638.  
  639. #if (defined(USE_SUBPIXELS) || defined(USE_SCANLINES))
  640. float2 q = (p*TextureSize/InputSize)*float2(TV_Pixels*3.,size.y*2.);
  641. #endif
  642.  
  643. #ifdef USE_SCANLINES
  644. float scanlines = size.y/OutputSize.x;
  645. float top = fmod(q.y-0.5*scanlines*2.,2.);
  646. float bottom = top+frac(scanlines)*2.;
  647. float2 sw = saturate(min(float2(1.,2.),float2(bottom, bottom))
  648. -max(float2(0.,1.),float2(top)))
  649. +saturate(min(float2(3.,4.),float2(bottom, bottom))
  650. -max(float2(2.,3.),float2(top)))
  651. +floor(scanlines);
  652. #ifdef ANIMATE_SCANLINE
  653. #define SCANLINE_MUL (fmod(float(FrameCount),2.0)<1.0001 \
  654. ? sw.x*dark_scanline+sw.y \
  655. : sw.x+sw.y*dark_scanline)
  656. #else
  657. #define SCANLINE_MUL (sw.x*dark_scanline+sw.y)
  658. #endif
  659. rgb = rgb*SCANLINE_MUL/(sw.x+sw.y);
  660.  
  661. /*
  662. //old stupid method
  663. float z =
  664. #ifdef ANIMATE_SCANLINE
  665. fmod(FrameCount,2.0)+
  666. #endif
  667. 0.5;
  668.  
  669. if (abs(fmod(q.y+0.5,2)-z)<0.5)
  670. rgb *= dark_scanline;
  671. */
  672. #endif
  673.  
  674. // size of pixel screen in texture coords:
  675. //float output_pixel_size = InputSize.x/(OutputSize.x*TextureSize.x);
  676.  
  677. // correctness check
  678. //if (fmod(p.x*output_pixel_size,2.0) < 1.0)
  679. // rgb = float3(0.,0.,0.);
  680.  
  681. #ifdef USE_SUBPIXELS
  682. float pixels = TV_Pixels/OutputSize.x;
  683. float left = fmod(q.x-0.5*pixels*3.,3.);
  684. float right = left+frac(pixels)*3.;
  685. float3 w = saturate(min(float3(1.,2.,3.),float3(right,right,right))
  686. -max(float3(0.,1.,2.),float3(left,left,left)))
  687. +saturate(min(float3(4.,5.,6.),float3(right,right,right))
  688. -max(float3(3.,4.,5.),float3(left,left,left)))
  689. +floor(pixels);
  690. rgb = rgb*3.*w/(w.x+w.y+w.z);
  691. #endif
  692.  
  693. #ifdef USE_COLORIMETRY
  694. float3 xyz1 = mul(RGB_to_XYZ,rgb);
  695. float3 srgb = saturate(mul(XYZ_to_sRGB,xyz1));
  696. float3 a1 = 12.92*srgb;
  697. float3 a2 = 1.055*pow(srgb,float3(1./2.4,1./2.4,1./2.4))-0.055;
  698. float3 ssrgb;
  699. ssrgb.x = (srgb.x<0.0031308?a1.x:a2.x);
  700. ssrgb.y = (srgb.y<0.0031308?a1.y:a2.y);
  701. ssrgb.z = (srgb.z<0.0031308?a1.z:a2.z);
  702. return ssrgb;
  703. #else
  704. return rgb;
  705. #endif
  706. }
  707.  
  708. // pos (left corner, sample size)
  709. float4 monitor_sample(sampler2D tex, float2 p, float2 sample_)
  710. {
  711. // linear interpolation was...
  712. // now other thing.
  713. // http://imgur.com/m8Z8trV
  714. // AT LAST IT WORKS!!!!
  715. // going to check in retroarch...
  716. float2 size = TextureSize;
  717. float2 next = float2(.25,1.)/size;
  718. float2 f = frac(float2(4.,1.)*size*p);
  719. sample_ *= float2(4.,1.)*size;
  720. float2 l;
  721. float2 r;
  722. if (f.x+sample_.x < 1.)
  723. {
  724. l.x = f.x+sample_.x;
  725. r.x = 0.;
  726. }
  727. else
  728. {
  729. l.x = 1.-f.x;
  730. r.x = min(1.,f.x+sample_.x-1.);
  731. }
  732. if (f.y+sample_.y < 1.)
  733. {
  734. l.y = f.y+sample_.y;
  735. r.y = 0.;
  736. }
  737. else
  738. {
  739. l.y = 1.-f.y;
  740. r.y = min(1.,f.y+sample_.y-1.);
  741. }
  742. float3 top = mix(monitor(tex, p), monitor(tex, p+float2(next.x,0.)), r.x/(l.x+r.x));
  743. float3 bottom = mix(monitor(tex, p+float2(0.,next.y)), monitor(tex, p+next), r.x/(l.x+r.x));
  744. return float4(mix(top,bottom, r.y/(l.y+r.y)),1.0);
  745. }
  746.  
  747. void main()
  748. {
  749. #ifdef USE_SAMPLED
  750. FragColor = monitor_sample(Texture, TEX0.xy, 1./OutputSize);
  751. #else
  752. FragColor = float4(monitor(Texture, TEX0.xy), 1.);
  753. #endif
  754. }
  755. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement