123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #version 150
-
- in vec4 position;
- in vec2 texCoord;
- in vec4 sourceSize[];
- in vec4 targetSize;
-
- out Vertex {
- vec2 texCoord;
- } vertexOut;
-
- float CRTgamma;
- float monitorgamma;
- vec2 overscan;
- vec2 aspect;
- float d;
- float R;
- float cornersize;
- float cornersmooth;
- vec3 stretch;
- vec2 sinangle;
- vec2 cosangle;
- vec2 one;
- float mod_factor;
- vec2 ilfac;
- #define FIX(c) max(abs(c), 1e-5);
- float intersect(vec2 xy)
- {
- float A = dot(xy,xy)+d*d;
- float B = 2.0*(R*(dot(xy,sinangle)-d*cosangle.x*cosangle.y)-d*d);
- float C = d*d + 2.0*R*d*cosangle.x*cosangle.y;
- return (-B-sqrt(B*B-4.0*A*C))/(2.0*A);
- }
- vec2 bkwtrans(vec2 xy)
- {
- float c = intersect(xy);
- vec2 point = vec2(c)*xy;
- point -= vec2(-R)*sinangle;
- point /= vec2(R);
- vec2 tang = sinangle/cosangle;
- vec2 poc = point/cosangle;
- float A = dot(tang,tang)+1.0;
- float B = -2.0*dot(poc,tang);
- float C = dot(poc,poc)-1.0;
- float a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
- vec2 uv = (point-a*sinangle)/cosangle;
- float r = R*acos(a);
- return uv*r/sin(r/R);
- }
- vec2 fwtrans(vec2 uv)
- {
- float r = FIX(sqrt(dot(uv,uv)));
- uv *= sin(r/R)/r;
- float x = 1.0-cos(r/R);
- float D = d/R + x*cosangle.x*cosangle.y+dot(uv,sinangle);
- return d*(uv*cosangle-x*sinangle)/D;
- }
- vec3 maxscale()
- {
- vec2 c = bkwtrans(-R * sinangle / (1.0 + R/d*cosangle.x*cosangle.y));
- vec2 a = vec2(0.5,0.5)*aspect;
- vec2 lo = vec2(fwtrans(vec2(-a.x,c.y)).x,
- fwtrans(vec2(c.x,-a.y)).y)/aspect;
- vec2 hi = vec2(fwtrans(vec2(+a.x,c.y)).x,
- fwtrans(vec2(c.x,+a.y)).y)/aspect;
- return vec3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));
- }
- void main()
- {
- // START of parameters
- // gamma of simulated CRT
- CRTgamma = 2.4;
- // gamma of display monitor (typically 2.2 is correct)
- monitorgamma = 2.2;
- // overscan (e.g. 1.02 for 2% overscan)
- overscan = vec2(0.99,0.99);
- // aspect ratio
- aspect = vec2(1.0, 0.75);
- // lengths are measured in units of (approximately) the width of the monitor
- // simulated distance from viewer to monitor
- d = 2.0;
- // radius of curvature
- R = 2.0;
- // tilt angle in radians
- // (behavior might be a bit wrong if both components are nonzero)
- const vec2 angle = vec2(0.0,-0.0);
- // size of curved corners
- cornersize = 0.03;
- // border smoothness parameter
- // decrease if borders are too aliased
- cornersmooth = 80.0;
- // END of parameters
-
- vertexOut.texCoord = texCoord.xy;
- gl_Position = position;
- // Precalculate a bunch of useful values we'll need in the fragment
- // shader.
- sinangle = sin(angle);
- cosangle = cos(angle);
- stretch = maxscale();
- ilfac = vec2(1.0,floor(sourceSize[0].y/200.0));
- // The size of one texel, in texture-coordinates.
- one = ilfac / sourceSize[0].xy;
- // Resulting X pixel-coordinate of the pixel we're drawing.
- mod_factor = texCoord.x * targetSize.x;
- }
|