Advertisement
EasyMode

crt-easymode.cg

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