Skyシェーダー

Skyシェーダーは空の背景を描画したり、Image-Based lighting (IBL) に使用される放射キューブマップを更新したりするために使用される特別なタイプのシェーダです。 Skyシェーダーには sky() 関数という 1 つのプロセッサー関数しかありません。

Skyシェーダが使用される場所は3つあります。

  • まずシーンの背景にSkyを使用することを選択した場合、Skyシェーダーを使用して空を描画します。

  • 2番目にアンビエントカラーまたは反射にSkyを使用するときに、Skyシェーダーを使用して放射キューブマップが更新されます。

  • 3番目にSkyシェーダーを使用して、高解像度の背景またはキューブマップパスで使用できる低解像度のサブパスを描画します。

これは合計でSkyシェーダーがフレームごとに最大6回実行できることを意味しますが、放射キューブマップはフレームごとに更新する必要がなく、すべてのサブパスが使用されるわけではないため、実際にはそれよりも少なくなります。 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);
    }
}

Skyシェーダーを使用して背景を描画する場合、画面上のオクルージョンされていないすべてのフラグメントに対してシェーダが呼び出されます。ただし背景のサブパスの場合、シェーダはサブパスのピクセルごとに呼び出されます。

Skyシェーダーを使用して放射キューブマップを更新する場合、Skyシェーダーはキューブマップ内のすべてのピクセルに対して呼び出されます。一方、シェーダーは放射キューブマップを更新する必要がある場合にのみ呼び出されます。いずれかのシェーダパラメーターが更新されると、放射キューブマップも更新する必要があります。たとえばシェーダーで TIME が使用されている場合、放射キューブマップはフレームごとに更新されます。次の変更のリストに応じて放射キューブマップの更新が強制されます。

  • TIME が使われている。

  • POSITION が使われており、カメラの位置が変更された場合。

  • LIGHTX_* プロパティが使用されており、いずれかの DirectionalLight3D が変更された場合。

  • シェーダー内のUniformが変更された場合。

  • 画面のサイズが変更され、いずれかのサブパスが使用される場合。

Try to avoid updating the radiance cubemap needlessly. If you do need to update the radiance cubemap each frame, make sure your Sky process mode is set to PROCESS_MODE_REALTIME.

プロセスモード は、放射キューブマップのレンダリングにのみ影響することに注意してください。可視範囲の空はピクセルごとにフラグメントシェーダーを呼び出すことによって常にレンダリングされます。複雑なフラグメントシェーダを使用すると、レンダリングのオーバーヘッドが高くなる可能性があります。空が静的である (上記の条件が満たされている) か、ゆっくりと変化する場合フレームごとにフルのフラグメントシェーダーを実行する必要はありません。これは、全ての空を放射キューブマップにレンダリングし、可視範囲の空をレンダリングするときにこのキューブマップから読み取ることで回避できます。完全に静的な空の場合は、レンダリングする必要があるのは 1 回だけであることを意味します。

次のコードは全ての空を放射キューブマップにレンダリングし、そのキューブマップから読み取って可視範囲の空を表示します。

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

シェーダーが1/2解像度パスに書き込み、アクセスできるようにします。

use_quarter_res_pass

シェーダが1/4解像度パスに書き込み、アクセスできるようにします。

disable_fog

指定すると、フォグは空に影響を与えません。

ビルトイン

Values marked as in are read-only. Values marked as out can optionally be written to and will not necessarily contain sensible values. Samplers cannot be written to so they are not marked.

グローバルビルトイン

グローバルビルトインはカスタム関数を含めあらゆる場所で使用できます。

4つの LIGHTX ライトがあり、 LIGHT0LIGHT1LIGHT2LIGHT3 としてアクセスします。

ビルトイン

説明

in float 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

放射キューブマップ。背景パス中でのみ読み取ることができます。使用前に !AT_CUBEMAP_PASS をチェックしてください。

in bool AT_HALF_RES_PASS

true when rendering to half resolution pass.

in bool AT_QUARTER_RES_PASS

true when rendering to quarter resolution pass.

in bool AT_CUBEMAP_PASS

true when rendering to radiance cubemap.

in bool LIGHTX_ENABLED

true if LIGHTX is visible and in the scene. If false, other light properties may be garbage.

in float LIGHTX_ENERGY

LIGHTX のエネルギー倍率。

in vec3 LIGHTX_DIRECTION

LIGHTX が向いている方向。

in vec3 LIGHTX_COLOR

LIGHTX の色。

in float LIGHTX_SIZE

空における LIGHTX の角直径でラジアンで表されます。参考までに地球からの太陽の距離は約 0.0087 ラジアン (0.5 度) です。

in float PI

PI 円周率の定数 (3.141592)。円の円周とその直径の比率、および半回転のラジアン量。

in float TAU

定数 TAU` は円周率の2倍 (6.283185)。 PI * 2 と、1回転のラジアン量に相当します。

in float E

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

Skyビルトイン

ビルトイン

説明

in vec3 EYEDIR

現在のピクセルの正規化された方向。これをプロシージャルエフェクトのベースの方向として使用します。

in vec2 SCREEN_UV

現在のピクセルのスクリーンUV座標。テクスチャを全画面にマッピングするために使用されます。

in vec2 SKY_COORDS

スフィアUV座標。パノラマテクスチャを空にマッピングするために使用されます。

in vec4 HALF_RES_COLOR

1/2解像度パスからの対応するピクセルの色。リニアフィルターを使用。

in vec4 QUARTER_RES_COLOR

1/4解像度パスからの対応するピクセルの色。リニアフィルターを使用。

out vec3 COLOR

出力の色。

out float ALPHA

出力のアルファ値。サブパスでのみ使用できます。

out vec4 FOG