Однако это двумерный эффект, который не учитывает вектор включения камеры и fov.
Если вы хотите нарисовать небо в 3D, то вы должны нарисовать на обратной плоскости нормализованного пространства устройства. Нормализованное пространство устройства - это куб с левой, нижней частью рядом с (-1, -1, -1) и правой верхней частью, f ar (1, 1, 1).
Задняя плоскость - это quad with:
bottom left: -1, -1, 1
bottom right: 1, -1, 1
top right: -1, -1, 1
top left: -1, -1, 1
Отобразить этот квад. Обратите внимание, что координаты вершины не должны быть преобразованы какой-либо матрицей, потому что это нормализованные координаты пространства устройства. Но вы должны преобразовать луч, который используется для неба (направление, которое передается в atmosphere
).
Этот луч должен быть направлением в мировом пространстве, от положения камеры к небу. По координате вершины квадра можно получить луч в нормированном пространстве устройства. Вы должны превратить этот луч в мировое пространство. Матрица обратной проекции (MATRIX_PROJECTION
) преобразуется из нормализованного пространства устройств в пространство просмотра, а матрица обратной проекции (MATRIX_VIEW
) преобразует пространство вида в мировое пространство. Используйте следующие матрицы в вершинном шейдере:
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));
}
В фрагментном шейдере вы должны повернуть луч на 90 ° вокруг оси x, но это вызвано только тем, как луч интерпретируется функцией atmosphere
:
varying vec3 v_world_ray;
// [...]
void main() {
vec3 world_ray = vec3(v_world_ray.x, v_world_ray.z, -v_world_ray.y);
vec3 color = atmosphere(
normalize( world_ray.xyz ), // normalized ray direction
vec3(0,6372e3,0), // ray origin
u_sunPosition, // position of the sun
22.0, // intensity of the sun
6371e3, // radius of the planet in meters
6471e3, // radius of the atmosphere in meters
vec3(5.5e-6, 13.0e-6, 22.4e-6), // Rayleigh scattering coefficient
21e-6, // Mie scattering coefficient
8e3, // Rayleigh scale height
1.2e3, // Mie scale height
0.758 // Mie preferred scattering direction
);
// Apply exposure.
color = ACESFilm( color );
fragColor = vec4(color.rgb, 1.0);
}
![](https://i.stack.imgur.com/b68js.gif)