In the last 3 days i’ve been working on an SSR shader that does simple raymarching in world space. It is still far from perfect, expecially with high frequency normals, but i suppose it might be a starting point for other people interested in this effect, for this reason i’m opensourcing it. (it is not required by the license, but if you manage to improve it, you are welcome to share it back )
In my game i don’t use JME’s filter system, and i don’t know how to use it, so you will have to implement your own java part. The usage is quite simple and explained below.
Rendering the reflection scene
The material used for this pass is ssr.j3md
What you need in order to make this work is
- The texture containing the color buffer of your scene (what is rendered with outFragColor)
- The texture containing the depth buffer of your scene
- A texture containing X and Y components of the world space normals of your scene encoded in R and G channels and glossiness encoded in the B channel
If this texture is not provided, the shader will approximate the normals using the depth buffer
You will have also to provide the following vars
The extract below shows the code for my postprocessing pipeline
in("Scene", /** TEXTURE CONTAINING YOUR SCENE **/); in("SceneDepth", /** TEXTURE CONTAINING THE DEPTH OF YOUR SCENE **/); // OPTIONAL // in("SceneNormals", /** TEXTURE CONTAINING THE WORLD NORMALS in RG and GLOSSINESS in B **/); in("SceneViewProjectionMatrixInverse", camera.getViewProjectionMatrix().invert() ); in("SceneViewProjectionMatrix", camera.getViewProjectionMatrix().clone() ); in("CameraPosition", camera.getLocation() ); Vector2f frustumNearFar = new Vector2f(); frustumNearFar.x = camera.getFrustumNear(); frustumNearFar.y = camera.getFrustumFar(); in("FrustumNearFar",frustumNearFar);
Note: this pass renders an RGBA texture that contains the reflected scene in RGB and the strength of the reflection in A, so the output format must be set accordingly.
More settings are available, see the j3md
Once you have your reflection scene it is time to blur and merge it to your scene
Merging the reflection scene
Note: you can decide to skip this entire part and use a simple alpha blending
The material used for this pass is ssrmerger.j3md
This pass can be called multiple times and does horizontal and vertical gaussian blur, you only need to set the Size of your blur, the reflections rendered in the previous pass and the direction, in the last pass you will have to set also the scene to perform the merging.
So a two pass blur looks as follow
new SSRMerger().in("SSR",ssrout).in("Size",1.5).in("Horrizontal",true).out("scene",blur1); new SSRMerger().in("SSR",blur1).in("Size",1.5).in("Vertical",true).out("scene",blur2); new SSRMerger().in("SSR",blur2).in("Size",1.5).in("Horizontal",true).out("scene",blur3); new SSRMerger().in("SSR",blur3).in("Scene",scenein).in("Size",1.5).in("Vertical",true).out("scene",sceneout);
Note in the last pass in(“Scene”,scenein) is the input color scene (from your forward rendering or previous filter) and out(“scene”,sceneout) will be the final scene with the reflections merged.
Some screenshots with different settings