Guest User

crt-easymode for review

a guest
Jul 1st, 2024
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.60 KB | None | 0 0
  1. #version 450
  2.  
  3. layout(push_constant) uniform Push
  4. {
  5. float BRIGHT_BOOST;
  6. float BRIGHT_BOOST_CUTOFF;
  7. float DILATION;
  8. float GAMMA_INPUT;
  9. float GAMMA_OUTPUT;
  10. float MASK_SIZE;
  11. float MASK_STAGGER;
  12. float MASK_STRENGTH;
  13. float MASK_DOT_HEIGHT;
  14. float MASK_DOT_WIDTH;
  15. float SCANLINE_CUTOFF;
  16. float SCANLINE_BEAM_WIDTH_MAX;
  17. float SCANLINE_BEAM_WIDTH_MIN;
  18. float SCANLINE_BRIGHT_MAX;
  19. float SCANLINE_BRIGHT_MIN;
  20. float SCANLINE_STRENGTH;
  21. float SHARPNESS_H;
  22. float SHARPNESS_V;
  23. } params;
  24.  
  25. #pragma parameter SHARPNESS_H "Sharpness Horizontal" 0.5 0.0 1.0 0.05
  26. #pragma parameter SHARPNESS_V "Sharpness Vertical" 1.0 0.0 1.0 0.05
  27. #pragma parameter MASK_STRENGTH "Mask Strength" 0.3 0.0 1.0 0.01
  28. #pragma parameter MASK_DOT_WIDTH "Mask Dot Width" 1.0 1.0 100.0 1.0
  29. #pragma parameter MASK_DOT_HEIGHT "Mask Dot Height" 1.0 1.0 100.0 1.0
  30. #pragma parameter MASK_STAGGER "Mask Stagger" 0.0 0.0 100.0 1.0
  31. #pragma parameter MASK_SIZE "Mask Size" 1.0 1.0 100.0 1.0
  32. #pragma parameter SCANLINE_STRENGTH "Scanline Strength" 1.0 0.0 1.0 0.05
  33. #pragma parameter SCANLINE_BEAM_WIDTH_MIN "Scanline Beam Width Min." 1.5 0.5 5.0 0.5
  34. #pragma parameter SCANLINE_BEAM_WIDTH_MAX "Scanline Beam Width Max." 1.5 0.5 5.0 0.5
  35. #pragma parameter SCANLINE_BRIGHT_MIN "Scanline Brightness Min." 0.35 0.0 1.0 0.05
  36. #pragma parameter SCANLINE_BRIGHT_MAX "Scanline Brightness Max." 0.65 0.0 1.0 0.05
  37. #pragma parameter SCANLINE_CUTOFF "Scanline Cutoff" 400.0 1.0 1000.0 1.0
  38. #pragma parameter GAMMA_INPUT "Gamma Input" 2.0 0.1 5.0 0.1
  39. #pragma parameter GAMMA_OUTPUT "Gamma Output" 1.8 0.1 5.0 0.1
  40. #pragma parameter BRIGHT_BOOST "Brightness Boost" 1.2 1.0 2.0 0.01
  41. #pragma parameter BRIGHT_BOOST_CUTOFF "Brightness Boost Cutoff" 1.1 1.0 2.0 0.01
  42. #pragma parameter DILATION "Dilation" 1.0 0.0 1.0 1.0
  43.  
  44. layout(std140, set = 0, binding = 0) uniform UBO
  45. {
  46. mat4 MVP;
  47. vec4 OutputSize;
  48. vec4 OriginalSize;
  49. vec4 SourceSize;
  50. } global;
  51.  
  52. #pragma stage vertex
  53. layout(location = 0) in vec4 Position;
  54. layout(location = 1) in vec2 TexCoord;
  55. layout(location = 0) out vec2 vTexCoord;
  56.  
  57. void main()
  58. {
  59. gl_Position = global.MVP * Position;
  60. vTexCoord = TexCoord;
  61. }
  62.  
  63. /*
  64. CRT Shader by EasyMode
  65. License: GPL
  66.  
  67. A flat CRT shader ideally for 1080p or higher displays.
  68.  
  69. Recommended Settings:
  70.  
  71. Video
  72. - Aspect Ratio: 4:3
  73. - Integer Scale: Off
  74.  
  75. Shader
  76. - Filter: Nearest
  77. - Scale: Don't Care
  78.  
  79. Example RGB Mask Parameter Settings:
  80.  
  81. Aperture Grille (Default)
  82. - Dot Width: 1
  83. - Dot Height: 1
  84. - Stagger: 0
  85.  
  86. Lottes' Shadow Mask
  87. - Dot Width: 2
  88. - Dot Height: 1
  89. - Stagger: 3
  90. */
  91.  
  92. #pragma stage fragment
  93. layout(location = 0) in vec2 vTexCoord;
  94. layout(location = 0) out vec4 FragColor;
  95. layout(set = 0, binding = 2) uniform sampler2D Source;
  96.  
  97. #define FIX(c) max(abs(c), 1e-5)
  98. #define PI 3.141592653589
  99.  
  100. #define TEX2D(c) dilate(texture(Source, c))
  101.  
  102. // Set to 0 to use linear filter and gain speed
  103. #define ENABLE_LANCZOS 1
  104.  
  105. vec4 dilate(vec4 col)
  106. {
  107. vec4 x = mix(vec4(1.0), col, params.DILATION);
  108.  
  109. return col * x;
  110. }
  111.  
  112. float curve_distance(float x, float sharp)
  113. {
  114.  
  115. /*
  116. apply half-circle s-curve to distance for sharper (more pixelated) interpolation
  117. single line formula for Graph Toy:
  118. 0.5 - sqrt(0.25 - (x - step(0.5, x)) * (x - step(0.5, x))) * sign(0.5 - x)
  119. */
  120.  
  121. float x_step = step(0.5, x);
  122. float curve = 0.5 - sqrt(0.25 - (x - x_step) * (x - x_step)) * sign(0.5 - x);
  123.  
  124. return mix(x, curve, sharp);
  125. }
  126.  
  127. mat4x4 get_color_matrix(vec2 co, vec2 dx)
  128. {
  129. return mat4x4(TEX2D(co - dx), TEX2D(co), TEX2D(co + dx), TEX2D(co + 2.0 * dx));
  130. }
  131.  
  132. vec3 filter_lanczos(vec4 coeffs, mat4x4 color_matrix)
  133. {
  134. vec4 col = color_matrix * coeffs;
  135. vec4 sample_min = min(color_matrix[1], color_matrix[2]);
  136. vec4 sample_max = max(color_matrix[1], color_matrix[2]);
  137.  
  138. col = clamp(col, sample_min, sample_max);
  139.  
  140. return col.rgb;
  141. }
  142.  
  143. /* main_fragment */
  144. void main()
  145. {
  146. vec2 dx = vec2(global.SourceSize.z, 0.0);
  147. vec2 dy = vec2(0.0, global.SourceSize.w);
  148. vec2 pix_co = vTexCoord * global.SourceSize.xy - vec2(0.5, 0.5);
  149. vec2 tex_co = (floor(pix_co) + vec2(0.5, 0.5)) * global.SourceSize.zw;
  150. vec2 dist = fract(pix_co);
  151. float curve_x;
  152. vec3 col, col2;
  153.  
  154. #if ENABLE_LANCZOS
  155. curve_x = curve_distance(dist.x, params.SHARPNESS_H * params.SHARPNESS_H);
  156.  
  157. vec4 coeffs = PI * vec4(1.0 + curve_x, curve_x, 1.0 - curve_x, 2.0 - curve_x);
  158.  
  159. coeffs = FIX(coeffs);
  160. coeffs = 2.0 * sin(coeffs) * sin(coeffs * 0.5) / (coeffs * coeffs);
  161. coeffs /= dot(coeffs, vec4(1.0));
  162.  
  163. col = filter_lanczos(coeffs, get_color_matrix(tex_co, dx));
  164. col2 = filter_lanczos(coeffs, get_color_matrix(tex_co + dy, dx));
  165. #else
  166. curve_x = curve_distance(dist.x, params.SHARPNESS_H);
  167.  
  168. col = mix(TEX2D(tex_co).rgb, TEX2D(tex_co + dx).rgb, curve_x);
  169. col2 = mix(TEX2D(tex_co + dy).rgb, TEX2D(tex_co + dx + dy).rgb, curve_x);
  170. #endif
  171.  
  172. col = mix(col, col2, curve_distance(dist.y, params.SHARPNESS_V));
  173. col = pow(col, vec3(params.GAMMA_INPUT / (params.DILATION + 1.0)));
  174.  
  175. float luma = dot(vec3(0.2126, 0.7152, 0.0722), col);
  176. float bright = (max(col.r, max(col.g, col.b)) + luma) * 0.5;
  177. float scan_bright = clamp(bright, params.SCANLINE_BRIGHT_MIN, params.SCANLINE_BRIGHT_MAX);
  178. float scan_beam = clamp(bright * params.SCANLINE_BEAM_WIDTH_MAX, params.SCANLINE_BEAM_WIDTH_MIN, params.SCANLINE_BEAM_WIDTH_MAX);
  179. float scan_weight = 1.0 - pow(cos(vTexCoord.y * 2.0 * PI * global.SourceSize.y) * 0.5 + 0.5, scan_beam) * params.SCANLINE_STRENGTH;
  180.  
  181. float mask = 1.0 - params.MASK_STRENGTH;
  182. vec2 mod_fac = floor(vTexCoord * global.OutputSize.xy * global.SourceSize.xy / (global.SourceSize.xy * vec2(params.MASK_SIZE, params.MASK_DOT_HEIGHT * params.MASK_SIZE)));
  183. int dot_no = int(mod((mod_fac.x + mod(mod_fac.y, 2.0) * params.MASK_STAGGER) / params.MASK_DOT_WIDTH, 3.0));
  184. vec3 mask_weight;
  185.  
  186. if (dot_no == 0) mask_weight = vec3(1.0, mask, mask);
  187. else if (dot_no == 1) mask_weight = vec3(mask, 1.0, mask);
  188. else mask_weight = vec3(mask, mask, 1.0);
  189.  
  190. float actual_boost = params.BRIGHT_BOOST;
  191. if (global.SourceSize.y >= params.SCANLINE_CUTOFF)
  192. scan_weight = 1.0, actual_boost = params.BRIGHT_BOOST_CUTOFF;
  193.  
  194. col2 = col.rgb;
  195. col *= vec3(scan_weight);
  196. col = mix(col, col2, scan_bright);
  197. col *= mask_weight;
  198. col = pow(col, vec3(1.0 / params.GAMMA_OUTPUT));
  199.  
  200. FragColor = vec4(col * actual_boost, 1.0);
  201. }
Advertisement
Add Comment
Please, Sign In to add comment