"FXAA Rules, OK?"

FlaH would like to thank everyone for their hard work on this and the amazing results produced.



However, he is currently trying to find his lower jaw after it bounced off the desk so he is unable to tell you himself.



:stuck_out_tongue:



Cheers!

~FlaH

phate666 said:
As i dont have commit access someone else should do this.



Thank you for your sharing!!!
@nehon , would you like to put this amazing code to JME CORE?
mifth said:
@nehon , would you like to put this amazing code to JME CORE?

Of course I do :D

I think the GammaCorrectionFilter could be useful as a stand alone filter too.
Is it mandatory for using the new FXAA?
If it is, it should be rendered as a pre-pass yes.
I'm gonna look into it
1 Like

I agree that it’d be nice to have it available externally. But if the gamma filter enhance the FXAA filter then I think there should be one embedded into it. AFAIK it’s better if it’s processed as an internal pass.



Of course there’s always the risk of having some people thinking the gamma filter should be added (separately) before turning it on in the FXAA… I know, I know, but it’s possible. I’ve seen worse. :wink:

I LOVE YOU GUYS!

@nehon , any chance to put this cool shader to JME beta?

Its in svn for quite some time now…

WOW!! COOOL!!!

Now everybody can test and use it!

http://code.google.com/p/jmonkeyengine/source/browse/trunk/sdk/jme3-core/src/com/jme3/gde/core/filters/impl/JmeFXAAFilter.java?r=8253



May I ask coredevs about Gamma Correction? I mean what @phate666 did above… Will it stay in JmeFXAAFilter or you make another one?

the thing is i tested the new version but got a big performance hit compared to the old one with a barely noticeable visual effect change, so i did not add it to the core.

But maybe i did something wrong.



Also the gamaCorection Filter could be useful on its own i guess i’ll add it

Possibly you should try the old version to compare fps?



About gamaCorection Filter is coool!!



Just give us feedback about it here when you add it to the core.

Done

2 Likes

I tried FXAA today and got a long error which i dont understand. (Using nightly build 11 11 2011)



Nov 11, 2011 12:54:05 PM com.jme3.system.JmeSystem initialize

INFO: Running on jMonkeyEngine 3.0.0 Beta

Nov 11, 2011 12:54:05 PM com.jme3.system.Natives extractNativeLibs

INFO: Extraction Directory: /home/ace/workspace/test collision

Nov 11, 2011 12:54:05 PM com.jme3.system.lwjgl.LwjglAbstractDisplay run

INFO: Using LWJGL 2.8.1

Nov 11, 2011 12:54:05 PM com.jme3.system.lwjgl.LwjglDisplay createContext

INFO: Selected display mode: 640 x 480 x 0 @0Hz

Nov 11, 2011 12:54:06 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo

INFO: Adapter: null

Nov 11, 2011 12:54:06 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo

INFO: Driver Version: null

Nov 11, 2011 12:54:06 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo

INFO: Vendor: Tungsten Graphics, Inc

Nov 11, 2011 12:54:06 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo

INFO: OpenGL Version: 2.1 Mesa 7.10.3

Nov 11, 2011 12:54:06 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo

INFO: Renderer: Mesa DRI Mobile Intel® GM45 Express Chipset x86/MMX/SSE2

Nov 11, 2011 12:54:06 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo

INFO: GLSL Ver: 1.20

Nov 11, 2011 12:54:06 PM com.jme3.system.lwjgl.LwjglTimer

INFO: Timer resolution: 1,000 ticks per second

Nov 11, 2011 12:54:06 PM com.jme3.renderer.lwjgl.LwjglRenderer initialize

INFO: Caps: [FrameBuffer, FrameBufferMRT, FrameBufferMultisample, OpenGL20, OpenGL21, ARBprogram, GLSL100, GLSL110, GLSL120, NonPowerOfTwoTextures, VertexBufferArray]

Nov 11, 2011 12:54:06 PM com.jme3.asset.DesktopAssetManager

INFO: DesktopAssetManager created.

Nov 11, 2011 12:54:07 PM com.jme3.renderer.Camera

INFO: Camera created (W: 640, H: 480)

Nov 11, 2011 12:54:07 PM com.jme3.renderer.Camera

INFO: Camera created (W: 640, H: 480)

Nov 11, 2011 12:54:07 PM com.jme3.input.lwjgl.LwjglMouseInput initialize

INFO: Mouse created.

