Anti Aliasing and LightScatteringFilter

Hello,

I have s problem when using the Light Scattering Filter. When it is used, the anti aliasing settings seem to be ignored, in fact there is no anti aliasing done.

Most time (when you are not looking into the sun) the filter is inactive. In this case, the fragment shader says

    gl_FragColor= texture2D(m_Texture,texCoord);

Should this be different? Any help is greatly appreciated.

Michael

Are you setting the number of samples on the FilterPostProcessor to be the same as the AA settings of the app?

Thanks, this points to the right direction. If I now set the numSamples in the FilterPostprocessor, I get errors of the following type:

compile error in:ShaderSource[name=LightScattering15.frag, defines, type=Fragment, language=GLSL150] error:
WARNING: 0:52: ‘texture2D’ : function is deprecated and not available in Core Profile context
WARNING: 0:56: ‘texture2D’ : function is deprecated and not available in Core Profile context
WARNING: 0:60: ‘texture2D’ : function is deprecated and not available in Core Profile context
WARNING: 0:64: ‘texture2D’ : function is deprecated and not available in Core Profile context
ERROR: 0:84: ‘getColor’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:84: ‘=’ : cannot convert from ‘const float’ to ‘4-component vector of float’
ERROR: 0:93: ‘fetchTextureSample’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:93: ‘r’ : field selection requires structure, vector, or matrix on left hand side
ERROR: 0:94: ‘fetchTextureSample’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:102: ‘getColor’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:102: ‘assign’ : cannot convert from ‘const float’ to ‘FragUserData 4-component vector of float’

Can you help there? Thank you!

Michael

On what hardware are you running it?

I use it here on a Windows 7 machine with integrated Intel graphics (core i7), which usually makes no Problems with OpenGL.,. But 'll try it also on a NVIDIA hardware and let you know.

Hello, I analyzed the problem on the two machines. On a Windows 7 computer with NVIDIA graphics card, the filter runs without problems. When I check the OpenGL capabilities, I see the Follwing:

BOTH computers can:

[FrameBuffer, FrameBufferMRT, FrameBufferMultisample,
TextureMultisample, OpenGL20,
OpenGL21, OpenGL30, OpenGL31, OpenGL32, ARBprogram, GLSL100, GLSL110, GLSL120,
GLSL130, GLSL140, GLSL150, VertexTextureFetch, TextureArray,
FloatTexture, FloatColorBuffer,
FloatDepthBuffer, PackedFloatTexture, SharedExponentTexture,PackedFloatColorBuffer,
NonPowerOfTwoTextures, MeshInstancing, VertexBufferArray,
Multisample, PackedDepthStencilBuffer]

The NVIDIA card offers two other capabilities:

TextureBuffer and TextureCompressionLATC

Is the capability TextureBuffer necessary for the LightScatteringFilter?

Thanks for your help

Michael

I guess the problem is that we should use “texture” instead of “texture2D”. texture2D is indeed deprecated for glsl1.5…it’s just a bit rough that the vendor decided to fail compiling on deprecated stuff…
I’ve committed the change could you please test with next nightly?

But it says “Core profile” so I think the compiler is doing what it is supposed to.

@nehon said: I guess the problem is that we should use "texture" instead of "texture2D". texture2D is indeed deprecated for glsl1.5....it's just a bit rough that the vendor decided to fail compiling on deprecated stuff... I've committed the change could you please test with next nightly?

Thanks. I’ll try it and give you Feedback. Thank you for your efforts.

Michael

Hello,

on the Win7-computer without the textureBuffer capability, i get the following error after your changes:

Exception in Render thread
com.jme3.renderer.RendererException: compile error in:ShaderSource[name=LightScattering15.frag, defines, type=Fragment, language=GLSL150] error:ERROR: 0:84: ‘getColor’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:84: ‘=’ : cannot convert from ‘const float’ to ‘4-component vector of float’
ERROR: 0:93: ‘fetchTextureSample’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:93: ‘r’ : field selection requires structure, vector, or matrix on left hand side
ERROR: 0:94: ‘fetchTextureSample’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:103: ‘getColor’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:103: ‘assign’ : cannot convert from ‘const float’ to ‘FragUserData 4-component vector of float’

