本日は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では次のように描画されます。

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