(1)效果 : 果然开启bloom 录屏就是会有问题
没啥好说的,直接上代码:
Shader "Unlit/MaLi"
{
Properties
{
_BaseMap ("_BaseMap", 2D) = "white" {}
_SSSMap ("_SSSMap", 2D) = "white" {}
_ILM ("_ILM", 2D) = "white" {}
_DetailMap ("_DetailMap", 2D) = "white" {}
_ToonTheshold("_ToonTheshold",range(0,1)) = 0.5
_ToonHardness("_ToonHardness",float) = 50
_SpecSzie("_SpecSzie",range(0,1)) = 0.1
// 第二个pass
_OutLineWidth("_OutLine",range(0,0.01)) = 1
_OutLineColor("_OutLineColor",color) = (0,0,0,0)
_OutlineZbias("_OutlineZbias",range(0,1)) = 1
// 补光 边缘光
_RimLightDir("_RimLightDir",vector) = (0,0,0,0)
_RimLightColor("_RimLightColor",color) = (0,0,0,0)
}
SubShader
{
Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwbase
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord0 : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
float3 normal : NORMAL;
float4 color : COLOR;
};
struct v2f
{
float4 uv : TEXCOORD0;
float3 pos_World : TEXCOORD1;
float3 normal_World : TEXCOORD2;
float4 pos : SV_POSITION;
float4 vertex_color : TEXCOORD3;
};
sampler2D _BaseMap,_SSSMap,_ILM,_DetailMap;
float4 _BaseMap_ST,_SSSMap_ST,_ILM_ST,_DetailMap_ST;
float _ToonTheshold,_ToonHardness,_SpecSzie;
float4 _RimLightColor;
float3 _RimLightDir;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.pos_World = mul(unity_ObjectToWorld,v.vertex).xyz;
o.normal_World = UnityObjectToWorldNormal(v.normal);
o.uv = float4(v.texcoord0,v.texcoord1);
o.vertex_color = v.color;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
half2 uv1 = i.uv.xy;
half2 uv2 = i.uv.zw;
float3 normalDir = normalize(i.normal_World);
float3 lightDir = normalize(UnityWorldSpaceLightDir(i.pos_World));
// base 主贴图
float4 base_map = tex2D(_BaseMap,uv1);
// 亮部颜色
float3 base_color = base_map.rgb;
// 用来区分皮肤头发 和非皮肤区域
float base_mask = base_map.a;
// 暗部计算
float4 sss_map = tex2D(_SSSMap,uv1);
// 暗部的颜色
float3 sss_color = sss_map.rgb;
// 边缘光的强度控制
float sss_alpha = sss_map.a;
// ILM 贴图
float4 ilm_map = tex2D(_ILM,uv1);
// 控制高光强度
float spec_intensity = ilm_map.r;
// 控制光照的偏移
float diffuse_control = ilm_map.g * 2.0 - 1.0;
// 控制高光形状的大小
float spec_size = ilm_map.b;
// 内描线
float inner_line = ilm_map.a;
// 顶点色
float ao = i.vertex_color.r;
// diffuse
float NdotL= dot(normalDir,lightDir);
float half_lambert = (NdotL + 1.0) * 0.5;
float larmbert_term = half_lambert * ao + diffuse_control;
float toon_diffuse = saturate(larmbert_term - _ToonTheshold) * _ToonHardness;
float3 final_diffuse = lerp(sss_color,base_color,toon_diffuse);
// 高光
float3 viewDir = normalize(UnityWorldSpaceViewDir(i.pos_World));
float ndotV = dot(normalDir,viewDir);
float spec_term = (ndotV+1.0) * 0.5;
spec_term = spec_term * ao + diffuse_control;
spec_term = half_lambert * 0.9 + spec_term * 0.1;
float toon_spec = saturate((spec_term - (1.0 - spec_size - _SpecSzie)) * 500 );
float3 final_spec = toon_spec * base_color * spec_intensity;
//return float4(toon_spec.xxx,1.0);
// 内描线
float3 inner_line_color = lerp(base_color * 0.2, float3(1.0,1.0,1.0),inner_line);
// 第二套uv Detail 细节贴图
float3 detail_color = tex2D(_DetailMap,uv2);
detail_color = lerp(base_color * 0.2, float3(1.0,1.0,1.0),detail_color);
float3 final_line = inner_line_color * inner_line_color * detail_color;
// 补光 边缘
float3 lightDir_rim = normalize(mul((float3x3)unity_MatrixInvV,_RimLightDir.xyz));
float NdotL_rim = (dot(normalDir,lightDir_rim) + 1.0) * 0.5;
float rimLight_term = NdotL_rim + diffuse_control;
float toon_rim = saturate((rimLight_term - _ToonTheshold) * 20);
float3 rim_color = (_RimLightColor.rgb + base_color.rgb) * 0.5 * sss_alpha;
// 最后乘以 toon_diffuse 跑到diffuse 阴影区域就会隐藏
float3 final_rimLight = toon_rim * rim_color * base_mask * toon_diffuse * _RimLightColor.a;
float3 final_color = (final_spec + final_diffuse) * final_line;
final_color = sqrt(max(exp2(log2(max(final_color,0.0))* 2.2),0.0));
return float4(final_color,1.0);
}
ENDCG
}
Pass
{
cull Front
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord0 : TEXCOORD0;
float3 normal : NORMAL;
float4 color : COLOR;
};
struct v2f
{
float2 uv : TEXCOORD0;
float3 pos_World : TEXCOORD1;
float3 normal_World : TEXCOORD2;
float4 pos : SV_POSITION;
float4 vertex_color : TEXCOORD3;
};
sampler2D _BaseMap,_SSSMap,_ILM,_DetailMap;
float4 _BaseMap_ST,_SSSMap_ST,_ILM_ST,_DetailMap_ST;
float _ToonTheshold,_ToonHardness,_SpecSzie;
float _OutLineWidth;
float4 _OutLineColor;
float _OutlineZbias;
v2f vert (appdata v)
{
v2f o;
o.pos_World = mul(unity_ObjectToWorld,v.vertex).xyz;
o.normal_World = UnityObjectToWorldNormal(v.normal);
float3 tempDir = float3(o.normal_World);
tempDir.z = _OutlineZbias * (1.0 - v.color.b);
o.pos_World = o.pos_World + tempDir * _OutLineWidth * v.color.a;
o.pos = mul(UNITY_MATRIX_VP,float4(o.pos_World,1.0));
o.uv = v.texcoord0;
o.vertex_color = v.color;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
half2 uv1 = i.uv.xy;
// base 主贴图
float3 base_color = tex2D(_BaseMap,uv1).rgb;
// 找出最亮的部分
float maxComponent = max(max(base_color.r,base_color.g),base_color.b) - 0.004;
float3 saturatedColor = step(maxComponent.rrr,base_color) * base_color;
saturatedColor = lerp(base_color.rgb,saturatedColor,0.6);
float3 outLineColor = 0.8 * saturatedColor * base_color * _OutLineColor.xyz;
return float4(outLineColor,1.0);
}
ENDCG
}
}
}
任重而道远, 都是自己熟悉的最基础的知识 ,然而只能看别人写完的东西爽歪歪, 尤其是对贴图资源的把控,太需要补充了!!!