未来を創る、テックコミュニティー

代表技術通信~Shader、シェーダー、勉強する①

草場代表
2020/11/18

こんばんわ。代表の草場です。

Shaderを本格的に勉強する必要あるので、7日間でマスターするUnityシェーダ入門にて、学び中です。まずは、【Unityシェーダ入門】Unityのシェーダで遊んでみようからです。

プロジェクトビューで右クリック→「Create」→「Shader」→「Standard Surface Shader」でシェーダファイルを作ります。名前はsampleにします。
続けて、いま作成したsampleシェーダを選択した状態で「Create」→「Material」マテリアルを作成し、こちらも名前はsampleにしておきます。

写真は後程

いま作成したマテリアルを3Dモデルにアタッチし、インスペクタからマテリアルのシェーダをCustom/sampleに変更します。

写真は後程

このように、Unityではマテリアルとシェーダが一対一でひも付きます。

Unityのサーフェイスシェーダの流れは以下です。

ポリゴン→Vertex(頂点情報を処理)→Surf(オブジェクトの色を決める)→Lighting(ライティング)→出力

Unityのサーフェイスシェーダには3つの工程があります。
Vertexシェーダでは頂点情報を処理
Surfシェーダではオブジェクトの表面の色を定義
Lightingではオブジェクトの陰影を決定

VertexとLightingの工程はUnityが自動生成してくれます。そのため、まずはSurfシェーダの部分だけを扱います。

プロジェクトビューのsampleシェーダを開いて中身を見ます。

写真は後程

大きく分けると、以下の三つから構成されています。

Parameters
Shader Settings
Surface Shader

Parametersにはインスペクタに公開する変数を書きます。C#スクリプトのpublic変数のようなものです。
Shader Settingsにはライティングや透明度など、シェーダの設定項目を記述します。
Surface Shaderにはシェーダ本体のプログラムを書きます。

プロジェクトビューのsampleシェーダをクリックして、Surf関数部分に修正を加えます。

void surf (Input IN, inout SurfaceOutputStandard o) {
                            // Albedo comes from a texture tinted by color
                           fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
                           o.Albedo = fixed4(0.1f, 0.1f, 0.1f, 1);
                           // Metallic and smoothness come from slider variables
                           o.Metallic = _Metallic;
                           o.Smoothness = _Glossiness;
                           o.Alpha = c.a;
}

o.Albedoの行を変更し、黒色にしました。Albedoはオブジェクトの基本色を定義しています。surfシェーダでオブジェクトの表面色を指定した後にライティングをする工程があるため、surfシェーダ直後は真っ黒なドラゴンが、Lightingの工程で光が当たることで陰影がつきます。

次は、【Unityシェーダ入門】20行から始めるUnityミニマルシェーダです。

以下のプログラムが、最小限のシェーダです。

Shader "Custom/sample" {
            SubShader {
                           Tags { "RenderType"="Opaque" }
                           LOD 200
                           CGPROGRAM
                          #pragma surface surf Standard fullforwardshadows
                          #pragma target 3.0

                           struct Input {
                                        float2 uv_MainTex;
                                           };
                           void surf (Input IN, inout SurfaceOutputStandard o) {
                                                 o.Albedo = fixed4(1.0f, 1.0f, 1.0f, 1);
                                            }
                           ENDCG
                        }
                        FallBack "Diffuse"
          }

Tags〜#pragmaまでの行がSettings部分です。重要なのは struct Input と surf関数です。
Unityのサーフェイスシェーダにおいて、Vertexシェーダから出力された値(Input構造体)を入力に取り、オブジェクトの表面色(SurfaceOutputStandard)を出力します。
このSurfaceOutputStandardに対してライティングを行い最終的な絵になります。このInput構造体で記述したフィールドだけがサーフェイスシェーダに渡されてきます。言葉の意味は以下です。

入力変数名    意味
uv_MainTex   テクスチャのuv座標
viewDir     視線方向
worldPos    ワールド座標
screenPos    スクリーン座標

Output構造体は次のような値です。

出力変数名   意味
Albedo     基本色
Normal    法線情報

重要なのは、サーフェイスシェーダの後段にUnityが自動生成してくれるライティングの工程があるため、自分でライティングの処理を書く必要がないだけでなく、自動的に影などの計算もしてくれるということです。

surf関数がサーフェイスシェーダの肝です。出力用の構造体(SurfaceOutputStandard)がもつAlbedo変数に色情報を指定しています。

この記事を書いた人
草場代表
エディター