Advertisement
Guest User

CRT-Geom-Flat.cg

a guest
Sep 7th, 2013
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.53 KB | None | 0 0
  1. /* COMPATIBILITY
  2. - HLSL compilers
  3. - Cg compilers
  4. */
  5.  
  6. // This is a good place for any #defines you might have
  7. #define FIX(c) max(abs(c), 1e-5);
  8.  
  9. // Comment the next line to disable interpolation in linear gamma (and gain speed).
  10. #define LINEAR_PROCESSING
  11.  
  12. // Enable 3x oversampling of the beam profile
  13. #define OVERSAMPLE
  14.  
  15. // Use the older, purely gaussian beam profile
  16. //#define USEGAUSSIAN
  17.  
  18. // Use interlacing detection; may interfere with other shaders if combined
  19. #define INTERLACED
  20.  
  21. #define SHARPER
  22.  
  23. // Macros.
  24. #define FIX(c) max(abs(c), 1e-5);
  25. #define PI 3.141592653589
  26.  
  27. #ifdef LINEAR_PROCESSING
  28. # define TEX2D(c) pow(tex2D(IN.texture, (c)), float4(CRTgamma))
  29. #else
  30. # define TEX2D(c) tex2D(IN.texture, (c))
  31. #endif
  32.  
  33. // gamma of simulated CRT
  34. #define CRTgamma 2.4
  35.  
  36. // gamma of display monitor (typically 2.2 is correct)
  37. #define monitorgamma 2.2
  38.  
  39. struct input // These are things that can attach to 'IN' to achieve similar function to ruby* stuff in existing GLSL shaders. NOTE: the ruby* prefix is deprecated but still works in GLSL for legacy compatibility purposes.
  40. {
  41. float2 video_size;
  42. float2 texCoord_size;
  43. float2 output_size;
  44. float frame_count;
  45. float frame_direction;
  46. float frame_rotation;
  47. float texture_size;
  48. sampler2D texture : TEXUNIT0;
  49. };
  50.  
  51. struct tex_coords
  52. {
  53. float2 texCoord : TEXCOORD0;
  54. float2 one : TEXCOORD2;
  55. };
  56.  
  57. // VERTEX SHADER //
  58.  
  59. void main_vertex
  60. (
  61. float4 position : POSITION,
  62. out float4 oPosition : POSITION,
  63. uniform float4x4 modelViewProj,
  64.  
  65. float4 color : COLOR,
  66. out float4 oColor : COLOR,
  67.  
  68. float2 tex : TEXCOORD,
  69.  
  70. uniform input IN,
  71. out tex_coords coords
  72. )
  73. {
  74. oPosition = mul(modelViewProj, position);
  75. oColor = color;
  76.  
  77. #ifdef SHARPER
  78. float2 TextureSize = float2(2.0*IN.texture_size.x, IN.texture_size.y);
  79. #else
  80. float2 TextureSize = IN.texture_size;
  81. #endif
  82.  
  83. coords.texCoord = tex + float2(0.0, 0.0);
  84. coords.one = 1.0 / TextureSize;
  85. }
  86.  
  87.  
  88.  
  89. // Calculate the influence of a scanline on the current pixel.
  90. //
  91. // 'distance' is the distance in texture coordinates from the current
  92. // pixel to the scanline in question.
  93. // 'color' is the colour of the scanline at the horizontal location of
  94. // the current pixel.
  95. float4 scanlineWeights(float distance, float4 color)
  96. {
  97. // "wid" controls the width of the scanline beam, for each RGB channel
  98. // The "weights" lines basically specify the formula that gives
  99. // you the profile of the beam, i.e. the intensity as
  100. // a function of distance from the vertical center of the
  101. // scanline. In this case, it is gaussian if width=2, and
  102. // becomes nongaussian for larger widths. Ideally this should
  103. // be normalized so that the integral across the beam is
  104. // independent of its width. That is, for a narrower beam
  105. // "weights" should have a higher peak at the center of the
  106. // scanline than for a wider beam.
  107. #ifdef USEGAUSSIAN
  108. float4 wid = 0.3 + 0.1 * pow(color, float4(3.0));
  109. float4 weights = float4(distance / wid);
  110. return 0.4 * exp(-weights * weights) / wid;
  111. #else
  112. float4 wid = 2.0 + 2.0 * pow(color, float4(4.0));
  113. float4 weights = float4(distance / 0.4);
  114. return 1.4 * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid);
  115. #endif
  116. }
  117.  
  118. // FRAGMENT SHADER //
  119.  
  120. float4 main_fragment(in tex_coords co, uniform input IN, uniform sampler2D s_p : TEXUNIT0) : COLOR
  121. {
  122. // Paste your fragment code--the part that is inside the GLSL shader's "void main(){ ... }"--here:
  123. // Here's a helpful diagram to keep in mind while trying to
  124. // understand the code:
  125. //
  126. // | | | | |
  127. // -------------------------------
  128. // | | | | |
  129. // | 01 | 11 | 21 | 31 | <-- current scanline
  130. // | | @ | | |
  131. // -------------------------------
  132. // | | | | |
  133. // | 02 | 12 | 22 | 32 | <-- next scanline
  134. // | | | | |
  135. // -------------------------------
  136. // | | | | |
  137. //
  138. // Each character-cell represents a pixel on the output
  139. // surface, "@" represents the current pixel (always somewhere
  140. // in the bottom half of the current scan-line, or the top-half
  141. // of the next scanline). The grid of lines represents the
  142. // edges of the texels of the underlying texture.
  143.  
  144. // Texture coordinates of the texel containing the active pixel.
  145. float2 xy = co.texCoord;
  146.  
  147. float2 ilfac = float2(1.0,floor(IN.video_size.y/200.0));
  148.  
  149. #ifdef SHARPER
  150. float2 TextureSize = float2(2.0*IN.texture_size.x, IN.texture_size.y);
  151. #else
  152. float2 TextureSize = IN.texture_size;
  153. #endif
  154.  
  155. // The size of one texel, in texture-coordinates.
  156. float2 one = ilfac / TextureSize;
  157.  
  158. float2 ilvec = float2(0.0,ilfac.y > 1.5 ? mod(float(IN.frame_count),2.0) : 0.0);
  159.  
  160. // Of all the pixels that are mapped onto the texel we are
  161. // currently rendering, which pixel are we currently rendering?
  162. #ifdef INTERLACED
  163. float2 ratio_scale = (xy * TextureSize - float2(0.5) + ilvec)/ilfac;
  164. #else
  165. float2 ratio_scale = xy * TextureSize - float2(0.5);
  166. #endif
  167.  
  168. #ifdef OVERSAMPLE
  169. float filter = (IN.video_size / (IN.output_size * TextureSize)) *(ratio_scale.y);
  170. #endif
  171. float2 uv_ratio = fract(ratio_scale);
  172.  
  173. // Snap to the center of the underlying texel.
  174. #ifdef INTERLACED
  175. xy = (floor(ratio_scale)*ilfac + float2(0.5) - ilvec) / TextureSize;
  176. #else
  177. xy = (floor(ratio_scale) + float2(0.5)) / TextureSize;
  178. #endif
  179.  
  180. // Calculate Lanczos scaling coefficients describing the effect
  181. // of various neighbour texels in a scanline on the current
  182. // pixel.
  183. float4 coeffs = PI * float4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
  184.  
  185. // Prevent division by zero.
  186. coeffs = FIX(coeffs);
  187.  
  188. // Lanczos2 kernel.
  189. coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
  190.  
  191. // Normalize.
  192. coeffs /= dot(coeffs, float4(1.0));
  193.  
  194. // Calculate the effective colour of the current and next
  195. // scanlines at the horizontal location of the current pixel,
  196. // using the Lanczos coefficients above.
  197. float4 col = clamp(mul(coeffs, float4x4(
  198. TEX2D(xy + float2(-co.one.x, 0.0)),
  199. TEX2D(xy),
  200. TEX2D(xy + float2(co.one.x, 0.0)),
  201. TEX2D(xy + float2(2.0 * co.one.x, 0.0)))),
  202. 0.0, 1.0);
  203. float4 col2 = clamp(mul(coeffs, float4x4(
  204. TEX2D(xy + float2(-co.one.x, co.one.y)),
  205. TEX2D(xy + float2(0.0, co.one.y)),
  206. TEX2D(xy + co.one),
  207. TEX2D(xy + float2(2.0 * co.one.x, co.one.y)))),
  208. 0.0, 1.0);
  209.  
  210. #ifndef LINEAR_PROCESSING
  211. col = pow(col , float4(CRTgamma));
  212. col2 = pow(col2, float4(CRTgamma));
  213. #endif
  214.  
  215. // Calculate the influence of the current and next scanlines on
  216. // the current pixel.
  217. float4 weights = scanlineWeights(uv_ratio.y, col);
  218. float4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2);
  219. #ifdef OVERSAMPLE
  220. uv_ratio.y =uv_ratio.y+1.0/3.0*filter;
  221. weights = (weights+scanlineWeights(uv_ratio.y, col))/3.0;
  222. weights2=(weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2))/3.0;
  223. uv_ratio.y =uv_ratio.y-2.0/3.0*filter;
  224. weights=weights+scanlineWeights(abs(uv_ratio.y), col)/3.0;
  225. weights2=weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2)/3.0;
  226. #endif
  227. float3 mul_res = (col * weights + col2 * weights2).rgb;
  228.  
  229. // Convert the image gamma for display on our output device.
  230. mul_res = pow(mul_res, float3(1.0 / monitorgamma));
  231.  
  232. return float4(mul_res, 1.0);
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement