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 ライトがあり、 LIGHT0 、 LIGHT1 、 LIGHT2 、 LIGHT3 としてアクセスします。
ビルトイン |
説明 |
|---|---|
in float TIME |
Global time since the engine has started, in seconds. It repeats after every |
in vec3 POSITION |
ワールド空間内のカメラの位置。 |
samplerCube RADIANCE |
放射キューブマップ。背景パス中でのみ読み取ることができます。使用前に |
in bool AT_HALF_RES_PASS |
|
in bool AT_QUARTER_RES_PASS |
|
in bool AT_CUBEMAP_PASS |
|
in bool LIGHTX_ENABLED |
|
in float LIGHTX_ENERGY |
|
in vec3 LIGHTX_DIRECTION |
|
in vec3 LIGHTX_COLOR |
|
in float LIGHTX_SIZE |
空における |
in float PI |
|
in float TAU |
定数 TAU` は円周率の2倍 ( |
in float E |
An |
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 |