LoginSignup
83
64

More than 5 years have passed since last update.

Unity Shaderの基礎 part 2

Last updated at Posted at 2016-02-04

テクスチャを貼ってみる

今回は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という感じでアクセスできます。
他にもfloat3float4などがあります。


sampler2D _MainTex;

プロパティで受け取ったデータをシェーダ内で使うための定義です。
2Dテクスチャの場合は、sampler2Dです。


void surf (Input IN, inout SurfaceOutput o) {
    o.Albedo = tex2D(_MainTex, IN.uv_MainTex);
}

tex2D関数は、UV座標(uv_MainTex)からテクスチャ(_MainTex)上のピクセルの色を計算して返します。


マテリアルに今回作ったシェーダとテクスチャを割り当てます。
キャプチャ002.PNG
割り当てたテクスチャ
texture001.png

実行結果

実行すると下記のようになります。
キャプチャ001.PNG

テクスチャを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をもとにしたfloat2scrollに、_Time.yを掛けています。
次の行でUV座標scrollを足してUVをずらしています。


マテリアルにシェーダを割り当て、ScrollXScrollYの値を設定します。
キャプチャ003.PNG
スクロール方向がわかりやすくなるようにテクスチャを変えました。
frame64x64.png

実行結果

uvscroll001.gif

ちなみに、今回使用したテクスチャのインポート設定で、Wrap ModeRepeatにしている場合は、上記のようにUVスクロールがループしますが、Clampにしていると、下記のようになります。
uvscroll002.gif

これは、UV座標がテクスチャの端(0~1の間)をはみ出した場合にループせずに端のピクセルを返すようになっているからです。
コレはコレでうまく使えば表現の幅が広がりそうです。

参考

http://qiita.com/edo_m18/items/591925d7fc960d843afa
http://docs.unity3d.com/462/Documentation/Manual/SL-BuiltinValues.html

83
64
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83
64