2017年2月21日火曜日

シェーダーについて

Sprites-Defaultシェーダーを使用して、シェーダーの勉強をしてみた。
何となくわかった気がした。
Sprites-Defaultシェーダーはアーカーブのダウンロードの項目のビルドインシェーダーに入っています。

アーカイブリンク
https://unity3d.com/jp/get-unity/download/archive

以下 よく分からないなりにSprites-Defaultシェーダーにコメントなどをつけてみた。

Shader "Sprites/Default"
{
 // カラーやベクトルなどのプロパティもこの箇所に記述
 // スクリプトなどからアクセスできる変数群,インスペクターにも表示される
    Properties
    {
     // メインテクスチャを白に設定
     //  [属性:テクスチャUI] 変数名 ( インスペクタ場で表示される名前設定, 2Dに設定) = 初期値:白のテクスチャ
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}

        // カラー
        // プロパティ名 ( 適当な名前, カラーに設定) = 初期値:
        _Color ("Color", Color) = (1,1,1,1)

        // この属性がついた値はインスペクタ上でチェックボックス切り替えになる。
        // ピクセルをスナップするか?
        //  [属性:トグルスイッチ] 変数名 ( 名前設定, floatに設定) = 初期値:0
        [MaterialToggle] PixelSnap ("is Pixel snap", Float) = 0
    }
 
    SubShader
    {
        Tags
        {
         // 描画順、アルファブレンディングするものはすべて、Transparentであるべき
         // "Background" = 1000 "Geometry" = 2000、"AlphaTest" = 2450、"Transparent" = 3000 "Overlay" = 4000
         // 値は "Queue" = "Geometry+1" のようにしてインデックスを明示することもできる
            "Queue"="Transparent"

            // Projector の投影を無視するか?
            "IgnoreProjector"="True"

            // 描画タイプ Opaque:不透明 Transparent:部分的な透過 他
            "RenderType"="Transparent"

            // マテリアルのインスペクター上でのプレビューの表示タイプ。
            // Plane:2D sphere:球体 Skybox:空テクスチャ
            "PreviewType"="Plane"

            // シェーダーがスプライトに用いられる場合やアトラスにパッキングされたとき動作しない場合、CanUseSpriteAtlas タグを “False” に設定します。
            "CanUseSpriteAtlas"="True"
        }

        // ポリンゴンのどちら側をカリング(描画しない)する
        // Back:視点と反対側をカリングする (デフォルト)  
        // Front:視点と同じ側のポリゴンをレンダリングしない。オブジェクトを反転するのに使用 (デフォルト) 
        // Off:カリングを無効にして、すべての面を描画します。特殊なエフェクトで使用します。
        Cull Off

        // ライティングの設定
        // On:ライティングを有効 Off:ライティングを無効
        Lighting Off

        // 深度情報を書き込むか制御する
        // On:不透明なオブジェクトを描画する場合(デフォルト)
        // Off:部分的に透過のエフェクトを描く場合
        ZWrite Off

        // ブレンド
        // ここはいろんなややこしい
        Blend One OneMinusSrcAlpha
 
        Pass
        {
        CGPROGRAM
   // #pragma vertex [関数名]
         // vertという関数内で 頂点(vertex)のプログラムを記述できるようになる。
            #pragma vertex vert
           
            // fragという関数内で 断片(fragment)のプログラムを記述できるようになる。
            #pragma fragment frag

            // よくわからない?
            // 色々定義する箇所?
            #pragma multi_compile _ PIXELSNAP_ON

            // インクルードする
            // 様々な関数が使えるようになる
            #include "UnityCG.cginc"

            // appdata_tという構造体
            struct appdata_t
            {
             // 頂点位置
                float4 vertex   : POSITION;

                // カラー
                float4 color    : COLOR;

                // UV座標とはテクスチャの座標
                // TEXCOORD0 は、第 1 の UV 座標で、一般的に、float2, float3, float4 です。
    // TEXCOORD1, TEXCOORD2, TEXCOORD3 は、それぞれ第 2、第 3、第 4 の UV 座標です。
    // この場合1 つ目のテクスチャ座標を使用
                float2 texcoord : TEXCOORD0;
            };

            // v2fという構造体を作成
            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                float2 texcoord  : TEXCOORD0;
            };

            // _Colorの定義
            fixed4 _Color;

            // v2f構造体を返す頂点シェーダーのプログラム 
            // 返り値はfrag関数の引数で使われるらしい
            // appdata_t IN は Unity側から送られるテクスチャ?データ
            v2f vert(appdata_t IN)
            { 
             // OUTという名前でv2f構造体を作成
                v2f OUT;

                // mul ベクトルや行列の掛け算をする
                // UNITY_MATRIX_MVP 現在のモデルビュー行列×射影行列 らしい?
                // 計算したデータの取得
                // この行を消すと表示されない
                OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);

                // UV座標の取得
                OUT.texcoord = IN.texcoord;

                // 元の色に Propertiesで入力された色を掛け合わせている
                OUT.color = IN.color * _Color;

                //PIXELSNAP_ON Onの場合
                #ifdef PIXELSNAP_ON
                OUT.vertex = UnityPixelSnap (OUT.vertex);
                #endif
 
                return OUT;
            }

            // 2Dテクスチャの変数定義
            sampler2D _MainTex;

            // 2Dテクスチャの変数定義
            sampler2D _AlphaTex;

            // float型の変数定義
            float _AlphaSplitEnabled;

            // fixed4を返す関数 引数はfloat2 uv
            fixed4 SampleSpriteTexture (float2 uv)
            {

             // 該当するテクスチャ座標の色を参照
             // _MainTexとuvでtex2Dのピクセルごとの色を作成している?
                fixed4 color = tex2D (_MainTex, uv);

                //fixed4 color = fixed4(1, 1, 1, 1);

                // ALPHASPLITが許可されている場合?
#if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
                if (_AlphaSplitEnabled)
                    color.a = tex2D (_AlphaTex, uv).r;
#endif // UNITY_TEXTURE_ALPHASPLIT_ALLOWED

    // 色を返す
                return color;
            }

            // fixed4を返す断片シェーダーのプログラム
            // vertex頂点シェーダー関数の後に呼ばれる
   // 引数には頂点シェーダー関数(vert)の返り値(OUT)が入ってくる。
   // ピクセル シェーダーは、SV_Depth および SV_Target システム値セマンティクスを持つパラメーターにのみ書き込むことができるらしい
            fixed4 frag(v2f IN) : SV_Target
            {
             // 2DテクスチャとUV座標からテクスチャのピクセルを取り出して、そこにパラメータで指定された色を合わせる
                //fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;

                // テストコード1 IN.colorを消してみる
                // 結果:綺麗に表示されない、透過されない部分がでる。
                //fixed4 c = SampleSpriteTexture (IN.texcoord);

                // テストコード2 SampleSpriteTexture (IN.texcoord)を消してみる 
                // 白で表示される
                //fixed4 c = IN.color;

                // テストコード3  IN.colorを消して白色を掛け合わせてみる
                // 結果:綺麗に表示される
                //fixed4 c = SampleSpriteTexture (IN.texcoord) * fixed4(1, 1, 1, 1);

                // テストコード4  IN.colorを消して半透明を掛け合わせてみる
                // 結果:半透明に表示される
                // IN.colorはプロパティで設定された色である
                //fixed4 c = SampleSpriteTexture (IN.texcoord) * fixed4(1, 1, 1, 0.5);

        // テストコード5加算合成
                fixed4 c = SampleSpriteTexture (IN.texcoord);
                c.rgb += IN.color.rgb;
                c.a *= IN.color.a;
                
                // これがない場合,透過されない部分がでる。
                c.rgb *= c.a;

                return c;
            }
        ENDCG
        }
    }
}


参考サイト
[Unity]ShaderLab入門とか
http://komaken.me/blog/2016/03/07/unityshaderlab%E5%85%A5%E9%96%80%E3%81%A8%E3%81%8B/

"UV"のお話
http://rudora7.blog81.fc2.com/blog-entry-308.html

0 件のコメント :

コメントを投稿

【早い者勝ち!】 あなたのお名前、残ってる?

シャドウバースにPC版が誕生