Custom Fog Shader?

Hey all,



I know there isn’t a proper fog system yet for JME3 (because it requires “shader injectors”, something not implemented yet as I understand it). However, I see other people writing their own shaders to do fancy stuff like force field effects. Is it possible to write a fog shader like this, and apply it to my in-game terrain? I can learn how to make it – just want to know if it is possible (or does it still require unimplemented JME3 features?).



Thanks!

It looks jme3 already have a fog filter, and you can add it to the app easily by using the Filter Processors plugin.

I’ve tried the fog filter… but it doesn’t work with transparency T_T… the fog filter works off the Z buffer after everything is drawn, so either transparent objects get improperly covered in fog, or they make everything behind them at the same “fog level” as the transparent object (depending on if depthWrite is off or on).

A fog filter can be done with just a few lines added to the end of Lighting. The reason the JME crew are reluctant to continue shoehorning things into Lighting.j3md is because it’s already pretty bloated.



I don’t know if there’s a better way, but I calculate my own z varying in my vert shader and then use that in the frag shader to tweak the colors right at the end to mix in a fog based on distance. If you’ve never modified a shader before then it’s probably a pretty daunting task, though.

The reason the JME crew are reluctant to continue shoehorning things into Lighting.j3md is because it’s already pretty bloated.

Also this way implies that you have to set the fog params to every single material you use....
We would need some kind of global params that could be injected to the shader at runtime....wait... aaaarggghhhh!!! Shader Injection 8O

@phr00t maybe you can try to put your transparent objects in the translucent bucket and use a TranslucentBucketFilter at the end of your filter stack.
Transparency and filters is tricky, especially with filters that use depth. This Filter as been made to resolve transparency issues with the water filter it should be the same for fog.

I wouldn’t mind supplying fog parameters to each of my materials if it meant full fog effects (I don’t have too many materials anyway). I will try the translucent bucket thing - however, I still want fog applied to the water (and the stuff behind it).

however, I still want fog applied to the water (and the stuff behind it).

This wouldn't work with the material way btw, now that i think of it....
However it works with the filter as long as the fog filter is after the water filter....
WaterFilter is really one of its kind because it's a 2D post process that actually renders a 3D object in the scene....it's pretty tricky to make it fit with every other features...
WaterFilter is really one of its kind because it’s a 2D post process that actually renders a 3D object in the scene….it’s pretty tricky to make it fit with every other features…


I'm not using a WaterFilter... my "water" is just a large semi-transparent quad that acts as the water surface (same goes for my cloud layers). Would the material method work for this? I'm really willing to try (almost) anything to get a decent fog system working, since just about every other part of my game is "complete".

What is this "material" way, anyway? And how could I implement it? :)

Basically its computing and displaying the fog directly on the object material instead of in a post processor. So you’d use MyFogLighting.j3md instead of Lighting.j3md. Just copy&paste the default jme shader from the “Library” node to the “Project Assets” node and adapt it.

In my case, I add a varying to my .vert and .frag:



varying float my_z;



I also have a uniform for fog color and I use the alpha channel of the fog color for distance.



And then in the main of my .vert after gl_Position is calculated:

my_z = gl_Position.z;





Then in my .frag’s main at the end:



[java]

float fogDensity = 1.2;

vec4 fogColor = m_FogColor;

float fogDistance = fogColor.a;

fogColor.a = 1.0;



float depth = my_z / fogDistance;



float fogFactor = exp2( -fogDensity * fogDensity * depth * depth * LOG2 );

fogFactor = clamp(fogFactor, 0.0, 1.0);

gl_FragColor =mix(fogColor,gl_FragColor,fogFactor);

[/java]



I don’t know if it’s the best way but it works for me. I calculate material alpha separately and apply it after the fog mix.



And if forking the lighting material and adding the above sounds scary then it’s best to steer clear. Editing GLSL is not for the faint of heart.

3 Likes
I don’t know if it’s the best way but it works for me

yes that's what i meant by "the material way"

I’m not going to bother to manually quote because I have no patience for that today. :wink:



Yeah, I know that’s what you were talking about with the “material way”. :slight_smile: I just don’t know if it’s the best way to do the “material way”. I generally whack at things until they look like I want them to and then treat them like they are covered with thorns. :slight_smile:

Another potential complication… I’m currently using the unshaded.j3md (because it renders much faster) and I do all my lighting via baked-in textures. Is there a way to modify the unshaded.j3md similarly? Or does it need to be the lighting one (and then I will have to take the hit in FPS)?



@pspeed, can you post that shader somewhere for me to look at? :slight_smile:



Thanks again!

It doesn’t have to be the lighting shader. That code snippet could be added to most shaders. As long as you can provide the z value to my_z in the .vert and do the gl_FragColor fog mix at the end of the .frag you are fine.



I don’t really want to post my whole shader, though.

Thanks @pspeed – I’m currently fixing the Shape3d code to make my weapons into 3D objects from 2D images (going pretty good so far). After that is done, I’ll tackle this. It sounds promising!

IT’S ALIVE! MUWAHAHAH!



http://i.imgur.com/wnpXA.png



Sooooo… is there a way to modify shader parameters via my Java code? Like, I’d like to change the fog color and density. I have a uniform fog color and a fixed density, currently…

mythruna 2 :P.

mythruna 2 .


ooooooooooooooooooo now now this game isn't about crafting :P It is about blowing stuff up, sneaking around, doing quests, loading your character with tons of futuristic items etc. etc. :D :D

I also think I found the answer to my own question:

[java]myMaterial.setVector4("m_FogColor", myVec4Color);[/java]

Or myMaterial.setColor( “m_FogColor”, myColor );

mythruna 2 :P .


I do have to admit... that kind of thing brings a little tear to my eye. ;) If I had a nickel for every time someone said "Oh, Minecraft with a texture pack" I think I'd be notch-rich by now. ;)