Hello! I'm pleased to announce the first ever FXAA method for GM:S. It takes almost no performance to use, and it only requires that you use it in fullscreen. There are variables in the pixel changer to change the resolution, but ATM it's hardcoded for 720P. At the moment, my copy of GM:S is having trouble taking screenshots, so if anyone could UL some I'd greatly appriciate it! Here are the shaders:

Vertex Shader

varying mat4 projMat; varying vec2 texCoords; varying vec3 vertPos; attribute vec3 in_Position; // (x,y,z) attribute vec4 in_Colour; // (r,g,b,a) attribute vec2 in_TextureCoord; // (u,v) //attribute vec3 in_Normal; // (x,y,z) unused in this shader. varying vec2 v_vTexcoord; varying vec4 v_vColour; void main() { vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; projMat = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION]; v_vColour = in_Colour; v_vTexcoord = in_TextureCoord; texCoords = v_vTexcoord; vertPos=in_Position; }

Frag Shader:

//uniform vec2 frameBufSize = 16/9; varying vec2 texCoords; void main( void ) { vec2 frameBufSize = vec2(1280,720); float alpha = texture2D(gm_BaseTexture,texCoords).w; float FXAA_SPAN_MAX = 8.0; float FXAA_REDUCE_MUL = 1.0/8.0; float FXAA_REDUCE_MIN = 1.0/128.0; vec3 rgbNW=texture2D(gm_BaseTexture,texCoords+(vec2(-1.0,-1.0)/frameBufSize)).xyz; vec3 rgbNE=texture2D(gm_BaseTexture,texCoords+(vec2(1.0,-1.0)/frameBufSize)).xyz; vec3 rgbSW=texture2D(gm_BaseTexture,texCoords+(vec2(-1.0,1.0)/frameBufSize)).xyz; vec3 rgbSE=texture2D(gm_BaseTexture,texCoords+(vec2(1.0,1.0)/frameBufSize)).xyz; vec3 rgbM=texture2D(gm_BaseTexture,texCoords).xyz; vec3 luma=vec3(0.299, 0.587, 0.114); float lumaNW = dot(rgbNW, luma); float lumaNE = dot(rgbNE, luma); float lumaSW = dot(rgbSW, luma); float lumaSE = dot(rgbSE, luma); float lumaM = dot(rgbM, luma); float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); vec2 dir; dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); float dirReduce = max( (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce); dir = min(vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) / frameBufSize; vec3 rgbA = (1.0/2.0) * ( texture2D(gm_BaseTexture, texCoords.xy + dir * (1.0/3.0 - 0.5)).xyz + texture2D(gm_BaseTexture, texCoords.xy + dir * (2.0/3.0 - 0.5)).xyz); vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * ( texture2D(gm_BaseTexture, texCoords.xy + dir * (0.0/3.0 - 0.5)).xyz + texture2D(gm_BaseTexture, texCoords.xy + dir * (3.0/3.0 - 0.5)).xyz); float lumaB = dot(rgbB, luma); if((lumaB < lumaMin) || (lumaB > lumaMax)){ gl_FragColor.xyzw=vec4(rgbA.x,rgbA.y,rgbA.z,alpha); }else{ gl_FragColor.xyzw=vec4(rgbB.x,rgbB.y,rgbB.z,alpha); } }