本日はShader枠です。
今回はノーマルマップを実装していきます。
〇ノーマルマップとは?
ノーマルマップ(法線マップ)はその名の通りノーマル(法線)をカスタマイズするテクスチャです。
ノーマルは通常メッシュごとに与えられているメッシュの向きを指します。
Shader内ではピクセルごとの法線を取得して、光情報と掛け合わせることでそのピクセルの光によって受ける陰影を計算しています。
float4 frag (v2f i) : SV_Target { float4 col = _MainColor; //Light.hlslで提供されるUnityのライトを取得する関数 Light lt = GetMainLight(); //ライトの向きを計算 float strength = dot(lt.direction, i.normalWS); float4 lightColor = float4(lt.color, 1); return col* lightColor*strength; }
ノーマルマップを使用することで通常メッシュごとに行われている法線計算がより細かく制御することができるようになります。
ノーマルマップを有効にしている場合とそうではない場合とでは近づいた際のディティールが大きく異なります。
例えば次の画像ではノーマルマップがあることで筋肉感を再現しています。
使用した画像は次のようになります。
〇ノーマルマップの実装
〇Propertiesブロック
ノーマルマップは前述のように画像を使用します。
しかし通常の画像とは異なりPropertiesブロックでの右辺はbumpを使用します。
Properties { _MainTex ("Texture", 2D) = "white" {} _NormalMap("NormalMap",2D) = "bump" {} }
bumpとはノーマルマップを含む法線マップを指します。
〇フラグメントシェーダーの実装
今回は先にフラグメントシェーダーでの実装を紹介します。
NormalMapはテクスチャなのでサンプリングを行う必要がありますが、NormalMap専用のサンプリング関数としてUnpackNormal()が用意されており、一般的にこちらを使用します。
half3 tangentNormal = UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uv));
これによってサンプリングができますが、ノーマルマップを使用するためにはこれにタンジェントを処理する必要があります。
タンジェントとは接ベクトルという意味でこれはメッシュ状のある一点に対しての接触面という意味になります。
タンジェントの処理はその②で行います。