--- /dev/null
+#extension GL_EXT_gpu_shader4 : enable\r
+uniform sampler2D m_Texture;\r
+uniform vec2 g_Resolution;\r
+varying vec2 texCoord;\r
+uniform float m_VxOffset;\r
+uniform float m_SpanMax;\r
+uniform float m_ReduceMul;\r
+varying vec4 posPos;\r
+#define FxaaInt2 ivec2\r
+#define FxaaFloat2 vec2\r
+#define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)\r
+#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)\r
+vec3 FxaaPixelShader(\r
+ vec4 posPos, // Output of FxaaVertexShader interpolated across screen.\r
+ sampler2D tex, // Input texture.\r
+ vec2 rcpFrame) // Constant {1.0/frameWidth, 1.0/frameHeight}.\r
+{\r
+/*---------------------------------------------------------*/\r
+ #define FXAA_REDUCE_MIN (1.0/128.0)\r
+ //#define FXAA_REDUCE_MUL (1.0/8.0)\r
+ //#define FXAA_SPAN_MAX 8.0\r
+/*---------------------------------------------------------*/\r
+ vec3 rgbNW = FxaaTexLod0(tex, posPos.zw).xyz;\r
+ vec3 rgbNE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,0), rcpFrame.xy).xyz;\r
+ vec3 rgbSW = FxaaTexOff(tex, posPos.zw, FxaaInt2(0,1), rcpFrame.xy).xyz;\r
+ vec3 rgbSE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,1), rcpFrame.xy).xyz;\r
+ vec3 rgbM = FxaaTexLod0(tex, posPos.xy).xyz;\r
+/*---------------------------------------------------------*/\r
+ vec3 luma = vec3(0.299, 0.587, 0.114);\r
+ float lumaNW = dot(rgbNW, luma);\r
+ float lumaNE = dot(rgbNE, luma);\r
+ float lumaSW = dot(rgbSW, luma);\r
+ float lumaSE = dot(rgbSE, luma);\r
+ float lumaM = dot(rgbM, luma);\r
+/*---------------------------------------------------------*/\r
+ float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\r
+ float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\r
+/*---------------------------------------------------------*/\r
+ vec2 dir;\r
+ dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\r
+ dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\r
+/*---------------------------------------------------------*/\r
+ float dirReduce = max(\r
+ (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * m_ReduceMul),\r
+ FXAA_REDUCE_MIN);\r
+ float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);\r
+ dir = min(FxaaFloat2( m_SpanMax, m_SpanMax),\r
+ max(FxaaFloat2(-m_SpanMax, -m_SpanMax),\r
+ dir * rcpDirMin)) * rcpFrame.xy;\r
+/*--------------------------------------------------------*/\r
+ vec3 rgbA = (1.0/2.0) * (\r
+ FxaaTexLod0(tex, posPos.xy + dir * (1.0/3.0 - 0.5)).xyz +\r
+ FxaaTexLod0(tex, posPos.xy + dir * (2.0/3.0 - 0.5)).xyz);\r
+ vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (\r
+ FxaaTexLod0(tex, posPos.xy + dir * (0.0/3.0 - 0.5)).xyz +\r
+ FxaaTexLod0(tex, posPos.xy + dir * (3.0/3.0 - 0.5)).xyz);\r
+ float lumaB = dot(rgbB, luma);\r
+ if((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;\r
+ return rgbB; }\r
+vec4 PostFX(sampler2D tex, vec2 uv, float time)\r
+{\r
+ vec4 c = vec4(0.0);\r
+ vec2 rcpFrame = vec2(1.0/g_Resolution.x, 1.0/g_Resolution.y);\r
+ c.rgb = FxaaPixelShader(posPos, tex, rcpFrame);\r
+ //c.rgb = 1.0 - texture2D(tex, posPos.xy).rgb;\r
+ c.a = 1.0;\r
+ return c;\r
+}\r
+void main()\r
+{\r
+ vec2 uv = texCoord.st;\r
+ gl_FragColor = PostFX(m_Texture, uv, 0.0);\r
+}
\ No newline at end of file
--- /dev/null
+package com.jme3.post.filters;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.material.Material;
+import com.jme3.post.Filter;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+
+/**
+ * <a href="http://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-opengl-test-radeon-geforce/3/" rel="nofollow">http://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-<span class="domtooltips" title="OpenGL (Open Graphics Library) is a standard specification defining a cross-language, cross-platform API for writing applications that produce 2D and 3D computer graphics." id="domtooltipsspan11">opengl</span>-test-radeon-geforce/3/</a>
+ * <a href="http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf" rel="nofollow">http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf</a>
+ *
+ * @author Phate666 (adapted to jme3)
+ *
+ */
+public class FXAAFilter extends Filter {
+
+ private float subPixelShif = 1.0f / 4.0f;
+ private float vxOffset = 0.0f;
+ private float spanMax = 8.0f;
+ private float reduceMul = 1.0f / 8.0f;
+
+ public FXAAFilter() {
+ super("FXAAFilter");
+ }
+
+ @Override
+ protected void initFilter(AssetManager manager,
+ RenderManager renderManager, ViewPort vp, int w, int h) {
+ material = new Material(manager, "Common/MatDefs/Post/FXAA.j3md");
+ material.setFloat("SubPixelShif", subPixelShif);
+ material.setFloat("VxOffset", vxOffset);
+ material.setFloat("SpanMax", spanMax);
+ material.setFloat("ReduceMul", reduceMul);
+ }
+
+ @Override
+ protected Material getMaterial() {
+ return material;
+ }
+
+ public void setSpanMax(float spanMax) {
+ this.spanMax = spanMax;
+ if (material != null) {
+ material.setFloat("SpanMax", this.spanMax);
+ }
+ }
+
+ /**
+ * set to 0.0f for higher quality
+ *
+ * @param subPixelShift
+ */
+ public void setSubPixelShift(float subPixelShift) {
+ subPixelShif = subPixelShift;
+ if (material != null) {
+ material.setFloat("SubPixelShif", subPixelShif);
+ }
+ }
+
+ /**
+ * set to 0.0f for higher quality
+ *
+ * @param reduceMul
+ */
+ public void setReduceMul(float reduceMul) {
+ this.reduceMul = reduceMul;
+ if (material != null) {
+ material.setFloat("ReduceMul", this.reduceMul);
+ }
+ }
+
+ public void setVxOffset(float vxOffset) {
+ this.vxOffset = vxOffset;
+ if (material != null) {
+ material.setFloat("VxOffset", this.vxOffset);
+ }
+ }
+
+ public float getReduceMul() {
+ return reduceMul;
+ }
+
+ public float getSpanMax() {
+ return spanMax;
+ }
+
+ public float getSubPixelShif() {
+ return subPixelShif;
+ }
+
+ public float getVxOffset() {
+ return vxOffset;
+ }
+}
\ No newline at end of file