Cheap misty effect

Hi community!
Here is a picture:


And there is a working demo:

The idea is to use functionality of clipping planes, with some modifications of the code for clipping :slight_smile: Now it’s not clipping, but interpolation between values of 0 and the depth of fog, using distance from a point to the plane.

Looks fine when the camera is above the plane, but when it goes down below, then you can see what’s the trick.

UPD #1
The example that doesn’t break functionality of clipping planes:

17 Likes

Very nice :ok_hand:

1 Like

very good, its so cool that you make it,

That is exactly what i looking for, good performance and easy use,

thank you very very much

1 Like

@x1911 You’re welcome :beers:
But keep in mind, that the approach from this example breakes functionality of clipping planes :slight_smile:

em… is any other way can keep the function of clipping planes?

because I still need it for the UI scroll

@x1911
I’ve updated the main post with a new example :slight_smile: Can’t say it’s elegant :slight_smile:

@prisoner849
so sweet, thank you,
Im going to try first, and report later : :stuck_out_tongue_winking_eye:

is this working still? i only get a blank screen for some reason.

The second codepen, from UPD #1 section, is working.

codepen is acting up, i tried both but now it works. :man_shrugging:

is it possible to make this generic, like standard fog? it seems here i have to mutate all materials, traverse models and so on.

It looks like function getFoggyMaterial simply extends MeshStandardMaterial… I don’t see a traverse method in the second pen, maybe I’m missing it, there’s a for loop that just creates a sphere and adds it to the scene each iteration…

it seems to create a material with an onBeforeCompile, if you had a model (say, GLTFLoader) i’m guessing you would have to traverse and apply oBC on each material, unless you change the prototype of all (?) materials, which would pose other problems since oBC is overwritten. this is what i meant with generic. with fog or fogexp2 it just works, no mesh or material has to be prepared in a specific way, i was hoping the same could be possible here.

Ah yeah i see what you mean @drcmda ,

this is tricky as in the example it is the actual material being affected by the fog itself, whereas ( afaiu ) fog and fogexp2 act like a dithered far clipping plane similar to the cameras clipping plane, whereby everything beyond a certain distance is simply swollowed by the fog itself…

i have tried my best to use @prisoner849’s example and extend MeshStandardMaterial similarly to how you have done with dreis MTM, see here…

and here’s a link to the MeshFoggyMaterial on github (excuse the file naming missmatch)…

this seems to work well but not sure how well it would stand up with the (const property in this) loop, this may need some expert attention to make fully workable with all properties of MeshStandardMaterial

i think the main hinderance is that in a real world project you have all kinds of materials, basic, standard, lambert, phong, physical, transmission, or any custom material. the inclusion of the fog import shader chunk should be enough for things to just work.

the same was done with pcss drei/softShadows.tsx at d7b88a50c6bb71475ac3bc33d66d9bed50e2c5f0 · pmndrs/drei · GitHub it overwrites the shaderchunk, which isn’t nice but cleaner than requiring all materials to be of a specific type, and fully reversible.

can a similar thing be undertaken with ground fog?

though i really don’t know how fog works, or how there can be fog and fogexp2 without having to prep shaders for it.

SimonDev’s YT video on fog might be of interest to this discussion:
https://youtu.be/k1zGz55EqfU

3 Likes

right yeah i see what you mean, i’m not sure what would be needed to replace parts of the MeshStandardMaterial’s THREE.ShaderChunk.clipping_planes_fragment and THREE.ShaderChunk.fog_fragment to make this work the way you suggest as both chunks are dependent on the planeFog float which is derived from one uniform… fPlane

I’m guessing this…

shader.fragmentShader = shader.fragmentShader.replace(
    `#include <clipping_planes_fragment>`,
    `#include <clipping_planes_fragment>
    float planeFog = 0.0;
    planeFog = smoothstep(0.0, -fDepth, dot( vViewPosition, fPlane.xyz) - fPlane.w);
    `
);
shader.fragmentShader = shader.fragmentShader.replace(
    `#include <fog_fragment>`,
    `#include <fog_fragment>
    gl_FragColor.rgb = mix( gl_FragColor.rgb, fColor, planeFog );
    gl_FragColor.a = 1.0 - planeFog;
    `
)

would have to be reformatted in respects of this…

THREE.ShaderChunk.clipping_planes_fragment = THREE.ShaderChunk.clipping_planes_fragment.replace(
    '#endif\n#endif;',
    `#endif\n#endif;\n 
    float planeFog = 0.0;\n
    float fDepth = `+this.uniforms.fDepth.value+`;\n
    vec4 fPlane = vec4(` +
        [
            this.uniforms.fPlane.value.x,
            this.uniforms.fPlane.value.y,
            this.uniforms.fPlane.value.z,
            100.0
        ].join() +
    `);\n
    planeFog = smoothstep(0.0, -fDepth, dot( vViewPosition, fPlane.xyz) - fPlane.w);\n
    `
)

THREE.ShaderChunk.fog_fragment = THREE.ShaderChunk.fog_fragment.replace(
    'gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif',
    `gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n
    float planeFog = 0.0;\n
    float fDepth = `+this.uniforms.fDepth.value+`;\n
    vec4 fPlane = vec4(` +
        [
            this.uniforms.fPlane.value.x,
            this.uniforms.fPlane.value.y,
            this.uniforms.fPlane.value.z,
            100.0
        ].join() +
    `);\n
    planeFog = smoothstep(0.0, -fDepth, dot( vViewPosition, fPlane.xyz) - fPlane.w);\n
    vec3 fColor = vec3(` +
        [
            this.uniforms.fColor.value.r,
            this.uniforms.fColor.value.g,
            this.uniforms.fColor.value.b
        ].join() +
    `);\n
    gl_FragColor.rgb = mix( gl_FragColor.rgb, fColor, planeFog );\n
    `
)

just seen this which may be along the lines you’re suggesting? https://8vko5q-5174.csb.app/

2 Likes

that’s beautiful! where did you find that? so this is just a plane with a material? shaders will always be magic to me. :exploding_head:

ps given that it’s open source and all i hope the author is OK with us adding it to drei with credits.

It’s a really lovely solution. Here’s the original source I spotted in the wild, it’s definitely worth asking if using its OK :wink:

EDIT:

Just had a look on android, it’s a little buggy but could be ironed out maybe?

the amazing @N8Three just created this

its a screen space shader material that can still use the planes whereabouts to calculate fog whereabouts.

3 Likes