# Glow effect disappears when the camera is near

**URL:** <https://discourse.threejs.org/t/glow-effect-disappears-when-the-camera-is-near/40878>\
**Category:** Questions\
**Tags:** shaders\
**Created:** [July 30, 2022, 12:27pm UTC](https://discourse.threejs.org/t/glow-effect-disappears-when-the-camera-is-near/40878 "2022-07-30T12:27:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![TheHappyKoala](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/thehappykoala/32/6074_2.png) [@TheHappyKoala](https://discourse.threejs.org/u/TheHappyKoala)\
**Post date:** [July 30, 2022, 12:27pm UTC](https://discourse.threejs.org/t/glow-effect-disappears-when-the-camera-is-near/40878/1 "2022-07-30T12:27:35Z")

</div>

I have created a pound shop planetary atmosphere, and while it looks quite good, it disappears when the camera is very close to it, as you can see in the images below.

 ![Screenshot 2022-07-30 at 14.02.05](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/d/0/d02fdbb6991dc4f6561c8cce545571e95edfdc23.jpeg)  
 ![Screenshot 2022-07-30 at 14.02.31](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/d/3/d311cb9911e060efdf14e456b8d6fe7aa7e0b7c5.jpeg)

I would like the atmosphere to be visible when you are close to the planet, too. Here is the shader code:

```javascript
    const Shaders = {
      atmosphere: {
        uniforms: {
          lightPosition: { value: new THREE.Vector3() },
          colour: {
            type: "c",
            value: new THREE.Color(this.mass.atmosphere)
          }
        },
        vertexShader: `
        varying vec3 vPosition;
        varying vec3 vNormal;

        void main() {
          vNormal = normalize( normalMatrix * normal );
          gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
          vPosition = gl_Position.xyz;
        }
        `,
        fragmentShader: `
        varying vec3 vNormal;
        varying vec3 vPosition;
        
        uniform vec3 lightPosition;
        uniform vec3 colour;

        void main() {
          vec3 lightDirection = normalize(lightPosition - vPosition);
          float dotNL = clamp(dot(lightDirection, vNormal), 0.0, 1.0);
          float intensity = pow( 0.8 - dot( vNormal, vec3( 0, 0, 1.0 ) ), 8.0 );
          gl_FragColor = vec4( colour, 1.0 ) * intensity * dotNL;
        }
        `
      }
    };

    const atmosphereMaterial = new THREE.ShaderMaterial({
      uniforms: THREE.UniformsUtils.clone(Shaders["atmosphere"].uniforms),
      vertexShader: Shaders["atmosphere"].vertexShader,
      fragmentShader: Shaders["atmosphere"].fragmentShader,
      side: THREE.BackSide,
      transparent: true
    });

```

I then update the light position, like so:

```javascript
      const atmosphere = massManifestation.getObjectByName("atmosphere");

      if (atmosphere) {
        atmosphere.material.uniforms.lightPosition.value
          .copy(
            this.manifestationsService.manifestations
              .find(manifestation => manifestation.name === "Sun")
              .getObjectByName("main").position
          )
          .applyMatrix4(this.camera.matrixWorldInverse);
      }

```

One solution that I have tried is to make the scale of the atmosphere mesh a function of the distance between it and the camera, and while this kind of works, the transition in scale is not smooth. Basically I set the scale of the mesh to be the ratio of the radius of the mesh and its distance to the camera, i.e r / d.

Any chance anyone could fill me in on how this problem could be addressed?

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [July 31, 2022, 3:46pm UTC](https://discourse.threejs.org/t/glow-effect-disappears-when-the-camera-is-near/40878/2 "2022-07-31T15:46:32Z")

</div>

Maybe your atmosphere mesh gets unintentionally frustum culled. Try to disable view frustum culling like so and see if it helps:

```nohighlight
atmosphere.frustumCulled = false;

```

---

<div class="post-metadata">

**Author:** ![TheHappyKoala](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/thehappykoala/32/6074_2.png) [@TheHappyKoala](https://discourse.threejs.org/u/TheHappyKoala)\
**Post date:** [July 31, 2022, 4:04pm UTC](https://discourse.threejs.org/t/glow-effect-disappears-when-the-camera-is-near/40878/3 "2022-07-31T16:04:08Z")

</div>

Thanks for chiming in. Unfortunately that didn’t do the trick. This [pen](https://codepen.io/motion/pen/xqRmpb) does not take the position of the light source into account, but the same issue occurs. If you set the camera z position vector to 1000, the atmosphere looks super, but when you set it to 400, it’s barely visible.

---

<div class="post-metadata">

**Author:** ![tfoller](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tfoller](https://discourse.threejs.org/u/tfoller)\
**Post date:** [August 1, 2022, 1:56am UTC](https://discourse.threejs.org/t/glow-effect-disappears-when-the-camera-is-near/40878/4 "2022-08-01T01:56:41Z")

</div>

The glow effect here comes from using **normalMatrix** in shader code

```javascript
vNormal = normalize( normalMatrix * normal );

```

that controls the intensity

```javascript
float intensity = 1.0 - vNormal.z;

```

if you zoom in/out here using mouse wheel:

> **[Edit fiddle - JSFiddle - Code Playground](https://jsfiddle.net/tfoller/xntqzu3c/41/)**
>
> Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

you will see that this effect fades out as you get closer to the sphere.

I don’t know what **normalMatrix** does, but judging by other components of **vNormal** that you can see by changing .z to .x or .y in this line:

```javascript
float intensity = 1.0 - vNormal.z

```

it seems to recalculate all geometry normals relative to the camera position, that also depends on distance from the camera to its target.

Maybe there is a way to compensate for that by mixing this distance into the code?

---

<div class="post-metadata">

**Author:** ![tfoller](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tfoller](https://discourse.threejs.org/u/tfoller)\
**Post date:** [August 2, 2022, 2:31am UTC](https://discourse.threejs.org/t/glow-effect-disappears-when-the-camera-is-near/40878/5 "2022-08-02T02:31:14Z")

</div>

It dawned upon me that most likely the reason for this effect to change with distance is that you’re using perspective camera, so you see less and less of a sphere as you get close to it, so the glow can not span across the whole sphere radius.

If you use ortho camera you will always see a half of the sphere and the effect will be unchanged regardless of the distance.

> **[Edit fiddle - JSFiddle - Code Playground](https://jsfiddle.net/tfoller/xntqzu3c/56/)**
>
> Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

To compensate for this you will need to pass camera position as a uniform into the shader and change the intensity but the formula will depend of your camera setup, so it will probably be hard to do.
