夜風のMixedReality

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

UnityでShaderを勉強する その⑦ 細部を表現するためのテクスチャを使用するShaderを書く

本日はShader勉強枠です。

前回UnityのレファレンスからDiffuse SimpleShaderを見てRimLightを使用するShaderを作成しました。

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

今回もDiffuse SimpleShaderを編集し、学んでいきます。

〇ディテールテクスチャを使用する。

今回は2つめのテクスチャを使用してさらに複雑な表現を行うShaderを書きます。

 前回までのDiffuse RimLight Shaderは以下になります。

●Exampes/Diffuse RimLight Shader
 //シンタックスShaderの名前と格納場所
Shader "Example/Diffuse RimLight"{

    Properties{
        _MainTex("Texture",2D) = "white"{}
        _BumpMap("Bumpmap", 2D) = "bump"{}
        _RimColor("Rim Color", Color) = (0.26,0.19,0.0)
            //リムpowerのレンジ defaultでは3に設定される。
        _RimPower("Rim Power", Range(0.5,8.0)) = 3.0
    }
        //Shaderの中身サブシェーダーではレンダリングパスの一覧を定義し、任意のオプションとしてすべてのパスに共通の State (状態)を設定します。追加で、サブシェーダーの特定の Tag を設定できます。
        SubShader{
        //RenderingType
            Tags{"RenderType" = "Opaque"}
            //
                CGPROGRAM
                #pragma surface surf Lambert
                struct Input {
                    float2 uv_MainTex;
                    float2 uv_BumpMap;
                    float3 viewDir;
                };
                sampler2D _MainTex;
                sampler2D _BumpMap;
                float4 _RimColor;
                float _RimPower;
                void surf(Input IN, inout SurfaceOutput o) {
                    o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
                    o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
                     //rim = 1.0 -viewDirの正規化したものとノーマルマップの内積(0~1の値を取る)
                    half rim = 1.0 - saturate(dot(normalize(IN.viewDir),o.Normal));
                    //Emissionに代入 propertyのRimColorの値(RGB)× rim^_RimPower= 0~1の値を取る 参考https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-pow 
                    o.Emission = _RimColor.rgb * pow(rim, _RimPower);
                }
                ENDCG
    }
        Fallback "Diffuse"
}

〇ディテールテクスチャを使用する

ディテールアップ用のテクスチャを使用するためPropertiesに追加します。

      Properties {
        _Detail ("Detail", 2D) = "gray" {}
      }

次にテクスチャ座標をInput構造体に記述します。

        struct Input {
            float2 uv_MainTex;
            float2 uv_Detail;
        };

ディテールテクスチャを渡すために記述します。

        sampler2D _Detail;

処理を記述します。

 void surf(Input IN, inout SurfaceOutput o) {
           //_Detailのrgbをo.Albedoに乗算
           o.Albedo *= tex2D(_Detail, IN.uv_Detail).rgb * 2;
       }

これを前回のExample/Difusse RimLightShaderに記述します。

//シンタックスShaderの名前と格納場所
Shader "Example/Diffuse Detail"{

    Properties{
        _MainTex("Texture",2D) = "white"{}
        _BumpMap("Bumpmap", 2D) = "bump"{}
        _RimColor("Rim Color", Color) = (0.26,0.19,0.0)
            //リムpowerのレンジ defaultでは3に設定される。
            _RimPower("Rim Power", Range(0.5,8.0)) = 3.0
            //SecondryTexture
            _Detail("Detail", 2D) = "gray"{}
    }
        //Shaderの中身サブシェーダーではレンダリングパスの一覧を定義し、任意のオプションとしてすべてのパスに共通の State (状態)を設定します。追加で、サブシェーダーの特定の Tag を設定できます。
        SubShader{
        //RenderingType
            Tags{"RenderType" = "Opaque"}
            CGPROGRAM
            #pragma surface surf Lambert
        //Input構造体はテクスチャ座標として扱うものを記述します。
       struct Input {
           float2 uv_MainTex;
           float2 uv_BumpMap;
           float3 viewDir;
           float2 uv_Detail;
       };
       sampler2D _MainTex;
       sampler2D _BumpMap;
       float4 _RimColor;
       float _RimPower;
       sampler2D _Detail;
       void surf(Input IN, inout SurfaceOutput o) {
           o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
           //_Detailのrgbをo.Albedoに乗算
           o.Albedo *= tex2D(_Detail, IN.uv_Detail).rgb * 2;
           o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
           //rim = 1.0 -viewDirの正規化したものとノーマルマップの内積(0~1の値を取る)
           half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
           //Emissionに代入 propertyのRimColorの値(RGB)× rim^_RimPower= 0~1の値を取る 参考https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-pow 
           o.Emission = _RimColor.rgb * pow(rim, _RimPower);
       }
       ENDCG
    }
        Fallback "Diffuse"
}

ではUnityで見ていきます。

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

マテリアルに[Detail]を設定する項目が現れました。

f:id:Holomoto-Sumire:20200421090139j:plain
DetailTextureが未設定の場合

f:id:Holomoto-Sumire:20200421085733j:plain
DetailTextureを使用

以上でディテールテクスチャが使用できました。