Thanks,

Michael

Can you post the dump of the shader code that was right before that? It includes line numbers and has all of the includes expanded and stuff.

Hello,

I am not sure how to dump the shader code, but the fragment shader is as follows ( i susbtituted the import line). I marked the line 84:

#extension GL_ARB_texture_multisample : enable

uniform int m_NumSamples;
uniform int m_NumSamplesDepth;

#ifdef RESOLVE_MS
#define COLORTEXTURE sampler2DMS
#else
#define COLORTEXTURE sampler2D
#endif

#ifdef RESOLVE_DEPTH_MS
#define DEPTHTEXTURE sampler2DMS
#else
#define DEPTHTEXTURE sampler2D
#endif

// NOTE: Only define multisample functions if multisample is available and is being used!
#if defined(GL_ARB_texture_multisample) && (defined(RESOLVE_MS) || defined(RESOLVE_DEPTH_MS))
vec4 textureFetch(in sampler2DMS tex,in vec2 texC, in int numSamples){
ivec2 iTexC = ivec2(texC * vec2(textureSize(tex)));
vec4 color = vec4(0.0);
for (int i = 0; i < numSamples; i++){
color += texelFetch(tex, iTexC, i);
}
return color / float(numSamples);
}

vec4 fetchTextureSample(in sampler2DMS tex,in vec2 texC,in int sample){
ivec2 iTexC = ivec2(texC * vec2(textureSize(tex)));
return texelFetch(tex, iTexC, sample);
}

vec4 getColor(in sampler2DMS tex, in vec2 texC){
return textureFetch(tex, texC, m_NumSamples);
}

vec4 getColorSingle(in sampler2DMS tex, in vec2 texC){
ivec2 iTexC = ivec2(texC * vec2(textureSize(tex)));
return texelFetch(tex, iTexC, 0);
}

vec4 getDepth(in sampler2DMS tex,in vec2 texC){
return textureFetch(tex,texC,m_NumSamplesDepth);
}
#endif

vec4 fetchTextureSample(in sampler2D tex,in vec2 texC,in int sample){
return texture(tex,texC);
}

vec4 getColor(in sampler2D tex, in vec2 texC){
return texture(tex,texC);
}

vec4 getColorSingle(in sampler2D tex, in vec2 texC){
return texture(tex, texC);
}

vec4 getDepth(in sampler2D tex,in vec2 texC){
return texture(tex,texC);
}
uniform COLORTEXTURE m_Texture;
uniform DEPTHTEXTURE m_DepthTexture;

uniform int m_NbSamples;
uniform float m_BlurStart;
uniform float m_BlurWidth;
uniform float m_LightDensity;
uniform bool m_Display;
uniform vec3 m_LightPosition;

in vec2 texCoord;
out vec4 fragColor;

void main(void)
{
if(m_Display){
// THIS SEEMS TO BE LINE 84
vec4 colorRes= getColor(m_Texture,texCoord);
float factor=(m_BlurWidth/float(m_NbSamples-1.0));
float scale;
vec2 texCoo=texCoord - m_LightPosition.xy;
vec2 scaledCoord;
vec4 res = vec4(0.0);
for(int i=0; i<m_NbSamples; i++) {
scale = i * factor + m_BlurStart ;
scaledCoord=texCoo*scale + m_LightPosition.xy;
if(fetchTextureSample(m_DepthTexture, scaledCoord,0).r==1.0){
res += fetchTextureSample(m_Texture,scaledCoord,0);
}
}
res /= m_NbSamples;

    //Blend the original color with the averaged pixels
    float mean = (res.r + res.g + res.b)/3;
    fragColor =mix(colorRes ,mix( colorRes, res, m_LightDensity),mean);        
}else{
    fragColor = getColor(m_Texture,texCoord);
}

}

