[SOLVED] Alternative to FogFilter that uses radius instead of a plane?

Hello, everyone.

I have a problem with the FogFilter, which i was wondering if anyone has a solution to.
I’m working on a multiplayer voxel game and tried adding fog to it, but the default jME3 shader doesn’t work as i’d like it to - it appears to draw fog in the distance based on the distance from the camera plane.
This means that you are able to see more of the game world around the sides of the screen compared to the middle, which is not optimal (players could “peek” and see further than they should be able to by rotating the camera).

See these screenshots for a description of the problem:

I was hoping that someone could provide me with an alternative shader that uses the distance from the camera itself (as described here: Create a fog shader, under “Getting the distance: Z-Depth vs Length”), because i tried solving the problem myself for the majority of the past 3 days unsuccessfully.
It should be a simple fix, but i cannot wrap my head around GLSL.

For reference (and convenience), here’s an archive of the default shaders: Dropbox link

files taken from: jME3-effects.jar/Common/MatDefs/Post/
contained within are:
– Fog.j3md
– Fog.frag
– Post.vert
– Fog15.frag
– Post15.vert

In addition, here’s the (seemingly) relevant code inside of Fog15.frag

void main() {
   vec4 texVal = getColor(m_Texture, texCoord);
   float fogVal = getDepth(m_DepthTexture,texCoord).r;
   float depth= (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - fogVal* (m_FrustumNearFar.y-m_FrustumNearFar.x));
   float fogFactor = exp2( -m_FogDensity * m_FogDensity * depth *  depth * LOG2 );
   fogFactor = clamp(fogFactor, 0.0, 1.0);
   gl_FragColor =mix(m_FogColor,texVal,fogFactor);
}

Anyone?

1 Like

For post-processed fog, this will look horrible.

Your best (and probably most efficient also by the way) option would be to incorporate fog into your actual shaders. It only takes a few lines added to the end and you can calculate distance however you want.

Edit: note it also gives you the ability to turn off fog for some objects (like lights if you use the fog for night-time darkness, for example).

The problem is that i can’t do this myself without spending weeks or so reading books about how all of this works.

There don’t appear to be too many tutorials on how to create these effects, which may be further complicated by the fact that jME3 uses specific variable names (not that i know what they are supposed to represent) - https://docs.jmonkeyengine.org/advanced/jme3_shaders.html

The closest thing i found to anyone else having implemented fog shaders (still as a post process effect) in jME3 is this thread, the code in which seemed to be bugged (and after fixing it, it still used the same distance calculation approach) - https://hub.jmonkeyengine.org/t/glsl-implementation-of-fog-filter-linear-exp2-camera-to-distance-exp2-distance-to-infinity/23546/3

Bottom line, i can’t do it myself and have no idea where to start, therefore i decided to ask the community before giving up. I’m not really concerned about how it looks, i just need to make the limited rendering distance. That is all.

I use method suggested by @pspeed

In any shader I have added:
in .j3md:

MaterialParameters 
    {
        Float FogStartDistance : 1500.0
        Float FogMaxDistance : 8000.0
        
    
    } 

in .vert in main()

dist = distance(g_CameraPosition.xyz, worldPos.xyz);

in .vert

varying float dist;

in .frag

varying float dist;
uniform float m_FogStartDistance;
uniform float m_FogMaxDistance;

in .frag in main() in the end

if (dist > m_FogStartDistance){
	       vec4 newLight  = m_Light;
               float distance = clamp((dist - m_FogStartDistance) / (m_FogMaxDistance - m_FogStartDistance), 0.0, 0.8);
               gl_FragColor = mix(texture2D(m_Texture, uv) * color * m_Light , newLight, distance);
	   }

Results in my game:

Not the best solution because I am not a shader masta but for me it works. Of course it can be different for different shaders, but I use it as a pattern.

3 Likes

Tried making the changes you suggested by copying the files, changing the filenames (and fixing the paths), as well as creating a new .java file that extends FogFilter.java to set the proper fog start and end values so they don’t have to be hardcoded.

Got the following error when i tried to launch the game:

Any idea how i’m supposed to fix this?
How am i supposed to pass the g_CameraPosition and worldPos values to the shader?
I’m feeling confused. :confused:

Here are the new files, in case i’m forgetting to do something: Dropbox link

Perhaps you could even upload an example of the shaders?

At first, you should make changes not to post but to Lightning (or your object’s shader). At second, it is just a pattern and it would be good for you to learn shaders a bit. Because in my case it is not the same for every shader. Just similar.
https://drive.google.com/open?id=0B1tgYi3V4RzsSmlfMlhnY0gxY1E

I use it for 2D sprites.

Thanks for the help, this will serve as a nice starting point! :slight_smile:
Edit: Nothing works, everything is terrible, life sucks.
Never touching shaders again in my life.

Biting the bullet and learning basic shaders is probably worth the time. Even if you don’t write your own in the end. It gives you are really good idea on what works, what is easy, and what will really use up all the fillrate.

In this case, this type of fog was is very similar to fix pipeline functionally in days of old. So a fairly easy one to add. At least in the bigger scheme of things. And then you can even contribute!

Some shaders i am considering adding to jME. Screen Space Reflections, Finite distance IBL (this is very experimental, but lots of fun, i even get to do math!), Planner Reflectors if that doesn’t work out, however jME sort of already has this with some of its water shaders.

1 Like