リアルとバーチャルの間

気まぐれに書いてます。

shaderを書こう@サーフェイス・シェーダ

UnityのShaderLabを使ってシェーダを作ってみよう!

unityでかけるシェーダの種類は3つあります。
・Fixed Function Shaders(固定機能シェーダ)
Surface Shaders(サーフェイスシェーダ)
・Vertex and Fragment Shaders(頂点・フラグメントシェーダ)

以下、シェーダーの基本要素です。

Shader "Path/To/ShaderName" {
    Properties {
        //...
    }
    SubShader {
        //...
    }
    SubShader {
        //...
    }
    SubShader {
        //...
    }
    //以下、必要なだけ繰り返し

    FallBack "Diffuse”
}


Properties
Propertiesは、シェーダーで使う変数とUnityエディタとの関連付けを行います。

name ("display name", Range (min, max)) = number
float型のプロパティ定義
minからmaxまでのスライダーをインスペクターに表示

name ("display name", Color) = (number,number,number,number)
カラープロパティ定義

name ("display name", 2D) = "name" { options }
2Dテクスチャプロパティ定義

name ("display name", Rect) = "name" { options }
矩形プロパティ定義

name ("display name", Cube) = "name" { options }
キューブマップテクスチャのプロパティ定義

name ("display name", Float) = number
float型のプロパティの定義

name ("display name", Vector) = (number,number,number,number)
4成分のベクトルプロパティの定義

[MaterialToggle] name ("display name", Float) = 0 // 0 is false, 1 is true
boolean風のプロパティ定義

nameは、シェーダー内の変数名
display nameは、Unityのインスペクタに表示される名前。

SubShader

Shader "Custom/SampleShader" {
    Properties {
        _MainTex ("Base", 2D) = "white" {}
    }

    SubShader {
        Tags { "RenderType"="Transparent" }

        CGPROGRAM

        #pragma surface surf Lambert

        struct Input {
            float2 uv_MainTex;
            float4 vtxColor : COLOR;
        };

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

        ENDCG
    }
}

#progma文
#pragmaの行は、サーフェイスシェーダーについての設定。
surfaceというキーワードではじまり、
次のsurfはシェーダのエントリ関数の名前を指定します。
Lambertは、ランバート反射の事でライティングの設定ができます。
さらにオプションを指定することもできます。


Input構造体

Shader "Custom/sample" {
    Properties {
        _MainColor("Color", Color) = (1, 1, 1)
        _MainTex("Texture", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Transparent" }

        CGPROGRAM

        float4 _MainColor;
        sampler2D _MainTex;

        #pragma surface surf Lambert alpha

        struct Input {
            float4 color : COLOR;
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb * _MainColor.rgb * half3(1, 0.5, 0.5);
            o.Alpha = 0.5;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

中央付近にInput構造体が定義されています。
上記のサンプルでは、Unityのインスペクタからカラーとテクスチャをそれっぞれ受け取るようになっています。
インスペクタから受け取ったテクスチャ情報は、Input構造体で定義され
uv_MainTexメンバに引数として渡してきます。

この内容は、edo_m18さんの記事をそのまま写経したものです。
監督ありがとうございます。