multisampling, antialiasing

I was attempting to reproduce Nvidia's openGL sample "Simple Framebuffer Object" using c#/tao - I am specifically interested in how they perform the multisample/antialiasing pass -

has anyone had any luck with this (antialiasing) in tao?

The example I reference is here:
http://developer.nvidia.com/object/sdk_home.html

thanks!

I don't know exactly what

I don't know exactly what the nVidia sample does, but I've been able to do MSAA on a framebuffer with Tao. It's not really different from C/C++.

that is great news! The MSAA

that is great news!

The MSAA would be a nice filter to run.

In the Nvidia example, they compile, then call a texture program:

glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, textureProgram);
glEnable(GL_FRAGMENT_PROGRAM_ARB);

I wasn't able to reproduce this step - is there an equivalent fragment shader that I could use that anyone knows of? I have discovered that this is compiled during initialization, then is being enabled after they draw to the FBO and before the bind the texture to a quad (then disabled right after they draw a quad with the MSAA enabled texture)

am I making this too difficult? is a separate shader necessary?

You should be doing

You should be doing something like this:

// Create multisampled framebuffer
int fb, color. fbtex;
Gl.glGenFramebuffersEXT(1, out fb);
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, fb);
Gl.glGenRenderbuffersEXT(1, out color);
Gl.glBindRenderbufferEXT(Gl.GL_RENDERBUFFER_EXT, color);
Gl.glRenderbufferStorageMultisampleEXT(Gl.GL_RENDERBUFFER_EXT, 4, Gl.GL_RGBA, 800, 600);
Gl.glFramebufferRenderbufferEXT(Gl.GL_FRAMEBUFFER_EXT, Gl.GL_COLOR_ATTACHEMENT0_EXT, Gl.GL_RENDERBUFFER_EXT, color);
// Repeat for depth buffer
// Create non-multisampled framebuffer for reading
Gl.glGenFramebuffersEXT(1, out fbtex);
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, tex);
Gl.glFramebufferTexture2DEXT(Gl.GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT, Gl.GL_TEXTURE_2D, tex, 0);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);


// Rendering
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, fb);
// Render your scene
// Copy MSAA buffer contents to texture
Gl.glBindFramebufferEXT(Gl.GL_READ_FRAMEBUFFER_EXT, fb);
Gl.glBindFramebufferEXT(Gl.GL_DRAW_FRAMEBUFFER_EXT, fbtex);
Gl.glBlitFramebufferEXT(0,0,800,600,0,0,800,600, Gl.GL_COLOR_BUFFER_BIT, Gl.GL_NEAREST);
// Final output
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, 0);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, tex);
// Render Fullscreen Quad

btw. to whoever manages to site, can we please have a proper code tag that doesn't break with whitelines?

!but now whats this! thanks

!but now whats this!

thanks so much for that sample code - it is nice to see that I was getting close, anyways...

Here's the wow part of this post:

has Tao incorporated multisampling into their latest build?

I grabbed the more recent build from this forum. And now, way before I start drawing, in the "InitializeComponent()" step I can add this line

this.simpleOpenGlControl1.Multisampling = 8;

and everything looks great! Too good to be true? Anyone else using this?

I gathered (and implemented) this from the following post over in the Developer Talk area:
http://www.taoframework.com/forum/development/developertalk/299#comment-...

this seems to be way easier to me, but perhaps there is a performance hit or something more that I am missing...

AFAIK the MSAA setting on

AFAIK the MSAA setting on OpenGlControl does multisampling when rendering to the screen (WGL_ARB_multisample). The example I showed does multisampling when rendering to a framebuffer (GL_EXT_framebuffer_multisample) and is used when you'd like to do post-processing on the image afterwards or for render-to-texture rendering.

this seems to be way easier

this seems to be way easier to me, but perhaps there is a performance hit or something more that I am missing...
No speed hit outside what's normal for MSAA. The difference really is what SeaEagle1 said (screen vs framebuffer multisample).

Note that your card may not actually support 8 samples per fragment, but that's not a problem (the biggest available value will be selected). Just something to keep in mind if you make this a user-selectable setting.

------
OpenTK

just wanted to update my

just wanted to update my progress/findings - the method I ended up using (this.simpleOpenGlControl1.Multisampling = 4;) indeed has no effect on the scenes rendered to my FBO as you stated.

