Custom Fog Shader?

@phr00t said:
@johncl -- yeah, I need to update the fog color dynamically for all my materials when the day/night shift happens. It was a minor pain... but once the code was there to do it, I forgot about it :D


Once you give a Material a color instance then you can change that color without resetting it to the Material. So just make sure to give all of your materials the same fog Color instance and then you only have to worry about changing that one color instance.
1 Like
@mifth said:
@pspeed , may I use your code for my LightBlow shader? I already have a task for it: http://code.google.com/p/jme-glsl-shaders/issues/detail?id=3


Yeah, that's fine.
@pspeed said:
Once you give a Material a color instance then you can change that color without resetting it to the Material. So just make sure to give all of your materials the same fog Color instance and then you only have to worry about changing that one color instance.


http://4.bp.blogspot.com/-7UyesaqfeFM/TmUTMYv0IiI/AAAAAAAAANE/lxclINENzkE/s1600/TheMoreYouKnow.jpg

Ah cool. I always thought things like Color objects were immutable stuff. That would simplify it immensely… Well if I can get it working with the post process water.

Vertex fog like I posted should have no problem with water. It’s post-processing fog that gets tricky.

1 Like

Ah brilliant. So this goes into my code asap! :slight_smile:

Hi!! I have added the fog to my LightBlow shader. Now objects can fade to either color or skybox out.



http://imageshack.us/photo/my-images/832/lightblowfog.jpg/



[java]

#ifdef FOG



vec4 fogColor = m_FogColor;



#ifdef FOG_SKY

fogColor.rgb = Optics_GetEnvColor(m_FogSkyBox, I).rgb;

#endif



float fogDensity = 1.2;

float fogDistance = fogColor.a;

float depth = fog_z / fogDistance;

float LOG2 = 1.442695;



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

fogFactor = clamp(fogFactor, 0.0, 1.0);

gl_FragColor.rgb =mix(fogColor.rgb,gl_FragColor.rgb,vec3(fogFactor));

#endif

[/java]



My shader located here:

http://code.google.com/p/jme-glsl-shaders/

Here is a fix to how to compute the fog via a frag shader… The way it is currently, brightness is not taken into effect at all. sooo… vec3(0.4, 0.1, 0.1) would look the same as vec3(1.0, 0.0, 0.0). To make sure the fog is rendered at the actual color you have defined, replace the last gl_FragColor = mix, blah) with:



[java]gl_FragColor.rgb = mix((gl_FragColor.rgb*fogColor.rgb),gl_FragColor.rgb,fogFactor);[/java]



Yeah… I know this is an old topic… but if this is ever going to be added to the Lighting.vert/.frag… it should probably do what you would expect :wink:



@mifth You probably want to update your light shader with this fix.

@pspeed Not sure if you are interested or not (maybe you already found and fixed this in your game) but, just in case you haven’t.

@nehon Because your cool and it might help determine whether or not to update the Lighting shader.



NOTE… As an added bonus, the fog color changes with the light settings.

I had a couple more thoughts on this as well…


  1. a minimum start depth… i.e. no fog unless gl_Position.z > defined # (This would slightly effect the fogFactor equation)
  2. The fogDensity should be a param that is defined when using the .j3md file.



    I guess that’s about it… Thanks for listening to me ramble.
1 Like
@t0neg0d said:
Here is a fix to how to compute the fog via a frag shader... The way it is currently, brightness is not taken into effect at all. sooo... vec3(0.4, 0.1, 0.1) would look the same as vec3(1.0, 0.0, 0.0). To make sure the fog is rendered at the actual color you have defined, replace the last gl_FragColor = mix, blah) with:

[java]gl_FragColor.rgb = mix((gl_FragColor.rgb*fogColor.rgb),gl_FragColor.rgb,fogFactor);[/java]


I'm not entirely sure I understand the "vec3(0.4, 0.1, 0.1) would look the same as vec3(1.0, 0.0, 0.0)."... is that the color of the fog or the color of the pixel?

Fog as previously implemented (or at least as implemented in my shaders) is a straight distance-based attenuation. As a point gets farther away, you see less of the point and more of the vapor between you and the point... and I think in that case that coloring the vapor (as you've done) is incorrect.

Can you give a more specific example where things are not what they are supposed to be?

Here’s an example of a problem with your version…



If gl_FragColor.rgb is 1,0,0 and fog color is 1, 1, 1 then even at maximum fog that pixel will still be red… and that’s not right.



With your version it seems there is no distance where fog is completely opaque.

1 Like

@pspeed I caught that right after posting this. I’m trying to find the solution atm. Correct color… or completely opaque. I’d like both! Hopefully it won’t be long now. Or… maybe you have the magic solution already? O.o That would be awesome.

But I don’t even really know what the problem is. You will have to explain it better because the mix() fog looks fine to me.

@pspeed When I tried to use it, blue is blue wether or not you set it to vec4(0, 0, 1, 1) or vec4(0, 0, 0.2, 1)… the mix function in the code at the beginning of this post doesn’t render different brightness of the same color (because of the lack of the alpha channel). Anyways… this one works (As far as I can tell. For some reason, you need to scale to color values of the fog to have it render correctly… so if you have a minute or three to play around with this… do tell me if you see the difference.



[java]fogColor *= 0.1;

fogColor.a = 1-fogFactor;

gl_FragColor.rgb = mix(fogColor,gl_FragColor,fogFactor).rgb;[/java]

Yeah, alpha should not be affected by fog.



Here is what I do in my shader for fog… (I don’t even think about alpha since it’s always forced at the end.)



[java]

#ifndef VERTEX_LIGHTING

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);

#endif



gl_FragColor.a = alpha;

[/java]



As you can see, I use fog color’s alpha to set the fog distance anyway. No reason to waste a uniform after all.



my_z is a varying set to the z value of the vertex in the vert shader.