Implementing post rendering 2D filter

Hi everyone,



i'm trying to implement a shader based 2D filtering support for JME3 (ie applying a blur effect on the entire rendered scene).



The requirements are :

  • be able to apply a shader based filter to the entire scene
  • be able to stack multiple effects
  • be able to enable/disable filter at runtime
  • make it simple enough so that you don’t need to know what’s going on in the shader



    I read a lot of posts about techniques on how to achieve this since i’m pretty new to the 3D development mechanics, and finaly came to some results.

    But i have some gliches which i can’t get rid of, and i don’t really know if i’m doing things the way they should.



    here is the rendered effect (2 combined filters : radial blur + color overlay (light grey))





    I combined what i found in exemples in JME3 source code (FBO passthrough, render to texture, BasicShadowProcessor, Picture …) to make it work.



    I’ve got a SceneProcessor that creates one postViewPort by filter. It’s redirecting the main viewport render into a frame buffer which texture is the input of the filter.

    The filter stacking is done by rendering each filter in a frame buffer and applying the texture to the next filter.

    Only the last filter is rendered to the screen.



    A filter is basicaly a full screen quad on which you apply the previously rendered scene as a texture and a material using the filter shader.



    That said… i have few questions :

    1- Am i doing things right??

       As i said i’m a bit new to JME and maybe there is method like renderer.applyCrazyShader(ThatCrazyEffectEveryOneWants.class)… and i’m just reinventing the wheel.



    2- I’ve got a strange glitch. when my spider robot thingy is at the center of the scene and filtering is enabled i’ve got a flying quad ruining the effect (see pic below)



    The quad is rotating with the camera (it’s not just on the full screen quad) and if i move the spider, at some point, it just move out of the scene and disapear.

    Maybe someone can have an idea on how to get rid of it?



    3- This one is tricky to explain : to disable the filtering at runtime, i’m removing the processor from the viewport, and re-add it for enabling. The problem is that when i enable the filter, the fullscreen quad seems to appear before the render of the scene is done. The result is that you can see a blink of the scene as it was last time you disabled filtering.

    I don’t understand how it’s appening, because the fullscreen quad is in a postviewport and should be rendered after the main viewport.





    i attached the source files in the post.

    I made the radial blur shader by merging a bit of the gui shader from JME3 source and info found on this site : http://www.gamerendering.com/2008/12/20/radial-blur-filter/





    Thanks for reading my post, for the ones that made it through, just PM me “bananapie” and…i see what i can do  XD
1 Like

This is pretty cool. I was going to make something like this at some point, but you beat me to it :slight_smile:

So far I think you're doing things right, if you follow in the same way that ShadowProcessor and HDRProcessor do things.

One thing I did notice, was that you attach the fullscreen quad as a post viewport, this is probably not a good idea. The post viewport is usually used for GUI and such.

The best way is to set a framebuffer on the main viewport, then process it in SceneProcessor, and output the results to the screen.

As a result, the moment you attach the SceneProcessor to a viewport of your choice, it will be processed and the effect displayed the moment it finishes handling that viewport. Look at how HDRProcsesor for example renders all the result to the screen after its done.

Momoko_Fan said:

I was going to make something like this at some point, but you beat me to it :)

Well, it seems you are already doing a lot in here, you can't do everything  :wink:

I've inspected the HDRRenderer code.
i'll come up with a better version of the FilterPostProcessor soon.

Thanks for your help

Hi all,



i made some progress whith the FilterPostProcessor, and finally came to a quite satisfying solution.



As you advised, Momoko_Fan, i used HDRRenderer as a model, so now :

  • i have only a single quad to render multiple filters
  • Filters are no more geometry, they just hold a FrameBuffer and the corresponding texture.
  • No more postViewPort usage
  • No more UFO quad glitch :stuck_out_tongue:



    I attached an exemple based on the TestSceneLoading.

    here is a screenshot





    If you want to try it just create a new project with JMP and copy the content of the zip file to the root folder.



    To initialize the filter see those lines in simpleInitApp


  if (renderer.getCaps().contains(Caps.GLSL100)) {
            fpp=new FilterPostProcessor(assetManager);
            //adding RadialBlurFilter
            // you can ply with the values to tweek the radial blur (those are default values)
            fpp.addFilter(new RadialBlurFilter(1.0f, 2.2f));
            
            //adding ColorOverlayFilter
            //you can change the color (default is white resulting in a transparent filter)
            fpp.addFilter(new ColorOverlayFilter(ColorRGBA.LightGray));
  }



In game press "f" to activate filtering and "g" key to deactivate.

If you want to make your own filter you just need to create a MyFilter java class that extends Filter and implement the getMaterial method.
This method should return a material using the effect shader and with all uniforms setted.
The uniform for the texture holding the render of the scene must be named "m_Texture" in your matDef/shader.

hope you'll find this usefull.


by the way you'll have to find the brightSky.dds texture in the JME3 test resource file as it's to big to be attached in a post

brilliant…

thanks…

Thanks from me, too!

Pretty cool. Now we just need some awesome filters to get this going :slight_smile: