本日はShader枠です。
今回はShaderの
〇環境
・Unity6000.0.2f1
・Windows11PC
〇セルルックなライティング
Unityのシェーダーの場合ライティングによる影の計算はNdotLが基本的な考え方です。
NdotLとはメッシュの法線=Normal、とライト=Lightのドット積によってライトが当たる面を計算するという意味です。
ライトのベクトルと比較してメッシュの向きが一致する場合は影、逆に逆行している場合はライトが当たる部分というようになります。
https://redhologerbera.hatenablog.com/entry/2022/11/11/231804
今回は、基本形のライティングシェーダーから流用してセルルックなライティングを行います。
Shader "Unlit/TutorialShader"
{
Properties
{
// _MainTex ("Texture", 2D) = "white" {}
_MainColor("Color" ,color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct appdata
{
float4 vertex : POSITION;
half3 normal: NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 normalWS : TEXCOORD1;
};
float4 _MainColor;
v2f vert (appdata 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
{
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;
}
ENDHLSL
}
}
}
このままでは以下のように写実的にグラデーションとして影が付きます。

セルルックな見た目にするためには影の付き方をグラデーションではなくメリハリがあるつけ方をする必要があります。
そこでNdotLの計算結果をStep関数を用いて0,1に分割することでこれが可能です。
//ライトの向きを計算
float strength = dot(lt.direction, i.normalWS);
float4 lightColor = float4(lt.color, 1);
return col* lightColor* step(0.3,strength);
Step関数は引数との差をもとに0,1で値を分けてくれます。
これによってセルルックなライティングの基本形が完成しました。

本日は以上です。