Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Шейдери неба

Шейдери неба — це особливий тип шейдерів, який використовується для малювання фону неба та для оновлення кубичних карт радіації, які використовуються для освітлення на основі зображень (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);
    }
}

Під час використання шейдера неба для малювання фону, шейдер буде викликано для всіх незакритих фрагментів на екрані. Однак для фонових підпроходів шейдер буде викликано для кожного пікселя підпроходу.

Під час використання шейдера неба для оновлення кубічної карти сяйва шейдер неба буде викликаний для кожного пікселя в кубічній карті. З іншого боку, шейдер буде викликаний лише тоді, коли потрібно буде оновити карту радіансу cubemap. Коли оновлюється будь-який із параметрів шейдера, необхідно оновлювати кубічну карту сяйва. Наприклад, якщо в шейдері використовується 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;
    }
}

Таким чином, складні обчислення відбуваються лише в проході кубічної карти, який можна оптимізувати, встановивши для неба process mode і radiance size, щоб отримати бажаний баланс між продуктивністю і візуальна точність.

Режими візуалізації

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

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, доступ до яких здійснюється як LIGHT0, LIGHT 1, LIGHT 2 і LIGHT 3.

Вбудований

Опис

In float TIME

Глобальний час з моменту запуску двигуна, у секундах. Повторюється кожні 3600 секунд (що можна змінити за допомогою налаштування rollover). На нього впливає time_scale, але не пауза. Якщо вам потрібна змінна TIME, на яку не впливає шкала часу, додайте власну global shader uniform та оновлюйте її кожного кадру.

In vec3 POSITION

Розташування камери у світовому просторі.

samplerCube RADIANCE

Кубомапа Radiance. Можна зчитувати лише під час фонового проходження. Перед використанням перевірте !AT_CUBEMAP_PASS.

In bool AT_HALF_RES_PASS

true під час рендерингу в проході з половинною роздільною здатністю.

In bool AT_QUARTER_RES_PASS

true при рендерингу на чверть роздільної здатності.

In bool AT_CUBEMAP_PASS

true під час рендерингу на кубічну карту сяйва.

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

Константа типу PI (3,141592). Відношення довжини кола до його діаметра та кількість радіан за півоберту.

у float TAU

Константа типу TAU (6.283185). Еквівалентна PI * 2 та кількості радіан у повному оберті.

у float E

Константа E (2.718281). Число Ейлера, основа натурального логарифма.

Sky вбудовані

Вбудований

Опис

In vec3 EYEDIR

Нормалізований напрямок поточного пікселя. Використовуйте його як основний напрямок для процедурних ефектів.

In vec2 SCREEN_UV

UV-координата екрану для поточного пікселя. Використовується для відображення текстури на весь екран.

In vec2 SKY_COORDS

Сфера УФ. Використовується для нанесення текстури панорами на небо.

In vec4 HALF_RES_COLOR

Значення кольору відповідного пікселя з проходу половинної роздільної здатності. Використовується лінійний фільтр.

In vec4 QUARTER_RES_COLOR

Значення кольору відповідного пікселя з чверть пропускної здатності. Використовується лінійний фільтр.

Out vec3 COLOR

Виведіть колір.

Out float ALPHA

Вихідне значення альфа, можна використовувати лише в підпрограмах.

Out vec4 FOG