夜風のMixedReality

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

Unity HLSLでライトを扱うShaderを書く

本日はShader勉強枠です。

Unityでは[ShaderLab]言語の中で[Cg/HLSL]言語を使用し、記述します。

近年のUnityでは[CGPROGRAM~ENDCG]から[HLSLPROGRAM~ENDHLSL]で記述する流れへ変わってきています。

これはどちらで書いても際はないようですが、[UniversalRenderPipline]ではこの流れが顕著になっています。

この場合ライティング関連で[UnityCG.cginc]の関数が衝突するためであるようですが、この場合使用する[UnityCG.cginc]に対応する[Core.hlsl]でライトを使用するコードを調べました。

正確には[Core.hlsl]と合わせてライト関連を使用するためには[Lighting.hlsl"]を使用する必要があります。

〇Core.hlslでライトを扱うShader

今回は次のようなコードを書きました。

詳細はコードのコメントアウトにありますが、基本的には[Lighting.hlsl"]の[Light構造体]を使用します。

Light lt = GetMainLight()

Lightを取得し、法線に合わせて向きを計算することでShader側では特に意識することなく光情報を扱えるようです。

Shader "Custom/LightSample"
{
    Properties
    {
        _MainColor("MainColor",color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass{
        HLSLPROGRAM
        #pragma vertex vert
        #pragma  fragment frag
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        //Lighting.hlslがライト情報を格納するコアpackage
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"

        struct appdata_t
        {
            float4 vertex:POSITION;
            float2 uv : TEXCOORD0;
            half3 normal: NORMAL;
        };

        struct v2f
        {
            float4 vertex : SV_POSITION;
            float2 uv : TEXCOORD0;
            float3 normalWS : TEXCOORD1;
        };

        v2f vert (appdata_t v)
        {
            v2f o;
            o.vertex = TransformObjectToHClip(v.vertex);
            //面の法線を取得、ライトの当たる向きを計算
            VertexNormalInputs normal = GetVertexNormalInputs(v.normal);
            o.normalWS = normal.normalWS;
            return  o;
        }
        float4 frag(v2f i):SV_TARGET
        {
          //Light.hlslで提供されるUnityのライトを取得する関数
          Light lt = GetMainLight();
          float4 col = (1,1,1,1);
          //ライトの向きを計算
          float strength = dot(lt.direction, i.normalWS);
             float4 lightColor = float4(lt.color, 1);
          return col* lightColor*strength;
        }
        ENDHLSL
      }
    }
}

Unityでは次のように描画されます。

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

以上でHLSLのShaderでライト情報を扱えました。