テクスチャを貼ってみる
今回は3Dモデルにテクスチャを貼ってみます。
Shader "Custom/surfaceshader003" {
Properties {
_MainTex("Base (RGB)",2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D(_MainTex, IN.uv_MainTex);
}
ENDCG
}
FallBack "Diffuse"
}
説明
Properties {
_MainTex("Base (RGB)",2D) = "white" {}
}
今回は、プロパティにテクスチャを指定しています。
プロパティの書式は、
変数名("Inspector上の表示名", 変数の種類) = デフォルト値
でしたね。
今回は、_MainTexという、2Dテクスチャの変数を定義しています。
デフォルト値の**"white"は白ベタのテクスチャを指しています。
試しに""**にしてみると灰色になりました。
struct Input {
float2 uv_MainTex;
};
surf関数に渡す構造体の指定です。
今回は、_MainTexのUV座標を定義しています。
変数名**_MainTexの前にuvとつけることで、自動的にマテリアルのテクスチャ座標設定(TilingとOffset)が適用されたUV座標が入ってきます。
ちなみに、float2というのはfloat型の2要素を持ったベクトルを表しています。
uv_MainTex.x uv_MainTex.yという感じでアクセスできます。
他にもfloat3やfloat4**などがあります。
sampler2D _MainTex;
プロパティで受け取ったデータをシェーダ内で使うための定義です。
2Dテクスチャの場合は、sampler2Dです。
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D(_MainTex, IN.uv_MainTex);
}
tex2D関数は、UV座標(uv_MainTex)からテクスチャ(_MainTex)上のピクセルの色を計算して返します。
マテリアルに今回作ったシェーダとテクスチャを割り当てます。
割り当てたテクスチャ
実行結果
テクスチャをUVスクロールさせてみる
先ほどのシェーダを改造して、UVスクロールをさせてみます。
テクスチャのUVをX方向とY方向に、時間に比例してずらすようにすればできそうです。
Shader "Custom/surfaceshader004" {
Properties {
_MainTex("Base (RGB)",2D) = "white" {}
_ScrollX("Scroll X", float) = 0
_ScrollY("Scroll Y", float) = 0
}
SubShader {
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
float _ScrollX, _ScrollY;
void surf (Input IN, inout SurfaceOutput o) {
float2 scroll = float2(_ScrollX, _ScrollY) * _Time.y;
o.Albedo = tex2D(_MainTex, IN.uv_MainTex + scroll);
}
ENDCG
}
FallBack "Diffuse"
}
説明
追加したのは3箇所ですが、要所だけ説明します。
Properties {
_MainTex("Base (RGB)",2D) = "white" {}
_ScrollX("Scroll X", float) = 0
_ScrollY("Scroll Y", float) = 0
}
_ScrollXと**_ScrollY**はUVスクロール用の移動量です。
void surf (Input IN, inout SurfaceOutput o) {
float2 scroll = float2(_ScrollX, _ScrollY) * _Time.y;
o.Albedo = tex2D(_MainTex, IN.uv_MainTex + scroll);
}
突然**_Time.yという変数が出てきましたが、コレは定義済み変数といって、Unity側が自動的に用意している変数の一つです。
_Timeは、時間に関する変数で、ゲーム中の経過時間が入ってます。
float4なので、4要素あるのですが、xは1/20、yは等倍、zは2倍、wは3倍の時間が入ってます。
今回は等倍速の時間が欲しかったのでyを使用しています。
_ScrollXと_ScrollYをもとにしたfloat2のscrollに、_Time.yを掛けています。
次の行でUV座標にscroll**を足してUVをずらしています。
マテリアルにシェーダを割り当て、ScrollXとScrollYの値を設定します。
スクロール方向がわかりやすくなるようにテクスチャを変えました。
実行結果
ちなみに、今回使用したテクスチャのインポート設定で、Wrap ModeをRepeatにしている場合は、上記のようにUVスクロールがループしますが、Clampにしていると、下記のようになります。
これは、UV座標がテクスチャの端(0~1の間)をはみ出した場合にループせずに端のピクセルを返すようになっているからです。
コレはコレでうまく使えば表現の幅が広がりそうです。
参考
http://qiita.com/edo_m18/items/591925d7fc960d843afa
http://docs.unity3d.com/462/Documentation/Manual/SL-BuiltinValues.html