Nov 11, 2011 12:54:07 PM com.jme3.input.lwjgl.LwjglKeyInput initialize

INFO: Keyboard created.

Nov 11, 2011 12:54:07 PM com.jme3.audio.lwjgl.LwjglAudioRenderer initInThread

INFO: AudioRenderer supports 64 channels

Nov 11, 2011 12:54:07 PM com.jme3.audio.lwjgl.LwjglAudioRenderer initInThread

INFO: Audio effect extension version: 1.0

Nov 11, 2011 12:54:07 PM com.jme3.audio.lwjgl.LwjglAudioRenderer initInThread

INFO: Audio max auxilary sends: 4

Nov 11, 2011 12:54:07 PM com.jme3.material.MaterialDef

INFO: Loaded material definition: Unshaded

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Gui Node)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Statistics View)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (Statistics View) attached to this node (Gui Node)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (floor) attached to this node (Root Node)

Nov 11, 2011 12:54:07 PM com.jme3.scene.Node attachChild

INFO: Child (p1) attached to this node (Root Node)

Nov 11, 2011 12:54:07 PM com.jme3.renderer.Camera

INFO: Camera created (W: 1, H: 1)

Nov 11, 2011 12:54:07 PM com.jme3.material.MaterialDef

INFO: Loaded material definition: GammaCorrection

Nov 11, 2011 12:54:07 PM com.jme3.material.MaterialDef

INFO: Loaded material definition: FXAA

Nov 11, 2011 12:54:07 PM com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform g_WorldViewProjectionMatrix is not declared in shader [ShaderSource[name=Common/MatDefs/Post/Post.vert, defines, type=Vertex], ShaderSource[name=Common/MatDefs/Post/GammaCorrection.frag, defines, type=Fragment]].

Nov 11, 2011 12:54:07 PM com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_computeLuma is not declared in shader [ShaderSource[name=Common/MatDefs/Post/Post.vert, defines, type=Vertex], ShaderSource[name=Common/MatDefs/Post/GammaCorrection.frag, defines, type=Fragment]].

Nov 11, 2011 12:54:07 PM com.jme3.renderer.lwjgl.LwjglRenderer updateShaderSourceData

WARNING: Bad compile of:

#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);
}


Nov 11, 2011 12:54:07 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Common/MatDefs/Post/FXAA.frag, defines, type=Fragment] error:0:2(12): warning: extension `GL_EXT_gpu_shader4' unsupported in fragment shader
0:0(0): error: no matching function for call to `texture2DLod(sampler2D, vec2, float)'
0:24(52): error: type mismatch
0:0(0): error: no matching function for call to `texture2DLodOffset(sampler2D, vec2, float, ivec2)'
0:25(70): error: type mismatch
0:0(0): error: no matching function for call to `texture2DLodOffset(sampler2D, vec2, float, ivec2)'
0:26(70): error: type mismatch
0:0(0): error: no matching function for call to `texture2DLodOffset(sampler2D, vec2, float, ivec2)'
0:27(70): error: type mismatch
0:0(0): error: no matching function for call to `texture2DLod(sampler2D, vec2, float)'
0:28(51): error: type mismatch
0:0(0): error: no matching function for call to `texture2DLod(sampler2D, vec2, float)'
0:53(64): error: type mismatch
0:0(0): error: no matching function for call to `texture2DLod(sampler2D, vec2, float)'
0:54(63): error: type mismatch
0:54(63): error: Operands to arithmetic operators must be numeric
0:54(64): error: Operands to arithmetic operators must be numeric
0:0(0): error: no matching function for call to `texture2DLod(sampler2D, vec2, float)'
0:56(64): error: type mismatch
0:0(0): error: no matching function for call to `texture2DLod(sampler2D, vec2, float)'
0:57(63): error: type mismatch
0:57(63): error: Operands to arithmetic operators must be numeric
0:57(64): error: Operands to arithmetic operators must be numeric
0:57(64): error: Operands to arithmetic operators must be numeric