In short, if you are just drawing to the screen, the (this.simpleOpenGlControl1.Multisampling = 4;) works like a charm (even works on my old graphics card at home that doesn't support more than openGL 1.2)

the method of using several frameBuffers to achieve MSAA (i.e. example from SeaEagle1) is necessary for scenes being drawn to a FBO, and requires openGL 2.0 or 2.1 hardware/drivers

thanks again for the help.

I hit a wall with this MSAA

I hit a wall with this MSAA method - I am trying to apply the antialiasing to an image that is about 2600x2400 pixels.

It took me awhile to determine the size/aspect limitations too. Right now it only runs at about 1600x1600

Is there a way to apply antialiasing to just part of an image? I tried using scissor test, but it still seems to apply antialiasing to the whole image (even though it is only drawing a fraction of it)

are there other ways of optimizing that are commonly used?

my code currently looks something like this:

// Setup our FBO
Gl.glGenFramebuffersEXT(1, out fb);
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, fb);

Gl.glGenTextures(TextureUnit, out tex);

//*****************************************************************
// init texture
Gl.glActiveTexture(TextureUnit);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, tex);

Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, Width, Height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, null);

Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
Gl.glGenerateMipmapEXT(Gl.GL_TEXTURE_2D);
// end init texture
//*****************************************************************

Gl.glGenRenderbuffersEXT(1, out colorFB);
Gl.glBindRenderbufferEXT(Gl.GL_RENDERBUFFER_EXT, colorFB);
Gl.glRenderbufferStorageMultisampleEXT(Gl.GL_RENDERBUFFER_EXT, 4, Gl.GL_RGBA, Width, Height);
Gl.glFramebufferRenderbufferEXT(Gl.GL_FRAMEBUFFER_EXT, Gl.GL_COLOR_ATTACHMENT0_EXT, Gl.GL_RENDERBUFFER_EXT, colorFB);

Gl.glGenRenderbuffersEXT(1, out depthFB);
Gl.glBindRenderbufferEXT(Gl.GL_RENDERBUFFER_EXT, depthFB);
Gl.glRenderbufferStorageMultisampleEXT(Gl.GL_RENDERBUFFER_EXT, 4, Gl.GL_DEPTH_COMPONENT, Width, Height);
Gl.glFramebufferRenderbufferEXT(Gl.GL_FRAMEBUFFER_EXT, Gl.GL_DEPTH_ATTACHMENT_EXT, Gl.GL_RENDERBUFFER_EXT, depthFB);

Gl.glGenFramebuffersEXT(1, out fbtex);
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, fbtex);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, tex);
Gl.glFramebufferTexture2DEXT(Gl.GL_FRAMEBUFFER_EXT, Gl.GL_COLOR_ATTACHMENT0_EXT, Gl.GL_TEXTURE_2D, tex, 0);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);

Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, fb);

int status = Gl.glCheckFramebufferStatusEXT(Gl.GL_FRAMEBUFFER_EXT);
if (status != Gl.GL_FRAMEBUFFER_COMPLETE_EXT)
throw new Exception("The card may not be compatable with Framebuffers. Try another bit depth.");
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, 0);// Unbind the FBO for now

AA is just expensive to do.

AA is just expensive to do. I don't know what hardware you're targeting but my 7600GT says it's able to do framebuffers up to 4096x4096 pixels, so 2600x2400 should be possible imho. If you only need partial aa, you can try to split up your scene in for example 4 fbos and merge them to the final image, but that's only useful if it allows you to reduce the number of pixels in the msaa fbo. (as you found out, MSAA is done on framebuffer level)

Some possible (small) optimizations when I look at your code:
- Make sure you need mipmapping, it's quite a bonus when you can get rid of it.
- Check you need RGBA or just RGB, 25% memory reduction

What kind of wall is this?

What kind of wall is this? Performance, or does the application fail to run?

------
OpenTK

thanks for the tips. I did

thanks for the tips.

I did find that the GeforceFX4600 was able to play the program at full resolution, antialiased. This is the platform I am deploying on, so that is good. My development platform, however, is using a GefFX1500 which chokes at some of the higher resolutions (maxed out at 1600x1200). The FX4600 plays it without problem.

the nature of the failure (on the FX1500) is that - as I increase the buffer resolution - frames drop, then only part of the display is updated (and finally) blank textures/program crashes.

I will try dropping the alpha to see if that helps.

I will also try implementing an Nvidia-specific antialiasing filter to see if that helps? if that is what this is: Gl.glRenderbufferStorageMultisampleCoverageNV

Theme by La Boite a site | Powered by Drupal