3D Fog

I’m wondering if there’s any way to use a shader to generate 3D (volumetric) fog. If I put this code in a Vuo shader image generator (for ex.), it does not generate errors, but is there a way to use it in Vuo? Is there a way for it to get the vertex color and have it respond to a scene with a camera moving around, etc.? I attached a 3D cube grid comp, wish it could work in there to start.

void main()
{
// density of fog
Float density = 0.0005;

// calculation from
// http://www.ozne3d.net/tutorials/glsl_fog/p04.php

const float LOG2 = 1.442695;

float z = gl_FragCoord.z / gl_FragCoord.w;
float fogFactor = exp2( -density * density * z * z * LOG2 );
fogFactor = clamp(fogFactor, 0.0, 1.0);

// mix vertex color with pixel color
vec4 frag_color = vColor * pixel;

// fog color is white
vec4 fog_color = vec4(1,1,1,0);

// mix frag color with fog color
gl_FragColor = mix(fog_color, frag_color, fogFactor);

}

Shader from here: Fog in GLSL (WebGL) | Geeks3D

There’s also this shadertoy which makes it seem like it would be a hack if it worked at all: Shader - Shadertoy BETA

But there’s also the “interface block” concept: How to pass data from shader to shader in OpenGL — Harold Serrano - Game Engine Developer

#version 450 core
//color is an input vertex attribute
layout (location =0) in vec4 color;

//declare COLOROUT as an output interface block
out COLOROUT{
    vec4 color; //send color to next stage
}colorout;

void main(){
//...Shader stuffs here

//output a color to the fragment shader through outcolor;
outcolor.color=vec4(1.0,0.0,0.0,1.0);
}

It would be super cool, maybe using Change All Shaders

gridCubeTest.vuo (8.59 KB)

Noticing gl_FragCoord.z/gl_FragCoord.w…

These are values that would be first setup in the vertex shader. Object(s) would need to have the shader attached as a material. Then there would be some info in the z/w lanes to do something with.

This is part of the reason why I filed a bug report the “shader” protocol, which obscures the connection to the vertex shader, has various “inputs” that aren’t uniforms, and ultimately doesn’t allow creation of the same kind of materials that connect to objects as shaders.

1 Like

Good explanation of gl_FragCoord.z/gl_FragCoord.w, mentioning clip space, camera space, near/far values, etc.

I read it thinking, oh well, then I find things like:

Alternatively, you could just use the projection matrix directly yourself, since fragment shaders can use the same uniforms available to vertex shaders. You can pick the A and B terms directly from that matrix. A = projectionMatrix[2][2], and B = projectionMatrix[3][2].

Which then makes it seem closer to being possible than I first imagined.

I think that with the existing objects you could render a scene to image and then attempt to use the depth channel info to do some similar effects…I can’t remember exactly how the vuo depth image would map to frag.zw offhand, or if it could really be massaged to be identical…but it is similar. Whatever “fog” is created with processed depth channel would have to be composited back with the color image.

Another thing that vuo has is the shader that colors positions, normals, uv, etc. If you setup things do that there is a color pass and a position pass, you can use the position pass info along with filtering to create position based effects and then blend back with the color pass. I think you would want to make sure things are in world coordinate, not local.

The kind of fog referenced in that tutorial is a lot like the QC fog object effect. Not really volumetric, but more of a gradual color effect imposed on rendering over z. That said, there are times when it really makes something pop.

My ignorance – I’d be thrilled with something reasonably close to QC fog. (what exactly is volumetric fog – a vertex shader?)

Great tip on trying the depth image – I forgot all about that!

Another thing that vuo has is the shader that colors positions, normals, uv, etc.

You mean the Vertex Attributes Shader? I’ll have a look.

Maybe there is some hybrid approach to consider here. Maybe a shader could even do some fancier thing with the depth image pixels…  

Well, I didn’t get to the Vertex Attributes Shader because the results were so good using the depth image – wow, hoorah! Can’t believe I overlooked that… No extra shader required, though I could see how a well designed fragment shader could bring a lot. The results are quite beautiful, imo, really just an episode using a bunch of blends and tweaking parameters. Lots of room for custom stuff here. Depth image!! I’ll post to the Composition Gallery, this is worthy.  

1 Like