crt-geom.vs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #version 150
  2. in vec4 position;
  3. in vec2 texCoord;
  4. in vec4 sourceSize[];
  5. in vec4 targetSize;
  6. out Vertex {
  7. vec2 texCoord;
  8. } vertexOut;
  9. float CRTgamma;
  10. float monitorgamma;
  11. vec2 overscan;
  12. vec2 aspect;
  13. float d;
  14. float R;
  15. float cornersize;
  16. float cornersmooth;
  17. vec3 stretch;
  18. vec2 sinangle;
  19. vec2 cosangle;
  20. vec2 one;
  21. float mod_factor;
  22. vec2 ilfac;
  23. #define FIX(c) max(abs(c), 1e-5);
  24. float intersect(vec2 xy)
  25. {
  26. float A = dot(xy,xy)+d*d;
  27. float B = 2.0*(R*(dot(xy,sinangle)-d*cosangle.x*cosangle.y)-d*d);
  28. float C = d*d + 2.0*R*d*cosangle.x*cosangle.y;
  29. return (-B-sqrt(B*B-4.0*A*C))/(2.0*A);
  30. }
  31. vec2 bkwtrans(vec2 xy)
  32. {
  33. float c = intersect(xy);
  34. vec2 point = vec2(c)*xy;
  35. point -= vec2(-R)*sinangle;
  36. point /= vec2(R);
  37. vec2 tang = sinangle/cosangle;
  38. vec2 poc = point/cosangle;
  39. float A = dot(tang,tang)+1.0;
  40. float B = -2.0*dot(poc,tang);
  41. float C = dot(poc,poc)-1.0;
  42. float a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
  43. vec2 uv = (point-a*sinangle)/cosangle;
  44. float r = R*acos(a);
  45. return uv*r/sin(r/R);
  46. }
  47. vec2 fwtrans(vec2 uv)
  48. {
  49. float r = FIX(sqrt(dot(uv,uv)));
  50. uv *= sin(r/R)/r;
  51. float x = 1.0-cos(r/R);
  52. float D = d/R + x*cosangle.x*cosangle.y+dot(uv,sinangle);
  53. return d*(uv*cosangle-x*sinangle)/D;
  54. }
  55. vec3 maxscale()
  56. {
  57. vec2 c = bkwtrans(-R * sinangle / (1.0 + R/d*cosangle.x*cosangle.y));
  58. vec2 a = vec2(0.5,0.5)*aspect;
  59. vec2 lo = vec2(fwtrans(vec2(-a.x,c.y)).x,
  60. fwtrans(vec2(c.x,-a.y)).y)/aspect;
  61. vec2 hi = vec2(fwtrans(vec2(+a.x,c.y)).x,
  62. fwtrans(vec2(c.x,+a.y)).y)/aspect;
  63. return vec3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));
  64. }
  65. void main()
  66. {
  67. // START of parameters
  68. // gamma of simulated CRT
  69. CRTgamma = 2.4;
  70. // gamma of display monitor (typically 2.2 is correct)
  71. monitorgamma = 2.2;
  72. // overscan (e.g. 1.02 for 2% overscan)
  73. overscan = vec2(0.99,0.99);
  74. // aspect ratio
  75. aspect = vec2(1.0, 0.75);
  76. // lengths are measured in units of (approximately) the width of the monitor
  77. // simulated distance from viewer to monitor
  78. d = 2.0;
  79. // radius of curvature
  80. R = 2.0;
  81. // tilt angle in radians
  82. // (behavior might be a bit wrong if both components are nonzero)
  83. const vec2 angle = vec2(0.0,-0.0);
  84. // size of curved corners
  85. cornersize = 0.03;
  86. // border smoothness parameter
  87. // decrease if borders are too aliased
  88. cornersmooth = 80.0;
  89. // END of parameters
  90. vertexOut.texCoord = texCoord.xy;
  91. gl_Position = position;
  92. // Precalculate a bunch of useful values we'll need in the fragment
  93. // shader.
  94. sinangle = sin(angle);
  95. cosangle = cos(angle);
  96. stretch = maxscale();
  97. ilfac = vec2(1.0,floor(sourceSize[0].y/200.0));
  98. // The size of one texel, in texture-coordinates.
  99. one = ilfac / sourceSize[0].xy;
  100. // Resulting X pixel-coordinate of the pixel we're drawing.
  101. mod_factor = texCoord.x * targetSize.x;
  102. }