Sky shaders

Шейдеры неба — это особый тип шейдеров, используемый для отрисовки фонов неба и обновления кубических карт сияния, используемых для освещения на основе изображения (IBL). Шейдеры неба имеют только одну функцию обработки — sky().

Шейдер неба используется в трех местах.

  • Сначала шейдер неба используется для отрисовки неба, когда вы выбираете использование неба в качестве фона в своей сцене.

  • Во-вторых, шейдер неба используется для обновления кубической карты сияния при использовании неба для окружающего цвета или отражений.

  • В-третьих, шейдер неба используется для отрисовки подпроходов с низким разрешением, которые можно использовать в проходе фона с высоким разрешением или кубической карты.

В общей сложности это означает, что шейдер неба может запускаться до шести раз за кадр, однако на практике это число будет значительно меньше, поскольку кубическая карта сияния не требует обновления в каждом кадре, и не все подпроходы будут использоваться. Вы можете изменить поведение шейдера в зависимости от того, где он вызывается, проверив булевы значения AT_*_PASS. Например:

shader_type sky;

void sky() {
    if (AT_CUBEMAP_PASS) {
        // Sets the radiance cubemap to a nice shade of blue instead of doing
        // expensive sky calculations
        COLOR = vec3(0.2, 0.6, 1.0);
    } else {
        // Do expensive sky calculations for background sky only
        COLOR = get_sky_color(EYEDIR);
    }
}

При использовании шейдера неба для отрисовки фона шейдер будет вызван для всех не перекрытых фрагментов на экране. Однако для подпроходов фона шейдер будет вызван для каждого пикселя подпрохода.

При использовании шейдера неба для обновления кубической карты сияния, шейдер неба будет вызываться для каждого пикселя кубической карты. С другой стороны, шейдер будет вызываться только при необходимости обновления кубической карты сияния. Кубическая карта сияния должна обновляться при обновлении любого из параметров шейдера. Например, если в шейдере используется TIME, то кубическая карта сияния будет обновляться в каждом кадре. Следующий список изменений приводит к обновлению кубической карты сияния:

  • Используется TIME.

  • Используется POSITION и положение камеры изменяется.

  • Если используются какие-либо свойства LIGHTX_* и изменяется какой-либо DirectionalLight3D.

  • Если в шейдере изменена какая-либо униформа.

  • Если размер экрана изменен и используется какой-либо из подпроходов.

Старайтесь избегать обновления кубической карты сияния без необходимости. Если вам всё же нужно обновлять кубическую карту сияния в каждом кадре, убедитесь, что для параметра Sky Process Mode установлено значение PROCESS_MODE_REALTIME.

Обратите внимание, что параметр process mode влияет только на рендеринг кубической карты сияния. Видимое небо всегда рендерится путём вызова фрагментного шейдера для каждого пикселя. При использовании сложных фрагментных шейдеров это может привести к высоким накладным расходам. Если небо статично (при соблюдении перечисленных выше условий) или медленно меняется, запуск полного фрагментного шейдера в каждом кадре не требуется. Этого можно избежать, рендеря всё небо в кубическую карту сияния и считывая данные из этой кубической карты при рендеринге видимого неба. В случае полностью статического неба это означает, что его нужно рендерить только один раз.

Следующий код визуализирует все небо в кубической карте сияния и считывает данные из этой кубической карты для отображения видимого неба:

shader_type sky;

void sky() {
    if (AT_CUBEMAP_PASS) {
        vec3 dir = EYEDIR;

        vec4 col = vec4(0.0);

        // Complex color calculation

        COLOR = col.xyz;
        ALPHA = 1.0;
    } else {
        COLOR = texture(RADIANCE, EYEDIR).rgb;
    }
}

Таким образом, сложные вычисления происходят только в проходе кубической карты, который можно оптимизировать, установив режим обработки неба и размер сияния, чтобы получить желаемый баланс между производительностью и визуальной точностью.

Режимы визуализации

