Unity の HLSL シェーダー:シンプルなカラーシェーダーを実装する
こんにちは、@studio_meowtoon です。今回は Unity でシンプルなカラーシェーダーを実装する方法を紹介します。
実現すること
Unity で HLSL 言語を使用したシンプルなカラーシェーダーを作成します。
HLSL とは?
Unity では、シェーダープログラムを記述するために HLSL というプログラミング言語を使用します。HLSL (High Level Shading Language) は元々はマイクロソフトによって開発された、Direct3D (DirectX) で使われるプログラマブルシェーダーのためのプロプライエタリなシェーディング言語です。
Unity のシェーダーを実装する
Unity における HLSL シェーダーの構造は、以下のようになっています。
// シェーダー名
Shader "Germio/Color"
{
// プロパティセクション
// マテリアルの外部から調整可能なパラメータを定義します。
Properties
{
}
// サブシェーダーセクション
// ここにシェーダーの実際の描画ロジックを記述します。
SubShader
{
}
// フォールバック
// このシェーダーが使用できない場合、
// デフォルトの "Standard" シェーダーを使用します。
Fallback "Standard"
}
次のシェーダーは、Unity のシェーダープログラムで書かれたシンプルなカラーシェーダーです。
// シェーダー名
Shader "Germio/Color"
{
// プロパティセクション
Properties
{
// カスタムプロパティ "_Color" の宣言
_Color("Color", Color) = (1, 1, 1, 1)
}
// サブシェーダーセクション
SubShader
{
// タグの設定: レンダリングキューを透明に設定
Tags { "Queue" = "Transparent" }
// ブレンドモードの設定: アルファブレンド
Blend SrcAlpha OneMinusSrcAlpha
// シェーダーのパスを定義
Pass
{
// パスの名前
Name "COLOR"
// プログラマブルなシェーダーの開始宣言
CGPROGRAM
// 頂点シェーダーの指定
#pragma vertex vert
// フラグメントシェーダーの指定
#pragma fragment frag
// 頂点情報を格納する構造体の宣言
struct appdata
{
// 頂点の座標情報
float4 vertex : POSITION;
};
// 頂点シェーダーからフラグメントシェーダーにデータを渡す構造体の宣言
struct v2f
{
// 頂点のスクリーン座標
float4 pos : SV_POSITION;
};
// 頂点シェーダー関数の宣言
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex); // 頂点位置をクリップ座標に変換
return o;
}
// プロパティで定義されたカラー情報を格納する変数
float4 _Color;
// フラグメントシェーダー関数の宣言
fixed4 frag(v2f i) : SV_Target
{
float4 final_color = _Color; // シェーダーの最終出力カラーを定義
final_color.a = _Color.a; // アルファ値をカスタムプロパティのアルファ値に設定
return final_color; // 最終出力カラーを返す
}
// プログラマブルなシェーダーの終了宣言
ENDCG
}
}
// フォールバック
Fallback "Standard"
}
シェーダーで描画する
Unity 標準の Standard シェーダーで描画した立方体の3Dモデルです。
こちらは今回実装したシンプルなカラーシェーダーで描画した立方体の3Dモデルです。
シェーダーの実装通りに全体が白で描画されています。この段階で重要なことは、シェーダーの基本的な記述方法を学ぶことです。
各セクションの説明
以下、各部分について詳しく説明します。
Shader "Germio/Color"
{
// プロパティセクション
Properties
{
// カスタムプロパティ "_Color" の宣言
_Color("Color", Color) = (1, 1, 1, 1)
}
この部分では、シェーダーのプロパティを定義しています。このシェーダーには "_Color" という名前のプロパティがあり、デフォルトで白色 (1, 1, 1, 1) が設定されています。このプロパティは後でフラグメントシェーダー内で使用されます。
// サブシェーダーセクション
SubShader
{
// タグの設定: レンダリングキューを透明に設定
Tags { "Queue" = "Transparent" }
// ブレンドモードの設定: アルファブレンド
Blend SrcAlpha OneMinusSrcAlpha
SubShader セクションでは、このシェーダーのサブシェーダーを定義しています。"Queue" タグを設定し、レンダリングの優先順位を "Transparent" に設定しています。また、ブレンドモードも設定しており、SrcAlpha と OneMinusSrcAlpha を使用して透明なオブジェクトの描画に適しています。
// シェーダーのパスを定義
Pass
{
// パスの名前
Name "COLOR"
// プログラマブルなシェーダーの開始宣言
CGPROGRAM
// 頂点シェーダーの指定
#pragma vertex vert
// フラグメントシェーダーの指定
#pragma fragment frag
Pass セクションでは、シェーダーのパスを定義しています。このパスの名前は "COLOR" で、CGPROGRAM ブロック内で定義された頂点シェーダーとフラグメントシェーダーが使用されます。
// 頂点情報を格納する構造体の宣言
struct appdata
{
// 頂点の座標情報
float4 vertex : POSITION;
};
appdata 構造体は頂点情報を格納するために使用されます。ここでは、頂点の位置情報を float4 型の変数として定義しています。
// 頂点シェーダーからフラグメントシェーダーにデータを渡す構造体の宣言
struct v2f
{
// 頂点のスクリーン座標
float4 pos : SV_POSITION;
};
v2f 構造体は頂点シェーダーからフラグメントシェーダーにデータを渡すために使用されます。ここでは、頂点の座標情報を float4 型の変数として定義しています。
// 頂点シェーダー関数の宣言
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex); // 頂点位置をクリップ座標に変換
return o;
}
vert 関数は頂点シェーダーで、appdata 構造体から v2f 構造体にデータを変換します。UnityObjectToClipPos 関数を使用して頂点位置をクリップ空間に変換し、v2f 構造体に格納しています。
// プロパティで定義されたカラー情報を格納する変数
float4 _Color;
// フラグメントシェーダー関数の宣言
fixed4 frag(v2f i) : SV_Target
{
float4 final_color = _Color; // シェーダーの最終出力カラーを定義
final_color.a = _Color.a; // アルファ値をカスタムプロパティのアルファ値に設定
return final_color; // 最終出力カラーを返す
}
frag 関数はフラグメントシェーダーで、各フラグメントの最終的な色を計算します。ここでは、プロパティで指定されたカラー情報を使い、アルファ値を変更せずに final_color 変数に格納しています。
// フォールバック
Fallback "Standard"
}
このシェーダーが使用できない場合、デフォルトの "Standard" シェーダーを使用します。
Unity エディタからプロパティを使用
作成したシェーダー(マテリアル)のプロパティは、Unity エディタから設定を変更することが可能です。
まとめ
Unity で HLSL 言語を使用したシンプルなカラーシェーダーを作成することができました。
この記事の実装例は一つのアプローチに過ぎず、必ずしも正しい方法とは限りません。他にも多様な方法がありますので、さまざまな情報を照らし合わせて検討してみてください。
どうでしたか? Window 11 の Unity で3Dゲームを開発する環境を手軽に構築することができます、ぜひお試しください。今後も Unity の開発トピックなどを紹介していきますので、ぜひお楽しみにしてください。
推奨コンテンツ
参考資料