Browse Source

Added FXAA filter to the core thanks to phate666 for its implementation

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7992 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
rem..om 14 years ago
parent
commit
10366623f7

+ 73 - 0
engine/src/core-data/Common/MatDefs/Post/FXAA.frag

@@ -0,0 +1,73 @@
+#extension GL_EXT_gpu_shader4 : enable
+uniform sampler2D m_Texture;
+uniform vec2 g_Resolution;
+varying vec2 texCoord;
+uniform float m_VxOffset;
+uniform float m_SpanMax;
+uniform float m_ReduceMul;
+varying vec4 posPos;
+#define FxaaInt2 ivec2
+#define FxaaFloat2 vec2
+#define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)
+#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
+vec3 FxaaPixelShader(
+  vec4 posPos, // Output of FxaaVertexShader interpolated across screen.
+  sampler2D tex, // Input texture.
+  vec2 rcpFrame) // Constant {1.0/frameWidth, 1.0/frameHeight}.
+{
+/*---------------------------------------------------------*/
+    #define FXAA_REDUCE_MIN   (1.0/128.0)
+    //#define FXAA_REDUCE_MUL   (1.0/8.0)
+    //#define FXAA_SPAN_MAX     8.0
+/*---------------------------------------------------------*/
+    vec3 rgbNW = FxaaTexLod0(tex, posPos.zw).xyz;
+    vec3 rgbNE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,0), rcpFrame.xy).xyz;
+    vec3 rgbSW = FxaaTexOff(tex, posPos.zw, FxaaInt2(0,1), rcpFrame.xy).xyz;
+    vec3 rgbSE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,1), rcpFrame.xy).xyz;
+    vec3 rgbM  = FxaaTexLod0(tex, posPos.xy).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 * m_ReduceMul),
+        FXAA_REDUCE_MIN);
+    float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
+    dir = min(FxaaFloat2( m_SpanMax,  m_SpanMax),
+          max(FxaaFloat2(-m_SpanMax, -m_SpanMax),
+          dir * rcpDirMin)) * rcpFrame.xy;
+/*--------------------------------------------------------*/
+    vec3 rgbA = (1.0/2.0) * (
+        FxaaTexLod0(tex, posPos.xy + dir * (1.0/3.0 - 0.5)).xyz +
+        FxaaTexLod0(tex, posPos.xy + dir * (2.0/3.0 - 0.5)).xyz);
+    vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
+        FxaaTexLod0(tex, posPos.xy + dir * (0.0/3.0 - 0.5)).xyz +
+        FxaaTexLod0(tex, posPos.xy + dir * (3.0/3.0 - 0.5)).xyz);
+    float lumaB = dot(rgbB, luma);
+    if((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;
+    return rgbB; }
+vec4 PostFX(sampler2D tex, vec2 uv, float time)
+{
+    vec4 c = vec4(0.0);
+    vec2 rcpFrame = vec2(1.0/g_Resolution.x, 1.0/g_Resolution.y);
+    c.rgb = FxaaPixelShader(posPos, tex, rcpFrame);
+    //c.rgb = 1.0 - texture2D(tex, posPos.xy).rgb;
+    c.a = 1.0;
+    return c;
+}
+void main()
+{
+    vec2 uv = texCoord.st;
+    gl_FragColor = PostFX(m_Texture, uv, 0.0);
+}

+ 20 - 0
engine/src/core-data/Common/MatDefs/Post/FXAA.j3md

@@ -0,0 +1,20 @@
+MaterialDef FXAA {
+    MaterialParameters {
+        Int NumSamples
+        Texture2D Texture
+        Float SubPixelShif
+        Float VxOffset
+        Float SpanMax
+        Float ReduceMul
+    }
+    Technique {
+        VertexShader GLSL100:   Common/MatDefs/Post/FXAA.vert
+        FragmentShader GLSL120: Common/MatDefs/Post/FXAA.frag
+        WorldParameters {
+            WorldViewProjectionMatrix
+            Resolution
+        }
+    }
+    Technique FixedFunc {
+    }
+}

+ 15 - 0
engine/src/core-data/Common/MatDefs/Post/FXAA.vert

@@ -0,0 +1,15 @@
+uniform mat4 g_WorldViewProjectionMatrix;
+uniform vec2 g_Resolution;
+attribute vec4 inPosition;
+attribute vec2 inTexCoord;
+varying vec2 texCoord;
+uniform float m_SubPixelShif;
+varying vec4 posPos;
+void main() {
+    gl_Position = inPosition * 2.0 - 1.0; //vec4(pos, 0.0, 1.0);
+    texCoord = inTexCoord;
+    vec2 rcpFrame = vec2(1.0/g_Resolution.x, 1.0/g_Resolution.y);
+    posPos.xy = inTexCoord.xy;
+    posPos.zw = inTexCoord.xy -
+                  (rcpFrame * (0.5 + m_SubPixelShif));
+}

+ 95 - 0
engine/src/desktop-fx/com/jme3/post/filters/FXAAFilter.java

@@ -0,0 +1,95 @@
+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;
+    }
+}