at com.jme3.renderer.lwjgl.LwjglRenderer.updateShaderSourceData(LwjglRenderer.java:1034)
at com.jme3.renderer.lwjgl.LwjglRenderer.updateShaderData(LwjglRenderer.java:1072)
at com.jme3.renderer.lwjgl.LwjglRenderer.setShader(LwjglRenderer.java:1153)
at com.jme3.material.Material.render(Material.java:1030)
at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:657)
at com.jme3.post.FilterPostProcessor.renderProcessing(FilterPostProcessor.java:200)
at com.jme3.post.FilterPostProcessor.renderFilterChain(FilterPostProcessor.java:279)
at com.jme3.post.FilterPostProcessor.postFrame(FilterPostProcessor.java:292)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1130)
at com.jme3.renderer.RenderManager.render(RenderManager.java:1168)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:266)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)
at java.lang.Thread.run(Thread.java:662)
Nov 11, 2011 12:54:07 PM com.jme3.renderer.lwjgl.LwjglRenderer cleanup
INFO: Deleting objects and invalidating state
Nov 11, 2011 12:54:07 PM com.jme3.input.lwjgl.LwjglMouseInput destroy
INFO: Mouse destroyed.
Nov 11, 2011 12:54:07 PM com.jme3.input.lwjgl.LwjglKeyInput destroy
INFO: Keyboard destroyed.
Nov 11, 2011 12:54:07 PM com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread
INFO: Display destroyed.


and here is my code

[java]
import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.FXAAFilter;
import com.jme3.post.filters.GammaCorrectionFilter;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;


public class MyCollision extends SimpleApplication implements ActionListener{
private Spatial floorMesh;
private Spatial p1Mesh;
@Override
public void simpleInitApp() {
initKeys();
createPlayer();
createFloor();
rootNode.attachChild(floorMesh);
rootNode.attachChild(p1Mesh);
cam.setLocation(new Vector3f(0, 100, 0));
cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Z);

FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
GammaCorrectionFilter gamma = new GammaCorrectionFilter();
gamma.setComputeLuma(true);
fpp.addFilter(gamma);
FXAAFilter fxaa = new FXAAFilter();
fpp.addFilter(fxaa);// if i comment this line the program will run
viewPort.addProcessor(fpp);

}
private void createFloor() {
floorMesh= new Geometry("floor", new Box(new Vector3f(-1, -1, -1),new Vector3f(1, 1, 1)));
Material mat=new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material
mat.setColor("Color", ColorRGBA.Red);
floorMesh.setMaterial(mat);
floorMesh.scale(13, -1, 13);
floorMesh.setLocalTranslation(0, 0, 0);

}
private void createPlayer() {//color,location,name//id
p1Mesh= new Geometry("p1", new Box(new Vector3f(-1, -1, -1),new Vector3f(1, 1, 1)));
Material mat=new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material
mat.setColor("Color", ColorRGBA.Blue);
p1Mesh.setMaterial(mat);
p1Mesh.setLocalTranslation(0, 0, 0);
}
private void initKeys() {
inputManager.addMapping("U", new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("D", new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("L", new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("R", new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("F", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, new String[]{"U","D","L","R","F"});
}
@Override
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("U")) {

}
else if (name.equals("D")) {

}
else if (name.equals("L")) {

}
else if (name.equals("R")) {

}
else if (name.equals("F")) {

}
}//end of Action
public static void main(String[] args) {
MyCollision app= new MyCollision(); app.setShowSettings(false); app.start();
}//end of main
}//end of class


[/java]

your hardware does not support the GPU shader 4 extension.

I guess we should mention this in the javadoc of the filter

I think gpu shader 4 needs opengl 3 or even 3.2 support

1 Like

I see,

thank you nehon

@nehon: perhaps the GLSL language versions that are used in the material can be raised. This will make a proper error message be shown instead, what do you think?

I was thinking of checking the extension in the Filter, raise a warning and disable it when the extension is not found.

But yeah we can also raise the shader version

I prefer to rely on GLSL version for features … Extension support is usually pretty bad and may have various bugs

oh ok, I didn’t know

I’ll check what exactly is the glsl version for shader model 4, and change the j3m accordingly.

The thing is…this is going to crash right?

for filters it could be nice to have a fallback.

Many filters just don’t have a fallback … As far as I see it there’s two options:

  1. Crash
  2. Do nothing



    But regardless of which option we choose, we could have a Filter.isSupported() or FilterPostProcessor.supportsFilter() method that could check if the current hardware can run the filter

That’s great man, thanks for staying on top of this. I’ve been interested in in new stuff like this:

MIX MSAA + OGSSAA + FXAA 2xTSSAA

I saw an equivalent for this in the Trine 2 beta, specifically:
Medium (FXAA)
High (FXAA+2xSSAA)
Very High (FXAA+4xSSAA)

I'm sure a lot of interesting combinations can be made from this.