# Cheap misty effect

**URL:** <https://discourse.threejs.org/t/cheap-misty-effect/6153>\
**Category:** Resources\
**Tags:** fragment-shader, clipping-planes\
**Created:** [February 15, 2019, 2:40pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153 "2019-02-15T14:40:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [February 15, 2019, 2:40pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/1 "2019-02-15T14:40:03Z")

</div>

Hi community!  
Here is a picture:

 ![Cheap%20misty%20fog%20effect](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/f/f238724ccc247f71a627a1a7071de530434f91f8.png)  
And there is a working demo:  
https://codepen.io/prisoner849/embed/preview/bzmrNm?height=300&slug-hash=bzmrNm&default-tabs=js,result&host=https://codepen.io

The idea is to use functionality of clipping planes, with some modifications of the code for clipping 🙂 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:  
https://codepen.io/prisoner849/embed/preview/gOPVeRv?height=300&slug-hash=gOPVeRv&default-tabs=js,result&host=https://codepen.io

---

<div class="post-metadata">

**Author:** ![looeee](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/looeee/32/59_2.png) [@looeee](https://discourse.threejs.org/u/looeee)\
**Post date:** [February 15, 2019, 4:04pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/2 "2019-02-15T16:04:24Z")

</div>

Very nice 👌

---

<div class="post-metadata">

**Author:** ![x1911](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/x1911/32/2976_2.png) [@x1911](https://discourse.threejs.org/u/x1911)\
**Post date:** [July 31, 2020, 2:50pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/3 "2020-07-31T14:50:43Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [July 31, 2020, 5:46pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/4 "2020-07-31T17:46:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![x1911](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/x1911/32/2976_2.png) [@x1911](https://discourse.threejs.org/u/x1911)\
**Post date:** [August 1, 2020, 12:18pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/5 "2020-08-01T12:18:11Z")

</div>

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

because I still need it for the UI scroll

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [August 1, 2020, 3:55pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/6 "2020-08-01T15:55:33Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![x1911](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/x1911/32/2976_2.png) [@x1911](https://discourse.threejs.org/u/x1911)\
**Post date:** [September 14, 2020, 11:02am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/7 "2020-09-14T11:02:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [March 21, 2023, 7:44am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/8 "2023-03-21T07:44:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [March 21, 2023, 7:50am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/9 "2023-03-21T07:50:15Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [March 21, 2023, 7:57am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/10 "2023-03-21T07:57:26Z")

</div>

codepen is acting up, i tried both but now it works. 🤷‍♂️

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

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [March 21, 2023, 9:39am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/12 "2023-03-21T09:39:23Z")

</div>

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…

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [March 21, 2023, 9:56am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/13 "2023-03-21T09:56:58Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [March 21, 2023, 2:49pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/15 "2023-03-21T14:49:24Z")

</div>

Ah yeah i see what you mean @drcmda ,

> [@drcmda](#):
>
> no mesh or material has to be prepared in a specific way

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…

https://codepen.io/forerunrun/embed/preview/ExedZaE?default-tabs=js%2Cresult&height=300&host=https%3A%2F%2Fcodepen.io&slug-hash=ExedZaE

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

> <https://github.com/forerunrun/extends/blob/babfae178521cdfa60b245c8e77bc7c495763b2e/MeshFogMaterial.js>

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`

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [March 21, 2023, 3:04pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/16 "2023-03-21T15:04:30Z")

</div>

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](https://github.com/pmndrs/drei/blob/d7b88a50c6bb71475ac3bc33d66d9bed50e2c5f0/src/core/softShadows.tsx#L147-L153) 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.

---

<div class="post-metadata">

**Author:** ![oldsegotia](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/oldsegotia/32/22601_2.png) [@oldsegotia](https://discourse.threejs.org/u/oldsegotia)\
**Post date:** [March 21, 2023, 3:55pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/17 "2023-03-21T15:55:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [March 21, 2023, 4:49pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/18 "2023-03-21T16:49:50Z")

</div>

> [@drcmda](#):
>
> requiring all materials to be of a specific type

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…

```javascript
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…

```javascript
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
    `
)

```

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [April 18, 2023, 12:25am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/19 "2023-04-18T00:25:30Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [April 18, 2023, 7:18am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/20 "2023-04-18T07:18:05Z")

</div>

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

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

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [April 18, 2023, 8:06am UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/21 "2023-04-18T08:06:49Z")

</div>

It’s a really lovely solution. Here’s the original [source](https://twitter.com/LongSto10058277/status/1648036437579690005?t=nI458Ited8dKEpSkpnV6kw&s=19) I spotted in the wild, it’s definitely worth asking if using its OK 😉

EDIT:

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

 ![Screenshot_20230418_090920](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/2/0/20d46c385e6f1b4dcf4989e1de990a80b7fb6e8e.jpeg)

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [April 18, 2023, 10:01pm UTC](https://discourse.threejs.org/t/cheap-misty-effect/6153/22 "2023-04-18T22:01:24Z")

</div>

the amazing @N8Three just created this

> **[admiring-wildflower-n8ivgz - CodeSandbox](https://codesandbox.io/s/lucid-matan-r4jwon?file=%2Fsrc%2FApp.js)**
>
> admiring-wildflower-n8ivgz using @react-three/drei, @react-three/fiber, @types/three, leva, react, react-dom, react-scripts, three

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

[Next page](https://discourse.threejs.org/t/cheap-misty-effect/6153.md?page=2)
