【Unity】シェーダーグラフを使ったシェーダーのシンプルなサンプル作成
Unityのシェーダーグラフを使用すると、視覚的なノードベースのインターフェースでシェーダーを作成できます。シンプルなサンプルとして、スプライトの点滅効果を作成する場合、Time
ノードを使用して経過時間を取得し、Multiply
ノードで速度を調整します。さらに、Sine
ノードで正弦波を生成し、Remap
ノードで範囲を0から1に変換します。最終的に、Fragment
ノードのアルファ値に接続して、点滅効果を実現します。
注意: 作業はSaveするまで保存されません
スプライト点滅シェーダーの作成手順(Lerpノード使用)
- プロジェクトのセットアップ:
- Unityを起動し、新しいプロジェクトを作成します。
- 「Universal Render Pipeline (URP)」を使用するプロジェクトテンプレートを選択します。
- プロジェクトが作成されたら、URPをインストールしてセットアップします。
- Shader Graphのインストール:
- 「Window」 > 「Package Manager」を開きます。
- 「Unity Registry」から「Shader Graph」を検索し、インストールします。
- Shader Graphの作成:
- プロジェクトビューで右クリックし、「Create」 > 「ShaderGraph」 > 「URP」 > 「Sprite Lit Shader Graph」を選択します。
- 作成されたシェーダーグラフを「BlinkingSpriteShader」などの名前に変更します。
- ダブルクリックしてShader Graphエディタを開きます。
- 点滅効果の追加:
- Main Previewウィンドウの左側にあるノードグラフエリアに「Time」ノードを追加します。
- 右クリックして「Create Node」を選択し、「Time」と検索して追加します。
- 「Time」ノードの「Sine Time」出力を「Lerp」ノードの「T」入力に接続します。
- 右クリックして「Create Node」を選択し、「Lerp」と検索して追加します。
- 「Lerp」ノードの「A」入力に「0」を、そして「B」入力に「1」を入力します。これにより、アルファ値が0から1の間で線形に変化します。
- 「Lerp」ノードの出力を「Fragment」ノードの「Alpha」入力に接続します。
- Main Previewウィンドウの左側にあるノードグラフエリアに「Time」ノードを追加します。
- Graph Settingsの設定:
- MaterialをSprite Litにします
Graph InspectorでUniversal > Sprite Litに設定します
- MaterialをSprite Litにします
- ベースカラーの設定:
- 「Color」ノードを作成し、好きなスプライトの基本色を設定します。
- 「Color」ノードの出力を「Fragment」ノードの「Base Color」入力に接続します。
- シェーダーの適用:
- シェーダーを保存し(Ctrl+S)、Shader Graphエディタを閉じます。
- プロジェクトビューでシェーダーを右クリックし、「Create」 > 「Material」を選択します。
- 作成されたマテリアルに「BlinkingSpriteMaterial」などの名前を付けます。
- 「Inspector」ウィンドウで、このマテリアルの「Shader」プロパティを先ほど作成した「BlinkingSpriteShader」に設定します。
- スプライトへの適用:
- 点滅させたいスプライトをシーンに追加し、そのスプライトの「Sprite Renderer」コンポーネントを選択します。
- 「Material」プロパティを「BlinkingSpriteMaterial」に設定します。
完成したノード構成
- Timeノード: 「Sine Time」出力を使用
- Lerpノード: Timeノードの「Sine Time」出力を「T」に接続し、「A」入力に「0」、そして「B」入力に「1」を設定
- Fragmentノード: Lerpノードの出力を「Alpha」に接続し、Colorノードの出力を「Base Color」に接続
これで、スプライトが点滅するシェーダーが完成しました。Lerpノードを使用することで、点滅の速度や強さをより滑らかに制御できます。
点滅の有効無効をコントロールする
- 点滅の有効・無効をコントロールするためのパラメータの追加:
- Booleanプロパティの追加:
- Blackboardに新しい「Boolean」プロパティを追加し、「_BlinkEnabled」という名前を付けます。
- _BlinkEnabledプロパティをShaderEditor画面にドラッグ&ドロップし、ノードにします
- Branchノードの追加:
- Shader Graphエディタで右クリックして「Create Node」を選択し、「Branch」と検索して追加します。
- ノードの接続:
- Branchノードの「Predicate」入力に_BlinkEnabledノードの出力を接続します。
- Branchノードの「True」入力にはLerpノードの出力を接続し、「False」入力には「1」を接続します。これにより、_BlinkEnabledがtrueのときに点滅効果が有効になります。
- Booleanプロパティの追加:
Booleanプロパティの追加
Blackboardに新しい「Boolean」プロパティを追加し、「_BlinkEnabled」という名前を付けます
_BlinkEnabledプロパティをShaderEditor画面にドラッグ&ドロップし、ノードにします
コードでの使い方
以下のスクリプトを使用して、点滅効果の有効・無効を切り替えます。
using UnityEngine;
public class BlinkController : MonoBehaviour
{
public Material blinkingMaterial;
private bool isBlinking = false;
void Start()
{
// 初期状態で点滅を無効に設定
SetBlinking(false);
}
void Update()
{
// スペースキーを押すと点滅をトグル
if (Input.GetKeyDown(KeyCode.Space))
{
isBlinking = !isBlinking;
SetBlinking(isBlinking);
}
}
void SetBlinking(bool enabled)
{
if (blinkingMaterial != null)
{
blinkingMaterial.SetFloat("_BlinkEnabled", enabled ? 1.0f : 0.0f);
}
}
}
点滅の速度をコントロールする(Sineノード、Remapを利用する)
上記に、速度コントロール用の時間の進み具合を設定速度を時間に掛け算する仕組みでも良いです
ただ、実は不透明後に透明化するのが急すぎる動きになっています
今回は、学習のため、その辺りの仕組みを変更するようにしています
下記に添付されているキャプチャーを参考に差し替え(変更・削除)を行なってみてください
- 点滅の速度をコントロールするためのパラメータの追加:
- Floatプロパティの追加:
- Blackboardに新しい「Float」プロパティを追加し、「_BlinkSpeed」という名前を付けます。
- Graph Inspectorでデフォルト値を1にします
- _BlinkSpeedプロパティをShaderEditor画面にドラッグ&ドロップし、ノードにします
- Multiplyノードの追加:
- Shader Graphエディタで右クリックして「Create Node」を選択し、「Multiply」と検索して追加します。
- ノードの接続:
- Multiplyノードに、
Time
ノードのTime
出力と_BlinkSpeed
ノード(プロパティ)を接続します。
これにより、点滅の速度を制御します。
- Multiplyノードに、
- Sineノードの追加:
- Shader Graphエディタで右クリックして「Create Node」を選択し、「Sine」と検索して追加します。
- ノードの接続
- Sineノードに、Multiplyノードの出力を接続します
これにより、正弦波の値が得られます。
- Sineノードに、Multiplyノードの出力を接続します
- Remapノードの追加:
- Shader Graphエディタで右クリックして「Create Node」を選択し、「Remap」と検索して追加します。
- Sineノードの出力をRemapノードの「In」入力に接続します。
- Remapノードの「In Min」に「-1」を、「In Max」に「1」を設定します。
- Remapノードの「Out Min」に「0」を、「Out Max」に「1」を設定します
これにより、入力値の-1から+1が0から+1に変換されます
アルファ値が0から1なのでこれに対応するためです
- ノードの接続
- Remapノードの出力をBranchノードの入力に接続します。
- Floatプロパティの追加:
コードでの使い方
以下のスクリプトを使用して、点滅効果の有効・無効と点滅速度を調整します。
using UnityEngine;
public class BlinkController : MonoBehaviour
{
public Material blinkingMaterial;
private bool isBlinking = false;
public float blinkSpeed = 2.0f; // 2.0に設定すると、点滅間隔は0.5秒になります
void Start()
{
// 初期状態で点滅を無効に設定
SetBlinking(false);
// 初期速度を設定
UpdateBlinkSpeed(blinkSpeed);
}
void Update()
{
// スペースキーを押すと点滅をトグル
if (Input.GetKeyDown(KeyCode.Space))
{
isBlinking = !isBlinking;
SetBlinking(isBlinking);
}
// 点滅速度を更新
UpdateBlinkSpeed(blinkSpeed);
}
void SetBlinking(bool enabled)
{
if (blinkingMaterial != null)
{
blinkingMaterial.SetFloat("_BlinkEnabled", enabled ? 1.0f : 0.0f);
}
}
void UpdateBlinkSpeed(float speed)
{
if (blinkingMaterial != null)
{
blinkingMaterial.SetFloat("_BlinkSpeed", speed);
}
}
}
参考
Shader Graphのフラグメント(Fragment)について
Shader Graphでは、シェーダーが視覚的に構築されます。その中で、シェーダーの処理は大きく分けて頂点シェーダーとフラグメントシェーダーの二つの段階に分かれます。フラグメントシェーダーは、画面上の各ピクセルに対して色やその他のデータを計算するためのシェーダーです。
フラグメントシェーダー(Fragment Shader):
- フラグメントシェーダーは、画面上の各ピクセル(フラグメント)に対して実行されます。
- シェーダーのこの段階では、頂点シェーダーから受け取ったデータ(例:位置、テクスチャ座標、ライティング情報など)を使用して、最終的なピクセルカラーを計算します。
- 通常、フラグメントシェーダーでは、テクスチャの色の取得やライティング計算、影の計算などが行われます。
Shader Graph内でのフラグメントノードは、これらの計算を視覚的に設定するためのノードで構成されています。例えば、テクスチャサンプルノードやカラー補正ノードなどをフラグメントノードに接続して、最終的なピクセルの色を計算します。
具体的なフラグメントシェーダーの設定は、Shader Graphエディタ内でノードを繋いでいくことで視覚的に行えます。これにより、プログラムコードを書くことなく、直感的にシェーダーを構築できます。
頂点シェーダー(Vertex Shader)について
頂点シェーダーは、シェーダーのパイプラインにおける最初のステージであり、3Dモデルの頂点ごとに実行されるシェーダーです。頂点シェーダーの主な役割は、頂点の位置を変換し、関連するデータ(例:法線、テクスチャ座標など)を計算・補正することです。
具体的には、次のような処理が行われます:
- 頂点の変換:
- 頂点シェーダーでは、モデル空間にある頂点の位置をワールド空間、ビュー空間、そしてクリップ空間へと変換します。これには、通常、モデル行列、ビュー行列、プロジェクション行列を使用します。
- 頂点属性の計算:
- 法線、テクスチャ座標、頂点カラーなど、頂点に関連する他の属性を補正・計算します。これには、ライティング計算のための法線の変換や、アニメーションのための頂点の変形が含まれます。
- データのパススルー:
- フラグメントシェーダーに必要なデータ(例:テクスチャ座標や色)を後続のパイプラインステージに渡します。
Shader Graphを使用すると、頂点シェーダーの処理も視覚的に設定できます。ノードを使って頂点の位置や属性の変換を定義し、最終的な頂点データをフラグメントシェーダーに渡します。
例として、Shader Graphでの頂点シェーダーの処理には以下のようなノードが使用されます:
- Positionノード: 頂点の位置を設定します。
- Normalノード: 頂点の法線を取得・変換します。
- Transformノード: 頂点の座標を異なる空間(例:ローカル、ワールド、ビュー)に変換します。
頂点シェーダーは、最終的にフラグメントシェーダーでのピクセルごとの詳細な処理の前段階として、頂点レベルでの基本的な変換とデータの準備を行います。
ディスカッション
コメント一覧
まだ、コメントがありません