会社でUnityのシェーダー触ることも出てきました。

学生の頃HTMLとかCSSとかしかってなかった奴には馴染みのない物がボロボロと出てきて焦って勉強したので、簡単にまとめようと思います。

Unlit / Transparent シェーダーに手を加えて半透明にできるようにする

これが、今回のミッションでした。

しかし、Unlit…..?そもそもシェーダーってどう動いてんだ。。。ってとこから始まったので、今回つかったUnityのUnlit / Transparentのシェーダーを自分なりに全文解説してみようと思います (間違えてたらコメントくださいmm)

UnityのShaderとは

これは他にばらしい記事がたくさんあったのでそちらをご覧ください。

Unity のシェーダの基礎を勉強してみたのでやる気出してまとめてみた

その1 UnityにおけるShaderとは?

Unityのシェーダーの説明をするための、マテリアルとシェーダーとテクスチャ の説明

Unity のレンダリングに必要な基本3要素

・ マテリアル

モデル表面の描画方法を定義する。テクスチャ,タイリング設定,色調への参照、使用するシェーダーを設定できる。

テクスチャ

ビットマップ画像。マテリアルのシェーダーがオブジェクト表面の色を計算するのに、テクスチャを使ったりする。オブジェクト表面の基本色(アルベド)では、反射率や粗さなどのマテリアル表面のさまざまな要素をテクスチャで置き換える事ができます。

・シェーダー

光源入力、マテリアル設定をベースにして、ピクセル毎の描画色を計算するための数学的な計算をするためのスクリプト

多くの一般的なレンダリング(人物、風景、環境、透明な個体、硬質・軟質な表面などのレンダリング)では通常、スタンダードシェーダー を使用するのが最善の選択です。このシェーダーは現実性の高い手法で、さまざまな種類の表面をレンダリングする能力を持つ、カスタマイズ性が高いシェーダーです。

参考 : マテリアルとシェーダーとテクスチャ

これをふまえた上で、Unityが標準で用意してくれているシェーダーの一つ、Unlit / Transparentシェーダーがこちら


// Unlit alpha-blended shader.
// - no lighting
// - no lightmap support
// - no per-material color

Shader "Unlit/Transparent" { //表示される名前
  Properties { //マテリアルからいじれるようになる値
    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} //テクスチャ、インスペクターで変更可能
  }

  SubShader {
    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} //描画方法を決めるためのタグ
    LOD 100 //

    ZWrite Off //深度情報は考慮しない
    Blend SrcAlpha OneMinusSrcAlpha //

    Pass {
      CGPROGRAM
      #pragma vertex vert //頂点シェーダーの関数宣言
      #pragma fragment frag //フラグメントシェーダーの関数宣言
      #pragma target 2.0 //バージョン指定
      #pragma multi_compile_fog //フォグの設定

      #include "UnityCG.cginc" //UnityCG.cginc のインポート、便利関数がたくさん

      struct appdata_t { //構造体
        float4 vertex : POSITION; //ローカルのポジションが入ってくる
        float2 texcoord : TEXCOORD0; //テクスチャのuv
        UNITY_VERTEX_INPUT_INSTANCE_ID //
      };

      struct v2f { //頂点→表面への変換構造体
        float4 vertex : SV_POSITION; //ローカルのポジション
        float2 texcoord : TEXCOORD0; //uv
        UNITY_FOG_COORDS(1)          //フォグの設定
        UNITY_VERTEX_OUTPUT_STEREO   //
      };

      sampler2D _MainTex; //プロパティのテクスチャ
      float4 _MainTex_ST; //

      v2f vert (appdata_t v) //頂点シェーダの処理
      {
        v2f o;  //構造体のインスタンス
        UNITY_SETUP_INSTANCE_ID(v); //
        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //頂点シェーダーへの変換
        o.vertex = UnityObjectToClipPos(v.vertex); //MVP変換
        o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); //uv変換
        UNITY_TRANSFER_FOG(o,o.vertex);       //頂点へのフォグの適応
        return o; //表面シェーダーで使う構造体を返す
      }

      fixed4 frag (v2f i) : SV_Target //表面シェーダーの処理
      {
        fixed4 col = tex2D(_MainTex, i.texcoord); //テクスチャ各uvでの色
        UNITY_APPLY_FOG(i.fogCoord, col); //フォグの設定
        return col; //色を返す
      }
      ENDCG
   }
}

Unityの(内臓)ビルドインシェーダーはこのページ、該当OSのプルダウンの「ビルドインシェーダー」クリックでダウンロードできます。

https://unity3d.com/jp/get-unity/download/archive

このシェーダーでできることテクスチャを描画できる。uvを設定できる。

ではミッション、alpha値を設定できるようにしたのがこちら、

Shader "Unlit/Transparent Alpha" {
  Properties {
    _Color ("Color", Color) = (1,1,1,1)
    _MainTex ("Texture", 2D) = "white" {}
  }

  SubShader {
    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    LOD 100

    ZWrite Off
    Blend SrcAlpha OneMinusSrcAlpha

    Pass {
      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #pragma multi_compile_fog

      #include "UnityCG.cginc"

      struct appdata_t {
      float4 vertex : POSITION;
      float2 texcoord : TEXCOORD0;
    };

    struct v2f {
      float4 vertex : SV_POSITION;
      half2 texcoord : TEXCOORD0;
      UNITY_FOG_COORDS(1)
    };

    sampler2D _MainTex;
    float4 _MainTex_ST;
    fixed4 _Color;

    v2f vert (appdata_t v)
    {
      v2f o;
      o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
      o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
      UNITY_TRANSFER_FOG(o,o.vertex);
      return o;
    }

    fixed4 frag (v2f i) : SV_Target
    {
      fixed4 col = tex2D(_MainTex, i.texcoord) * _Color;
      UNITY_APPLY_FOG(i.fogCoord, col);
      return col;
    }
    ENDCG
  }
}

Colorを設定できるようにしてフラグメントシェーダーで色を乗算しただけです。。なんで標準でこれないんだ。。。

<Unlit – TranceParent の時 >

<Unlit – TranceParent Alpha の時 >

inspectorのColor値からalphaをかけると

裏に隠れてたTextMeshが見えました〜。めでたしめでたし。