Advertisement
vewlix360

zfast+dotmask.glsl

Dec 9th, 2018
385
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.29 KB | None | 0 0
  1. /*
  2. zfast_crt_standard - A simple, fast CRT shader.
  3.  
  4. Copyright (C) 2017 Greg Hogan (SoltanGris42)
  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. Notes: This shader does scaling with a weighted linear filter for adjustable
  13. sharpness on the x and y axes based on the algorithm by Inigo Quilez here:
  14. http://http://www.iquilezles.org/www/articles/texture/texture.htm
  15. but modified to be somewhat sharper. Then a scanline effect that varies
  16. based on pixel brighness is applied along with a monochrome aperture mask.
  17. This shader runs at 60fps on the Raspberry Pi 3 hardware at 2mpix/s
  18. resolutions (1920x1080 or 1600x1200).
  19. */
  20.  
  21. //For testing compilation
  22. //#define FRAGMENT
  23. //#define VERTEX
  24.  
  25. //This can't be an option without slowing the shader down
  26. //Comment this out for a coarser 3 pixel mask...which is currently broken
  27. //on SNES Classic Edition due to Mali 400 gpu precision
  28. //#define FINEMASK
  29. //Some drivers don't return black with texture coordinates out of bounds
  30. //SNES Classic is too slow to black these areas out when using fullscreen
  31. //overlays. But you can uncomment the below to black them out if necessary
  32. //#define BLACK_OUT_BORDER
  33.  
  34. // Parameter lines go here:
  35. #pragma parameter BLURSCALEX "Blur Amount X-Axis" 0.30 0.0 1.0 0.05
  36. #pragma parameter LOWLUMSCAN "Scanline Darkness - Low" 6.0 0.0 10.0 0.5
  37. #pragma parameter HILUMSCAN "Scanline Darkness - High" 8.0 0.0 50.0 1.0
  38. #pragma parameter BRIGHTBOOST "Dark Pixel Brightness Boost" 1.25 0.5 1.5 0.05
  39. #pragma parameter MASK_DARK "Mask Effect Amount" 0.0 0.0 1.0 0.05
  40. #pragma parameter MASK_FADE "Mask/Scanline Fade" 0.8 0.0 1.0 0.05
  41.  
  42. #pragma parameter shadowMask "Mask Style" 3.0 0.0 4.0 1.0
  43. #pragma parameter DOTMASK_STRENGTH "CGWG Dot Mask Strength" 0.3 0.0 1.0 0.01
  44. #pragma parameter maskDark "Lottes maskDark" 0.5 0.0 2.0 0.1
  45. #pragma parameter maskLight "Lottes maskLight" 1.5 0.0 2.0 0.1
  46.  
  47. #if defined(VERTEX)
  48.  
  49. #if __VERSION__ >= 130
  50. #define COMPAT_VARYING out
  51. #define COMPAT_ATTRIBUTE in
  52. #define COMPAT_TEXTURE texture
  53. #else
  54. #define COMPAT_VARYING varying
  55. #define COMPAT_ATTRIBUTE attribute
  56. #define COMPAT_TEXTURE texture2D
  57. #endif
  58.  
  59. #ifdef GL_ES
  60. #define COMPAT_PRECISION mediump
  61. #else
  62. #define COMPAT_PRECISION
  63. #endif
  64.  
  65. COMPAT_ATTRIBUTE vec4 VertexCoord;
  66. COMPAT_ATTRIBUTE vec4 COLOR;
  67. COMPAT_ATTRIBUTE vec4 TexCoord;
  68. COMPAT_VARYING vec4 COL0;
  69. COMPAT_VARYING vec4 TEX0;
  70. COMPAT_VARYING float maskFade;
  71. COMPAT_VARYING vec2 invDims;
  72.  
  73. vec4 _oPosition1;
  74. uniform mat4 MVPMatrix;
  75. uniform COMPAT_PRECISION int FrameDirection;
  76. uniform COMPAT_PRECISION int FrameCount;
  77. uniform COMPAT_PRECISION vec2 OutputSize;
  78. uniform COMPAT_PRECISION vec2 TextureSize;
  79. uniform COMPAT_PRECISION vec2 InputSize;
  80.  
  81. // compatibility #defines
  82. #define vTexCoord TEX0.xy
  83. #define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
  84. #define OutSize vec4(OutputSize, 1.0 / OutputSize)
  85.  
  86. #ifdef PARAMETER_UNIFORM
  87. // All parameter floats need to have COMPAT_PRECISION in front of them
  88. uniform COMPAT_PRECISION float BLURSCALEX;
  89. //uniform COMPAT_PRECISION float BLURSCALEY;
  90. uniform COMPAT_PRECISION float LOWLUMSCAN;
  91. uniform COMPAT_PRECISION float HILUMSCAN;
  92. uniform COMPAT_PRECISION float BRIGHTBOOST;
  93. uniform COMPAT_PRECISION float MASK_DARK;
  94. uniform COMPAT_PRECISION float MASK_FADE;
  95. uniform COMPAT_PRECISION float shadowMask;
  96. uniform COMPAT_PRECISION float DOTMASK_STRENGTH;
  97. uniform COMPAT_PRECISION float maskDark;
  98. uniform COMPAT_PRECISION float maskLight;
  99. #else
  100. #define BLURSCALEX 0.45
  101. //#define BLURSCALEY 0.20
  102. #define LOWLUMSCAN 5.0
  103. #define HILUMSCAN 10.0
  104. #define BRIGHTBOOST 1.25
  105. #define MASK_DARK 0.0
  106. #define MASK_FADE 0.8
  107. #define shadowMask 3.0
  108. #define DOTMASK_STRENGTH 0.3
  109. #define maskDark 0.5
  110. #define maskLight 1.5
  111. #endif
  112.  
  113. void main()
  114. {
  115. gl_Position = MVPMatrix * VertexCoord;
  116.  
  117. TEX0.xy = (TexCoord.xy);
  118. maskFade = 0.3333*MASK_FADE;
  119. invDims = 1.0/TextureSize.xy;
  120. }
  121.  
  122. #elif defined(FRAGMENT)
  123.  
  124. #ifdef GL_ES
  125. #ifdef GL_FRAGMENT_PRECISION_HIGH
  126. precision highp float;
  127. #else
  128. precision mediump float;
  129. #endif
  130. #define COMPAT_PRECISION mediump
  131. #else
  132. #define COMPAT_PRECISION
  133. #endif
  134.  
  135. #if __VERSION__ >= 130
  136. #define COMPAT_VARYING in
  137. #define COMPAT_TEXTURE texture
  138. out COMPAT_PRECISION vec4 FragColor;
  139. #else
  140. #define COMPAT_VARYING varying
  141. #define FragColor gl_FragColor
  142. #define COMPAT_TEXTURE texture2D
  143. #endif
  144.  
  145. uniform COMPAT_PRECISION int FrameDirection;
  146. uniform COMPAT_PRECISION int FrameCount;
  147. uniform COMPAT_PRECISION vec2 OutputSize;
  148. uniform COMPAT_PRECISION vec2 TextureSize;
  149. uniform COMPAT_PRECISION vec2 InputSize;
  150. uniform sampler2D Texture;
  151. COMPAT_VARYING vec4 TEX0;
  152. COMPAT_VARYING float maskFade;
  153. COMPAT_VARYING vec2 invDims;
  154.  
  155. // compatibility #defines
  156. #define Source Texture
  157. #define vTexCoord TEX0.xy
  158. #define texture(c, d) COMPAT_TEXTURE(c, d)
  159. #define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
  160. #define OutSize vec4(OutputSize, 1.0 / OutputSize)
  161.  
  162. #ifdef PARAMETER_UNIFORM
  163. // All parameter floats need to have COMPAT_PRECISION in front of them
  164. uniform COMPAT_PRECISION float BLURSCALEX;
  165. //uniform COMPAT_PRECISION float BLURSCALEY;
  166. uniform COMPAT_PRECISION float LOWLUMSCAN;
  167. uniform COMPAT_PRECISION float HILUMSCAN;
  168. uniform COMPAT_PRECISION float BRIGHTBOOST;
  169. uniform COMPAT_PRECISION float MASK_DARK;
  170. uniform COMPAT_PRECISION float MASK_FADE;
  171. uniform COMPAT_PRECISION float shadowMask;
  172. uniform COMPAT_PRECISION float DOTMASK_STRENGTH;
  173. uniform COMPAT_PRECISION float maskDark;
  174. uniform COMPAT_PRECISION float maskLight;
  175. #else
  176. #define BLURSCALEX 0.45
  177. //#define BLURSCALEY 0.20
  178. #define LOWLUMSCAN 5.0
  179. #define HILUMSCAN 10.0
  180. #define BRIGHTBOOST 1.25
  181. #define MASK_DARK 0.25
  182. #define MASK_FADE 0.8
  183. #define shadowMask 3.0
  184. #define DOTMASK_STRENGTH 0.3
  185. #define maskDark 0.5
  186. #define maskLight 1.5
  187. #endif
  188.  
  189. #define mod_factor vTexCoord.x * SourceSize.x * OutSize.x / SourceSize.x
  190.  
  191. // Shadow mask.
  192. vec3 Mask(vec2 pos)
  193. {
  194. vec3 mask = vec3(maskDark, maskDark, maskDark);
  195.  
  196. // Very compressed TV style shadow mask.
  197. if (shadowMask == 1.0)
  198. {
  199. float line = maskLight;
  200. float odd = 0.0;
  201.  
  202. if (fract(pos.x/6.0) < 0.5)
  203. odd = 1.0;
  204. if (fract((pos.y + odd)/2.0) < 0.5)
  205. line = maskDark;
  206.  
  207. pos.x = fract(pos.x/3.0);
  208.  
  209. if (pos.x < 0.333) mask.r = maskLight;
  210. else if (pos.x < 0.666) mask.g = maskLight;
  211. else mask.b = maskLight;
  212. mask*=line;
  213. }
  214.  
  215. // Aperture-grille.
  216. else if (shadowMask == 2.0)
  217. {
  218. pos.x = fract(pos.x/3.0);
  219.  
  220. if (pos.x < 0.333) mask.r = maskLight;
  221. else if (pos.x < 0.666) mask.g = maskLight;
  222. else mask.b = maskLight;
  223. }
  224.  
  225. // Stretched VGA style shadow mask (same as prior shaders).
  226. else if (shadowMask == 3.0)
  227. {
  228. pos.x += pos.y*3.0;
  229. pos.x = fract(pos.x/6.0);
  230.  
  231. if (pos.x < 0.333) mask.r = maskLight;
  232. else if (pos.x < 0.666) mask.g = maskLight;
  233. else mask.b = maskLight;
  234. }
  235.  
  236. // VGA style shadow mask.
  237. else if (shadowMask == 4.0)
  238. {
  239. pos.xy = floor(pos.xy*vec2(1.0, 0.5));
  240. pos.x += pos.y*3.0;
  241. pos.x = fract(pos.x/6.0);
  242.  
  243. if (pos.x < 0.333) mask.r = maskLight;
  244. else if (pos.x < 0.666) mask.g = maskLight;
  245. else mask.b = maskLight;
  246. }
  247.  
  248. return mask;
  249. }
  250.  
  251. void main()
  252. {
  253.  
  254. //This is just like "Quilez Scaling" but sharper
  255. COMPAT_PRECISION vec2 p = vTexCoord * TextureSize;
  256. COMPAT_PRECISION vec2 i = floor(p) + 0.50;
  257. COMPAT_PRECISION vec2 f = p - i;
  258. p = (i + 4.0*f*f*f)*invDims;
  259. p.x = mix( p.x , vTexCoord.x, BLURSCALEX);
  260. COMPAT_PRECISION float Y = f.y*f.y;
  261. COMPAT_PRECISION float YY = Y*Y;
  262.  
  263. #if defined(FINEMASK)
  264. COMPAT_PRECISION float whichmask = fract( gl_FragCoord.x*-0.4999);
  265. COMPAT_PRECISION float mask = 1.0 + float(whichmask < 0.5) * -MASK_DARK;
  266. #else
  267. COMPAT_PRECISION float whichmask = fract(gl_FragCoord.x * -0.3333);
  268. COMPAT_PRECISION float mask = 1.0 + float(whichmask <= 0.33333) * -MASK_DARK;
  269. #endif
  270. COMPAT_PRECISION vec3 colour = COMPAT_TEXTURE(Source, p).rgb;
  271.  
  272. COMPAT_PRECISION float scanLineWeight = (BRIGHTBOOST - LOWLUMSCAN*(Y - 2.05*YY));
  273. COMPAT_PRECISION float scanLineWeightB = 1.0 - HILUMSCAN*(YY-2.8*YY*Y);
  274.  
  275. #if defined(BLACK_OUT_BORDER)
  276. colour.rgb*=float(tc.x > 0.0)*float(tc.y > 0.0); //why doesn't the driver do the right thing?
  277. #endif
  278.  
  279. FragColor.rgb = colour.rgb*mix(scanLineWeight*mask, scanLineWeightB, dot(colour.rgb,vec3(maskFade)));
  280. FragColor.rgb = pow(FragColor.rgb, vec3(2.2,2.2,2.2));
  281. float dotmask = 1.0 - DOTMASK_STRENGTH;
  282.  
  283. //cgwg's dotmask emulation:
  284. //Output pixels are alternately tinted green and magenta
  285. vec3 dotMaskWeights = mix(vec3(1.0, dotmask, 1.0),
  286. vec3(dotmask, 1.0, dotmask),
  287. floor(mod(mod_factor, 2.0)));
  288. if (shadowMask == 0.)
  289. {
  290. FragColor.rgb *= dotMaskWeights;
  291. }
  292. else
  293. {
  294. FragColor.rgb *= Mask(floor(1.000001 * gl_FragCoord.xy + vec2(0.5,0.5)));
  295. }
  296.  
  297. FragColor.rgb = pow(FragColor.rgb, vec3(1./2.2,1./2.2,1./2.2));
  298.  
  299. }
  300. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement