fxaa.frag 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // FXAA shader, GLSL code adapted from:
  2. // http://horde3d.org/wiki/index.php5?title=Shading_Technique_-_FXAA
  3. // Whitepaper describing the technique:
  4. // http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf
  5. uniform sampler2D textureSampler;
  6. // The inverse of the texture dimensions along X and Y
  7. vec3 rgb2hsv(vec3 c)
  8. {
  9. vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
  10. vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
  11. vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
  12. float d = q.x - min(q.w, q.y);
  13. float e = 1.0e-10;
  14. return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
  15. }
  16. vec3 hsv2rgb(vec3 c)
  17. {
  18. vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
  19. vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
  20. return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
  21. }
  22. void main() {
  23. // The parameters are hardcoded for now, but could be
  24. // made into uniforms to control fromt he program.
  25. float FXAA_SPAN_MAX = 8.0;
  26. float FXAA_REDUCE_MUL = 1.0/8.0;
  27. float FXAA_REDUCE_MIN = (1.0/128.0);
  28. vec2 texcoordOffset = vec2(0.0005, 0.0005);
  29. vec3 rgbNW = texture2D(textureSampler, gl_TexCoord[0].st + (vec2(-1.0, -1.0) * texcoordOffset)).xyz;
  30. vec3 rgbNE = texture2D(textureSampler, gl_TexCoord[0].st + (vec2(+1.0, -1.0) * texcoordOffset)).xyz;
  31. vec3 rgbSW = texture2D(textureSampler, gl_TexCoord[0].st + (vec2(-1.0, +1.0) * texcoordOffset)).xyz;
  32. vec3 rgbSE = texture2D(textureSampler, gl_TexCoord[0].st + (vec2(+1.0, +1.0) * texcoordOffset)).xyz;
  33. vec3 rgbM = texture2D(textureSampler, gl_TexCoord[0].st).xyz;
  34. vec3 luma = vec3(0.299, 0.587, 0.114);
  35. float lumaNW = dot(rgbNW, luma);
  36. float lumaNE = dot(rgbNE, luma);
  37. float lumaSW = dot(rgbSW, luma);
  38. float lumaSE = dot(rgbSE, luma);
  39. float lumaM = dot( rgbM, luma);
  40. float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
  41. float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
  42. vec2 dir;
  43. dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
  44. dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
  45. float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
  46. float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
  47. dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
  48. max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * texcoordOffset;
  49. vec3 rgbA = (1.0/2.0) * (
  50. texture2D(textureSampler, gl_TexCoord[0].st + dir * (1.0/3.0 - 0.5)).xyz +
  51. texture2D(textureSampler, gl_TexCoord[0].st + dir * (2.0/3.0 - 0.5)).xyz);
  52. vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
  53. texture2D(textureSampler, gl_TexCoord[0].st + dir * (0.0/3.0 - 0.5)).xyz +
  54. texture2D(textureSampler, gl_TexCoord[0].st + dir * (3.0/3.0 - 0.5)).xyz);
  55. float lumaB = dot(rgbB, luma);
  56. if((lumaB < lumaMin) || (lumaB > lumaMax)){
  57. gl_FragColor.xyz=rgbA;
  58. } else {
  59. gl_FragColor.xyz=rgbB;
  60. }
  61. vec3 hsv = rgb2hsv(gl_FragColor.xyz);
  62. hsv.y += 0.1 * (1.0 - hsv.y);
  63. gl_FragColor = vec4(hsv2rgb(hsv), texture2D(textureSampler, gl_TexCoord[0].st).a);
  64. }