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.
I would like the atmosphere to be visible when you are close to the planet, too. Here is the shader code:
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:
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?