No, specifically the one that was in the log where you saw the error messages. Whenever the shader fails to compile, in addition to dumping the error it also prints out the shader that was compiled.

The shader as it exists in source form is not useful because none of the line numbers will match up. This leaves some guesswork to try to figure out what the error refers to exactly.

And when you post code, please use code tags.

Only thing I can think of here is that somehow GL_ARB_texture_multisample is not defined with this card and we failed to detect it before…
Could you please add this line to your simpleInit method and post the output please?
System.out.println(renderer.getCaps());

Hello,

on the intel card (where the error occours) I have:

[FrameBuffer, FrameBufferMRT, FrameBufferMultisample, TextureMultisample, OpenGL20, OpenGL21, OpenGL30, OpenGL31, OpenGL32, ARBprogram, GLSL100, GLSL110, GLSL120, GLSL130, GLSL140, GLSL150, VertexTextureFetch, TextureArray, FloatTexture, FloatColorBuffer, FloatDepthBuffer, PackedFloatTexture, SharedExponentTexture, PackedFloatColorBuffer, NonPowerOfTwoTextures, MeshInstancing, VertexBufferArray, Multisample, PackedDepthStencilBuffer]

On the NVIDIA card, where the former code worked, there is in addition

[TextureBuffer, TextureCompressionLATC]

I could imagine, that the capability TextureBufferis required… ??

Thanks again,

Michael

Looks like ARB_texture_multisample is not supported by the card…that’s pretty weird considering the caps you posted but i guess that’s the issue

I know it’s kind of a far fetched work around…but did you consider using FXAA?
I’m gonna see if I can get the information about the ARB_texture_multisample extension availability on the card, when enabling multisampling for the FilterPostProcessor…but the fall back will be to disable multisampling so it won’t fix your issue…it’ll just prevent your game from crashing. So FXAA might be the way to go in any case…

One more thing, could you try to test this code
System.err.println(GL11.glGetString(GL11.GL_EXTENSIONS));
if the output does not contain GL_ARB_texture_multisample then that’s the issue.
You could check for this extension and enable multisampling only if it’s there, if it’s not, use FXAA.

@nehon said: One more thing, could you try to test this code System.err.println(GL11.glGetString(GL11.GL_EXTENSIONS)); if the output does not contain GL_ARB_texture_multisample then that's the issue. You could check for this extension and enable multisampling only if it's there, if it's not, use FXAA.

… and if it is GL_ARB_texture_multisample that is the issue do you suppose it would be worthwhile to add that check to the #ifdef RESOLVE_MS (and the depth version) that sets up the sampler types?

Well if i check it there it’s too late because the framebuffer is already a MS framebuffer and reading it as a texture2D will fail.
I guess a better way would be to check it directly in the FilterPostProcessor when enabling MS, and either throw an Exception or fallback to no MS…
Throwing an exception would allow the user to fall back to FXAA if he wants…
We’d need a generic way to get those extensions in the renderer to avoid making direct gl calls in the core. Maybe something like renderer.supportsExtension(extensionName) would be nice.

@nehon said: Well if i check it there it's too late because the framebuffer is already a MS framebuffer and reading it as a texture2D will fail. I guess a better way would be to check it directly in the FilterPostProcessor when enabling MS, and either throw an Exception or fallback to no MS.... Throwing an exception would allow the user to fall back to FXAA if he wants... We'd need a generic way to get those extensions in the renderer to avoid making direct gl calls in the core. Maybe something like renderer.supportsExtension(extensionName) would be nice.

I don’t know. In general, I find it frustrating that we can’t query some more general things about openGL. (For example, I’d like to be able to query the sprite size.) At least not without resorting to direct LWJGL calls. :-/