うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】法線マッピングを使ってみる

法線マップ(Normal Map)(Bump mapping) - Unity マニュアル

公式にあるように法線 (Normal) マッピングとは、法線マップを利用してモデルの表面に凸凹や、傷などを付ける技法

上記のリンクより画像をそのままお借りしますが、石垣のテクスチャに対して
法線マップを利用すると下図のように凸凹がわかるようになります

https://docs.unity3d.com/ja/2018.4/uploads/Main/BumpMapStoneExampleNoBumps.jpg

https://docs.unity3d.com/ja/2018.4/uploads/Main/BumpMapStoneExampleDay.jpg

法線マップ

白黒のハイトマップを用意したら、Unityに突っ込む

※ 今回は以前の記事から拝借

そして

Texture Type を Normal Map
Create From GrayScale にチェックを入れる

f:id:hacchi_man:20210115232847p:plain:w250

そうすることで白黒のハイトマップが、法線マップのテクスチャとして利用できる

f:id:hacchi_man:20210115233145p:plain:h150 f:id:hacchi_man:20210115233206p:plain:h150

Bumpiness を変えることで、法線マップへの角度の変換具合を調整でき

値が小さいと左図ように、値が大きいと右図のようになる

f:id:hacchi_man:20210115233528p:plain:h150 f:id:hacchi_man:20210115233549p:plain:h150

法線マップを利用する Shader

法線マップを用意できたので、それを利用するための Shader を作ります

法線マップではライトの影響を受けるので、サーフェイス Shader を変更します

法線マップから 法線を取得するのは以下を利用します

UnpackNormal(tex2D (_NormalMap, IN.uv_NormalMap));

これを利用した Shader が以下です

本来は MainTex とともに利用するものですが、面倒だったので
色を指定するのみとしています

Shader "Custom/Normal"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _NormalMap ("Normal Map", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows

        #pragma target 3.0

        sampler2D _NormalMap;

        struct Input
        {
            float2 uv_NormalMap;
        };
 
        fixed4 _Color;
 
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
             o.Normal = UnpackNormal(tex2D (_NormalMap, IN.uv_NormalMap));
        }
        ENDCG
    }
    FallBack "Diffuse"
}

法線マップ Shader を使ってみる

Cube に対して 法線マップを使ってみると以下のようになり、ちょっと凸凹してるのがわかると思います

f:id:hacchi_man:20210115235614p:plain:w300

ライトの向きを変えてみるとちゃんと影も変わっていることが確認できます

f:id:hacchi_man:20210115235858g:plain