However this is a 2D effect that doesn't take into account the camera up vector, nor fov.

If you want to draw a sky in 3D, then you have to draw the on the back plane of the normalized device space. The normalized device space is is a cube with the left, bottom near of (-1, -1, -1) and the right, top, f ar of (1, 1, 1).

The back plane is the quad with:

bottom left: -1, -1, 1 bottom right: 1, -1, 1 top right: -1, -1, 1 top left: -1, -1, 1

Render this quad. Note, the vertex coordinates have not to be transformed by any matrix, because the are normalized device space coordinates. But you have to transform the ray which is used for the sky (the direction which is passed to atmosphere ).

This ray has to be a direction in world space, from the camera position to the the sky. By the vertex coordinate of the quad you can get a ray in normalized device space. You have tor transform this ray to world space. The inverse projection matrix ( MATRIX_PROJECTION ) transforms from normalized devices space to view space and the inverse view matrix ( MATRIX_VIEW ) transforms form view space to world space. Use this matrices in the vertex shader:

attribute vec3 in_Position; varying vec3 v_world_ray; void main() { gl_Position = vec4(inPos, 1.0); vec3 proj_ray = vec3(inverse(gm_Matrices[MATRIX_PROJECTION]) * vec4(inPos.xyz, 1.0)); v_world_ray = vec3(inverse(gm_Matrices[MATRIX_VIEW]) * vec4(proj_ray.xyz, 0.0)); }

In the fragment shader you have to rotate the ray by 90° around the x axis, but that is just caused by the way the ray is interpreted by function atmosphere :