夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

UnityでShaderを勉強する その② 実際にShaderの中身を見ていく

 本日はShader勉強枠です。

 Shaderは3Dオブジェクトの表現において非常に大切なものですが、Unity自体やC#などと違い初心者向けの情報が少なく手を出しにくいのが現状です。

 前回Shaderとは何かを見ました。

redhologerbera.hatenablog.com

 今回はShaderの中身をのぞいていきます。

〇Shaderの中身

 Unityで作成したShaderを開くと以下のように記述されています。

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        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 = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
●ShaderLab 

UnityのShaderはShaderLabという言語の中でHLSLという別の言語で処理が記述されています。

f:id:Holomoto-Sumire:20200330082456j:plain

ShaderLabの部分は大きく以下の成分で記述されています。

Shader "MyShader" {
    Properties {
   C#におけるPublicクラスのように、ここに記述されたプロパティはUnityのマテリアルで扱うことができます。
    }
    SubShader {
  実際の処理が記述されます。
    }
}

また、この部分をShaderLabシンタックスとも表します。

シンタックスを詳しく見ると次のようになります。

Shader "name"// この名前がShaderの名前になります。
{
//Propertiesに記述したパラメータはUnityのマテリアルのパラメータとして扱うことができます。 
[Properties] 
//Shaderの処理
Subshaders 
//Shaderが処理できなかった場合に実行される予備のShader
[Fallback] 
[CustomEditor] 
}

例えば

Shader "HoloMoto/yokazenoMixedReality"
{
    Properties
    {

    }

}

と記述すると

f:id:Holomoto-Sumire:20200330083850j:plain

UnityのマテリアルでHoloMoto/yokazenoMixedRealityとしてShaderが登録されます。

ここではShaderの処理が記述されていないのでShaderエラーを示す蛍光紫のマテリアルになります。

docs.unity3d.com

●HLSL

HLSL(High Level Shading Language)言語はMicrosoftによって開発されたシェーディング言語です。

ShaderLab内で

CGPROGRAM

ENDCG

の間に記述される部分がHLSL言語で記述します。

UnityではShaderとはShaderLabでUnityのマテリアルとHLSL言語を結び付けています。

ここからは実際にUnityのレファレンスからShaderを記述しながら学びます。

docs.unity3d.com

〇DiffuseShader

  [Diffuse]とは拡散を意味します。

 3Dオブジェクトに当たった光の反射を単純化し均一に反射させることを意味します。

 広く使われるShaderの表現でオブジェクトの[Albedo]=反射光色に使われます。

 光源からの光の向きとオブジェクト表面の法線ベクトルによって光の強さが変化します。

 Shader "Example/Diffuse Simple" {
      SubShader {
        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert
        struct Input {
            float4 color : COLOR;
        };
        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = 1;
        }
        ENDCG
      }
      Fallback "Diffuse"
    }

 勉強したことを解説していきます。

Shaderにコメントを付けていくと次のようになります。

//Shaderの名前
 Shader "Example/Diffuse Simple" {
      SubShader {
      //処理
       Tags { "RenderType" = "Opaque" }
   //CGPROGRAM~ENDCGの間はHLSL言語を使用して記述されます。
        CGPROGRAM
     //ターゲットコンパイルを指定します。
        #pragma surface surf Lambert
   //描画時にUnityから渡される引数が入った構造体
        struct Input {
    //float4型の頂点カラー
            float4 color : COLOR;
        };
  //実際の描画
        void surf (Input IN, inout SurfaceOutput o) {   
    o.Albedo = 1;
        }
        ENDCG
      }
  //このShaderを実行できない場合、"Diffuse"を試す
      Fallback "Diffuse"
    }

今回Shaderの中身を軽く見ました。

次回以降より詳しく見ていきます。