【Unity】【シェーダ】MatCap(スフィアマッピング)を実装する

f:id:halya_11:20180614225006g:plain

MatCapとかスフィアマッピングとか呼ばれる手法の実装方法です。

MatCapとは?

ライティング済みの球体を映したテクスチャから色をいい感じにサンプリングすることで、さもライティングされているかのように見せられます。

f:id:halya_11:20180614225838p:plain

この球体が描かれたテクスチャをMatCap(Material Capture)といいます。
レンダリング結果のように見えますが、あくまで球体の描かれただけのテクスチャです。

実装の考え方

考え方はとてもシンプルです。
まず適用したいモデルとMatCapテクスチャを用意します。

f:id:halya_11:20180614230646p:plain

法線がカメラ方向(要は手前)を向いている部分はテクスチャの中心の色を取ります。
そして法線が視線と垂直になっていくにつれてテクスチャの外側をサンプリングするようにします。

f:id:halya_11:20180614224345p:plain

ちょっと雑な説明ですが、要するにこういうことです。

シェーダ

シェーダは次のように実装します。

Shader "MatCap"
{
    Properties
    {
        _MatCap ("Mat Cap", 2D) = "white" {}
    }

    Subshader
    {
        Tags { "RenderType"="Opaque" }
        
        Pass
        {
            CGPROGRAM
           #include "UnityCG.cginc"
           #pragma vertex vert
           #pragma fragment frag

            sampler2D _MatCap;
                
            struct v2f
            {
                float4 pos  : SV_POSITION;
                half2 uv    : TEXCOORD0;
            };
                
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos (v.vertex);
                
                // カメラ座標系の法線を取得
                float3 normal = UnityObjectToWorldNormal(v.normal);
                normal = mul((float3x3)UNITY_MATRIX_V, normal);

                // 法線のxyを0~1に変換する
                o.uv = normal.xy * 0.5 + 0.5;

                return o;
            }
                
            float4 frag (v2f i) : COLOR
            {
                // カメラから見た法線のxyをそのままUVとして使う
                return tex2D(_MatCap, i.uv);
            }

            ENDCG
        }
    }
}

説明はコメントに書いてある通りで、特に難しいことはやっていません。
これを適用すると、次のようなレンダリング結果が得られます。

f:id:halya_11:20180614225006g:plain

使いどころ

MatCapの特徴として、サンプリングが視点と法線に依存するということがあります。
そしてライトの方向には依存しません。
しかし本来、ライティングは(当然ながら)ライト方向に依存するものです。

これらのことから、ライトの方向強く意識されたりカメラがいろんな方向に動いたりする状況では違和感を感じそうです。

しかしカメラとライトの角度が固定的なシーンだったり、複雑な反射をする宝石のようにそもそもライトの方向が意識しづらいものだったりする場合には十分使えそうです。

それになによりアーティストが直感的にテクスチャを作れるのは大きなメリットです。
そういう意味ではトゥーン系の表現とかは相性がよさそうです。

このあたりは色々と検証と改善の余地がありそうなので試してまた記事化しようと思います。

参考サイト

この記事で使っているMatCapは以下のサイトからお借りしています。 www.pixelfondue.com