OSDN Git Service

Added FXAA filter to the core thanks to phate666 for its implementation
authorremy.bouquet@gmail.com <remy.bouquet@gmail.com@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Tue, 9 Aug 2011 15:37:58 +0000 (15:37 +0000)
committerremy.bouquet@gmail.com <remy.bouquet@gmail.com@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Tue, 9 Aug 2011 15:37:58 +0000 (15:37 +0000)
git-svn-id: http://jmonkeyengine.googlecode.com/svn/trunk@7992 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

engine/src/core-data/Common/MatDefs/Post/FXAA.frag [new file with mode: 0644]
engine/src/core-data/Common/MatDefs/Post/FXAA.j3md [new file with mode: 0644]
engine/src/core-data/Common/MatDefs/Post/FXAA.vert [new file with mode: 0644]
engine/src/desktop-fx/com/jme3/post/filters/FXAAFilter.java [new file with mode: 0644]

diff --git a/engine/src/core-data/Common/MatDefs/Post/FXAA.frag b/engine/src/core-data/Common/MatDefs/Post/FXAA.frag
new file mode 100644 (file)
index 0000000..679e9d2
--- /dev/null
@@ -0,0 +1,73 @@
+#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
diff --git a/engine/src/core-data/Common/MatDefs/Post/FXAA.j3md b/engine/src/core-data/Common/MatDefs/Post/FXAA.j3md
new file mode 100644 (file)
index 0000000..88401f5
--- /dev/null
@@ -0,0 +1,20 @@
+MaterialDef FXAA {\r
+    MaterialParameters {\r
+        Int NumSamples\r
+        Texture2D Texture\r
+        Float SubPixelShif\r
+        Float VxOffset\r
+        Float SpanMax\r
+        Float ReduceMul\r
+    }\r
+    Technique {\r
+        VertexShader GLSL100:   Common/MatDefs/Post/FXAA.vert\r
+        FragmentShader GLSL120: Common/MatDefs/Post/FXAA.frag\r
+        WorldParameters {\r
+            WorldViewProjectionMatrix\r
+            Resolution\r
+        }\r
+    }\r
+    Technique FixedFunc {\r
+    }\r
+}
\ No newline at end of file
diff --git a/engine/src/core-data/Common/MatDefs/Post/FXAA.vert b/engine/src/core-data/Common/MatDefs/Post/FXAA.vert
new file mode 100644 (file)
index 0000000..6594926
--- /dev/null
@@ -0,0 +1,15 @@
+uniform mat4 g_WorldViewProjectionMatrix;\r
+uniform vec2 g_Resolution;\r
+attribute vec4 inPosition;\r
+attribute vec2 inTexCoord;\r
+varying vec2 texCoord;\r
+uniform float m_SubPixelShif;\r
+varying vec4 posPos;\r
+void main() {\r
+    gl_Position = inPosition * 2.0 - 1.0; //vec4(pos, 0.0, 1.0);\r
+    texCoord = inTexCoord;\r
+    vec2 rcpFrame = vec2(1.0/g_Resolution.x, 1.0/g_Resolution.y);\r
+    posPos.xy = inTexCoord.xy;\r
+    posPos.zw = inTexCoord.xy -\r
+                  (rcpFrame * (0.5 + m_SubPixelShif));\r
+}
\ No newline at end of file
diff --git a/engine/src/desktop-fx/com/jme3/post/filters/FXAAFilter.java b/engine/src/desktop-fx/com/jme3/post/filters/FXAAFilter.java
new file mode 100644 (file)
index 0000000..27de145
--- /dev/null
@@ -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;
+    }
+}
\ No newline at end of file