影はセル、ハイライトはフレネルで表現することを目的としたShaderです。
光の方向はDirectional Lightに依存しますが、ハイライトと影の濃さはマテリアルで操作します。
ShadowPower 影の強さ
ShadowCutOff セル影の範囲
ShadowOpacity 影の濃さ
FresnelColor フレネルの色
FresnelPower フレネルの強さ
FresnelOpacity フレネルの濃さ
CelLikeShader
Shader "Anime/CelLikeShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_ShadowPower("Shodow Power",Range(0.0,1.0))=0.1
_ShadowCutOff("Shadow CutOff",Range(0.0,1.0))=0.25
_ShadowOpacity("Shadow Opacity",Range(0.0,1.0))=0.5
[Space]
_FresnelColor("FresnelColor", Color) = (1,1,1,1)
_FresnelPower("FresnelPower", Range(1, 20)) = 2
_FresnelOpacity("FresnelOpacity" , Range(0, 1)) = 1
}
SubShader
{
LOD 100
Pass
{
Tags { "LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float3 viewDir : TEXCOORD1;
float3 lightDir : TEXCOORD2;
float3 normal : TEXCOORD3;
};
sampler2D _MainTex;
float4 _MainTex_ST;
half _ShadowPower;
half _ShadowCutOff;
half _ShadowOpacity;
half4 _FresnelColor;
half _FresnelPower;
half _FresnelOpacity;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.viewDir = normalize(UnityWorldSpaceViewDir(v.vertex.xyz));
o.lightDir = normalize(UnityWorldSpaceLightDir(v.vertex.xyz));
o.normal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
half vdotn = max(0,dot(i.normal, i.viewDir));
half ldotn = max(0,dot(i.normal, i.lightDir));
//影部分
half shadow=pow(vdotn,_ShadowPower)*pow(ldotn,_ShadowPower);
shadow=saturate(step(_ShadowCutOff,shadow)+(1-_ShadowOpacity));
col=lerp(col,col*col*shadow,1-shadow);
//フレネル部分
half4 fresnel =_FresnelColor* pow((1.0 - vdotn) * 0.5 + 0.5, _FresnelPower);
col.r=lerp(col.r,min(1,col.r+fresnel.r),_FresnelOpacity);
col.g=lerp(col.g,min(1,col.g+fresnel.g),_FresnelOpacity);
col.b=lerp(col.b,min(1,col.b+fresnel.b),_FresnelOpacity);
return col;
}
ENDCG
}
}
}