Unity - URPのShader Graphで雲が流れるSkyboxを作る
UnityのURPでProcedural skyboxに雲を足したものが欲しくて作り方を調べたが、情報が少ない感じだったので書く。
環境
- Unity: 2020.3.26f1 Personal
- Universal RP: 10.8.1
- Shader Graph: 10.8.1
できあがりイメージ
- 太陽 … 割と情報ありそうだったのでこの記事ではおまけ。
- 空 … 天頂付近・中空・地平線付近・地面の4層で個別に色を指定し、各層の間でグラデーションさせる。
- 雲 … Noiseノードを使って生成する(テクスチャファイルを使わない)。
ShaderGraph
(画像のリンク先はGoogleDrive*1。700KBくらい。)
プロパティ設定例
完成品.unitypackage
手元の環境で動くのか手っ取り早く確認するための完成品パッケージ。
チュートリアルをやり切ってから動かないことが分かるとつらい。
CloudySkyboxShaderSample.unitypackage (47KBくらい) - Google ドライブ
各要素の補足
太陽
- 実装は最低限。
Bloom
で光り、Directional Light
のRotation
で傾きを制御できる。- 日の傾きによる光の強弱や色の変化などには対応していない。
参考リンクでそれらを含めて実装できるチュートリアルを紹介している。 - 太陽を描画する方角と色を求めるために
Custom Function
ノードを使う。
中身はこんな感じ。
HLSL部分:
#ifdef SHADERGRAPH_PREVIEW Direction = float3(0.5, 0.5, 0); Color = 1; #else Light light = GetMainLight(); Direction = light.direction; Color = light.color; #endif
空
- 天頂付近で空が深く、濃くなるようにしたかったのでグラデーションを4層にした。
4層だとLerp
が使えないので、Minimum
やSubtract
で各層の差分を取って色を付け、重ね直すというやり方をしている。
もっといい方法があるかもしれない。
雲
雲は
Simple Noise
とGradient Noise
で生成する。
Gradient Noise
(1つめ)で雲の発生パターン、Simple Noise
とGradient Noise
(2つめ)で雲の表面パターンを作る。
Gradient Noise
(2つめ)は雲の位置とずらして生成することで、雲が移動するにつれて形を変えていく感じにした。
ただ、雲の流れを早くしたり、ずっと同じ場所を見つめたりしているとNoiseのパターンが見えてしまう。雲の移動はC#スクリプトで制御する。
ShaderGraph側のClouds Offset
プロパティに_CloudsOffset
というReferenceを割り当て、それをC#スクリプト側から制御するようにした。
MoveClouds.cs:
using UnityEngine; public class MoveClouds : MonoBehaviour { public Vector4 _cloudsSpeed = new Vector4(0.5f, 0.5f); private const string CLOUDS_OFFSET = @"_CloudsOffset"; private void Update() { var skybox = RenderSettings.skybox; Vector4 current = skybox.GetVector(CLOUDS_OFFSET); Vector4 next = current + (_cloudsSpeed * Time.deltaTime); skybox.SetVector(CLOUDS_OFFSET, next); } }
参考リンク
Unity ShaderGraph Procedural Skybox Tutorial Pt.1 – Coster-Graphics
ShaderGraphでSkyboxを作るチュートリアル。
ShaderGraphの作り方から、空、太陽、テクスチャを使った雲や星空など、SkyboxShaderの作成に必要な知識を体系的に学べる。また、Pt.2ではC#スクリプトを使って
Directional Light
(太陽)を回転させ、その傾きに応じて光の色や強度を変化させたり、朝や深夜など特定のタイミングでUnityEventを発生させるといった、より踏み込んだ内容も含まれている。Unity2019時点で執筆されたものだが、Unity2020.3でも動作した。
(ShaderGraph上のノードのプレビューイメージがやや異なるが)
*1:このブログだと大きい画像は自動で縮小されるのでフォントがつぶれてしまう