はるのゲーム開発メモ

自分の勉強の成果などをメモ代わりにします

UnityのShader勉強3 外部からの入力

 

今回は外部から値を入力してみます。

モデルごとに色を変えたり、頂点のずらす量、使用するテクスチャなどを与えることができます。

値を入力するにはProperties{}を使います。

前回のコードに加えてみます。

Shader "Unlit/TestShader"
{
	Properties{
      //ここに外部から何を入れるか決める
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			struct appdata
			{
				float4 vertex : POSITION;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
			};

			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				return o;
			}
			
			fixed4 frag () : SV_Target
			{
				fixed4 col = fixed4(1,0,0,1);
				return col;
			}
			ENDCG
		}
	}
}

 

入力する値は

Properties{
	_Texture("Texture",2D)="white"{}
	_Float("float",float) = 1
	_Color("Color",Color) = (1,1,1,1)
	_Range("Range",Range(0,10))=0.5
	_Vector("ector",Vector)=(0,0,0,0)
}

このように書きます。

テクスチャの種類は2DのほかにCube,3Dとあるのですがまだ使っていないので省略します。

これをマテリアルから見てみると

f:id:Haru_android:20171216014344p:plain

こんな感じになりました。

それぞれの意味については特に説明もいらないと思います。

 

書きかたにはとても癖があり

例えば

_Float("float",float)=1

の場合

_Float 変数名
"float" インスペクター上の名前
float
=1 入力する初期値

となります。

非常にややこしいです。

 

ちなみにCGPROGRAM~ENDCG外では;はつけません。

こういうところがわかりずらいです。

 

さて入力できたのですがこのままでは使えません。

まずは使えるようにします。

Shader "Unlit/TestShader"
{
	Properties{
		_Texture("Texture",2D)="white"{}
		_Float("float",float) = 1
		_Color("Color",Color) = (1,1,1,1)
		_Range("Range",Range(0,10))=0.5
		_Vector("ector",Vector)=(0,0,0,0)
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			sampler2D _Texture;
			fixed _Float;
			fixed4 _Color;
			fixed _Range;
			fixed4 _Vector;
struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag () : SV_Target { fixed4 col = fixed4(1,0,0,1); return col; } ENDCG } } }

 

CGPROGRAM~ENDCG内に上記のように記述します。

uniform修飾子をつけるとかいてあるブログもありましたが、公式をみると必須ではないようです。

記述方法は

Propertiesで宣言した変数名と同じ変数で新たに宣言します。

 

テクスチャの場合はsampler2D

_Float,、_Rangeは値が一つなのでfixedなど

_Color、_Vectorは値が四つあるのでfixed4などと記述しましょう

 

これで外部から入力した値を使用することができるようになりました。

 

今回は入力した色でモデルを塗ってみます。

frag関数の

fixed4 col=(1,0,0,1);

fixed4 col=_Color;

 

と書き換えてみます。

f:id:Haru_android:20171216020715p:plain

無事に入力した色でモデルを塗ることができました。

 

続いて、すこし頂点もずらしてみます。

 

まずは変換前の頂点をずらしてみます。

vert関数を

v2f o;
o.vertex = UnityObjectToClipPos(v.vertex); return o;

v2f o;
float4 ver = v.vertex;
ver.x += _Range;
o.vertex = UnityObjectToClipPos(ver);
return o;

と書き換えてみます。

f:id:Haru_android:20171216022336p:plain

 

ずれましたね。

UnityChanが逆に動いているのはもともと後ろを向いているのを反転させているからです。(目と髪の一部はちがう動きをしていますが、不明です。別パーツだから元の向きがちがうのかな?でもEditor上ではちゃんと動いてるのに...)

またCanvasのImageはずれません。

 

次に変換後にずらしてみます。

ためしに_Rangeではなく_Vectorでずらしてみます。

vert関数を

v2f o;
float4 ver = v.vertex;
o.vertex = UnityObjectToClipPos(ver);
o.vertex += _Vector; return o;

と書き換えてみます。

f:id:Haru_android:20171216023623p:plain

真上から見た写真です。

わかりずらいですが、カメラをどこから向けてもカメラに対した向きに動きます。

 

xで左右に、yで上下に、zで前後、wでカメラに近づいたり離れたり。

これは実際にやって見て気づいたのですが、

y軸のみ加算で下へモデルは動き、Imageは上に動きました。

 

調べたのですが、よくわかりませんでした。

Unityの座標の扱い方の問題でしょうか?

 

まぁ上にずらしたい!とかあんまりないので無視します。

必要になったら調べます。

 

 

頂点をずらすのは、実用的な話で言えば法線方向に膨らませてアウトラインに使えます。

 

おわり

今回は外部から受け取った値を実際に使ってみました。

頂点を任意の位置にずらす際はもっと勉強が必要そうです。

 

次回はテクスチャを貼り付けてみます。