Подпроходы позволяют выполнять более ресурсоёмкие вычисления в более низком разрешении, ускоряя шейдеры. Например, следующий код рендерит облака в более низком разрешении, чем остальное небо:

shader_type sky;
render_mode use_half_res_pass;

void sky() {
    if (AT_HALF_RES_PASS) {
        // Run cloud calculation for 1/4 of the pixels
        vec4 color = generate_clouds(EYEDIR);
        COLOR = color.rgb;
        ALPHA = color.a;
    } else {
        // At full resolution pass, blend sky and clouds together
        vec3 color = generate_sky(EYEDIR);
        COLOR = color + HALF_RES_COLOR.rgb * HALF_RES_COLOR.a;
    }
}

Режим рендеринга

Описание

use_half_res_pass

Позволяет шейдеру записывать данные и получать доступ к проходу с половинным разрешением.

use_quarter_res_pass

Позволяет шейдеру записывать данные и получать доступ к проходу разрешения в четверть.

disable_fog

При использовании туман не повлияет на небо.

Встроенные функции

Значения, отмеченные как in, доступны только для чтения. Значения, отмеченные как out, могут быть записаны и не обязательно содержат осмысленные значения. В сэмплеры запись невозможна, поэтому они не отмечены.

Глобальные встроенные функции

Глобальные встроенные функции доступны везде, в том числе и в пользовательских функциях.

Имеется 4 индикатора LIGHTS, доступ к которым осуществляется как LIGHT, LIGHT 1, LIGHT 2 и LIGHT3.

Встроенный

Описание

в плавающем TIME

Global time since the engine has started, in seconds. It repeats after every 3,600 seconds (which can be changed with the rollover setting). It's affected by time_scale but not by pausing. If you need a TIME variable that is not affected by time scale, add your own global shader uniform and update it each frame.

in vec3 POSITION

Положение камеры в мировом пространстве.

samplerCube RADIANCE

Radiance cubemap. Can only be read from during the background pass. Check !AT_CUBEMAP_PASS before using.

in bool AT_HALF_RES_PASS

true when rendering to the half resolution pass.

in bool AT_QUARTER_RES_PASS

true when rendering to the quarter resolution pass.

in bool AT_CUBEMAP_PASS

true when rendering to the radiance cubemap.

in bool LIGHTX_ENABLED

true, если LIGHTX виден и присутствует в сцене. Если false, другие свойства света могут быть неверными.

in float LIGHTX_ENERGY

Множитель энергии для LIGHTX.

in vec3 LIGHTX_DIRECTION

Направление, куда смотрит LIGHTX.

in vec3 LIGHTX_COLOR

Цвет LIGHTX.

in float LIGHTX_SIZE

Угловой диаметр LIGHTX на небе. Выражается в радианах. Для справки, расстояние от Солнца до Земли составляет около 0,0087 радиана (0,5 градуса).

в float PI

A PI constant (3.141592). The ratio of a circle's circumference to its diameter and the number of radians in a half turn.

в float TAU

A TAU constant (6.283185). Equivalent to PI * 2 and the number of radians in a full turn.

В float E

An E constant (2.718281). Euler's number, the base of the natural logarithm.

Встроенные модули Sky

Встроенный

Описание

in vec3 EYEDIR

Normalized direction of the current pixel. Use this as your basic direction for procedural effects.

vec2 SCREEN_UV

Screen UV coordinate for the current pixel. Used to map a texture to the full screen.

in vec2 SKY_COORDS

Сферическая UV-развёртка. Используется для наложения панорамной текстуры на небо.

in vec4 HALF_RES_COLOR

Color value of the corresponding pixel from the half resolution pass. Uses linear filter.

in vec4 QUARTER_RES_COLOR

Color value of the corresponding pixel from the quarter resolution pass. Uses linear filter.

out vec3 COLOR

Цвет на выходе.

out float ALPHA

Выходное альфа-значение может использоваться только в подпроходах.

out vec4 FOG