🌈

そろそろShaderをやるパート34 法線を使う

2021/06/05に公開

そろそろShaderをやります

そろそろShaderをやります。そろそろShaderをやりたいからです。
パート100までダラダラ頑張ります。10年かかってもいいのでやります。
100記事分くらい学べば私レベルの初心者でもまあまあ理解できるかなと思っています。

という感じでやってます。

※初心者がメモレベルで記録するので
 技術記事としてはお力になれないかもしれません。

下準備

下記参考
そろそろShaderをやるパート1 Unite 2017の動画を見る(基礎知識~フラグメントシェーダーで色を変える)

デモ

今更ですが、法線を利用してどうこうするってのを
ジオメトリーシェーダーでしかやってなかったので、
頂点シェーダーでも法線を利用した内容をまとめます。

法線に応じて頂点の色を変更させてみました。

左がローカル座標系の法線、右がワールド座標系の法線を利用したものです。

下記プロジェクトから拝借してます。
Unity プロジェクトの Zip ファイル

Shaderサンプル

Shader "Custom/Normal"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex:POSITION;
                float3 normal:NORMAL;
            };

            struct v2f
            {
                half3 normal:TEXCOORD0;
                float4 pos:SV_POSITION;
            };

            //頂点シェーダー
            v2f vert(appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                //法線方向のベクトル
                //o.normal = v.normal; ローカル座標系の法線
                o.normal = UnityObjectToWorldNormal(v.normal);
                return o;
            }

            //フラグメントシェーダー
            fixed4 frag(v2f i) : SV_Target
            {
                return float4(i.normal,1);
            }
            ENDCG
        }
    }
}

頂点シェーダーが受け取る構造体appdataの中で
float3 normal:NORMAL;と記述し、法線ベクトルを渡しています。

次に頂点シェーダー内でその法線ベクトルを利用してワールド座標系に変換しています。
組み込み関数のUnityObjectToWorldNormalを使用すればワールド座標系に変換できます。

そのまま渡せばローカル座標系として利用できます。

最後にフラグメントシェーダーで色情報に法線ベクトルを入れれば完了です。

参考リンク

頂点シェーダーとフラグメントシェーダーの例
知識0からのUnityShader勉強

Discussion