简单卡渲的实现 https://roystan.net/articles/toon-shader.html

# 边缘光非描边

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
Shader "Roystan/Toon"
{
Properties
{
_Color("Color", Color) = (0.5, 0.65, 1, 1)
_MainTex("Main Texture", 2D) = "white" {}
[HDR]
_AmbientColor("Ambient Color",Color) = (0.4,0.4,0.4,1)
[HDR]
_SpecularColor("Specular Color",Color) = (0.9,0.9,0.9,1)
_Glossiness("Glossiness",Float) = 32
[HDR]
_RimColor("Rim Color",Color) = (1,1,1,1)
_RimAmount("Rim Amount",Range(0,1)) = 0.716
_RimThreshold("Rim Threshold", Range(0, 1)) = 0.1
}
SubShader
{
Pass
{

Tags{
"LightMode" = "ForwardBase"
"PassFlags" = "OnlyDirectional"
}

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase

#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"

struct appdata
{
float3 normal : NORMAL;
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
};

struct v2f
{
//从对象空间变换到世界空间的法线
float3 worldNormal : NORMAL;
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 viewDir : TEXCOORD1;
SHADOW_COORDS(2)
};

sampler2D _MainTex;
float4 _MainTex_ST;

v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = WorldSpaceViewDir(v.vertex);

TRANSFER_SHADOW(o)
return o;
}

float4 _Color;
float4 _AmbientColor;
float _Glossiness;
float4 _SpecularColor;
float4 _RimColor;
float _RimAmount;
float _RimThreshold;

float4 frag(v2f i) : SV_Target
{
float shadow = SHADOW_ATTENUATION(i);
float3 normal = normalize(i.worldNormal);
//法线与光线方向的点积
float NdotL = dot(_WorldSpaceLightPos0, normal);
//这样阴影交界处会有一些锯齿
//float lightIntensity = NdotL > 0 ? 1 : 0;
//使用smoothstep可以去掉锯齿
float lightIntensity = smoothstep(0, 0.01, NdotL * shadow);
float4 light = lightIntensity * _LightColor0;
float4 sample = tex2D(_MainTex, i.uv);

//镜面反射部分
float3 viewDir = normalize(i.viewDir);
float3 halfVector = normalize(_WorldSpaceLightPos0 + viewDir);
float NdotH = dot(normal, halfVector);
float specularIntensity = pow(NdotH * lightIntensity, _Glossiness * _Glossiness);
//增加镜面反射的突变
float specularIntensitySmooth = smoothstep(0.005, 0.01, specularIntensity);
float4 specular = specularIntensitySmooth * _SpecularColor;

//加边缘光
float4 rimDot = 1 - dot(viewDir, normal);
float rimIntensity = rimDot * pow(NdotL,_RimThreshold);
rimIntensity = smoothstep(_RimAmount - 0.01, _RimAmount + 0.01, rimIntensity);
float4 rim = rimIntensity * _RimColor;

return _Color * sample * (_AmbientColor+ light + specular + rim);
}
ENDCG
}

UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}

# 描边

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
Shader "Roystan/Toon2"
{
Properties
{
_Color("Color", Color) = (0.5, 0.65, 1, 1)
_MainTex("Main Texture", 2D) = "white" {}
[HDR]
_AmbientColor("Ambient Color",Color) = (0.4,0.4,0.4,1)
[HDR]
_SpecularColor("Specular Color",Color) = (0.9,0.9,0.9,1)
_Glossiness("Glossiness",Float) = 32
[HDR]
_RimColor("Rim Color",Color) = (1,1,1,1)
_RimAmount("Rim Amount",Range(0,1)) = 0.716
_RimThreshold("Rim Threshold", Range(0, 1)) = 0.1
}
SubShader
{
Pass
{

Tags{
"LightMode" = "ForwardBase"
"PassFlags" = "OnlyDirectional"
}

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase

#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"

struct appdata
{
float3 normal : NORMAL;
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
};

struct v2f
{
//从对象空间变换到世界空间的法线
float3 worldNormal : NORMAL;
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 viewDir : TEXCOORD1;
SHADOW_COORDS(2)
};

sampler2D _MainTex;
float4 _MainTex_ST;

v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = WorldSpaceViewDir(v.vertex);

TRANSFER_SHADOW(o)
return o;
}

float4 _Color;
float4 _AmbientColor;
float _Glossiness;
float4 _SpecularColor;
float4 _RimColor;
float _RimAmount;
float _RimThreshold;

float4 frag(v2f i) : SV_Target
{
float shadow = SHADOW_ATTENUATION(i);
float3 normal = normalize(i.worldNormal);
//法线与光线方向的点积
float NdotL = dot(_WorldSpaceLightPos0, normal);
//这样阴影交界处会有一些锯齿
//float lightIntensity = NdotL > 0 ? 1 : 0;
//使用smoothstep可以去掉锯齿
float lightIntensity = smoothstep(0, 0.01, NdotL * shadow);
float4 light = lightIntensity * _LightColor0;
float4 sample = tex2D(_MainTex, i.uv);

//镜面反射部分
float3 viewDir = normalize(i.viewDir);
float3 halfVector = normalize(_WorldSpaceLightPos0 + viewDir);
float NdotH = dot(normal, halfVector);
float specularIntensity = pow(NdotH * lightIntensity, _Glossiness * _Glossiness);
//增加镜面反射的突变
float specularIntensitySmooth = smoothstep(0.005, 0.01, specularIntensity);
float4 specular = specularIntensitySmooth * _SpecularColor;

//加边缘光
float4 rimDot = 1 - dot(viewDir, normal);
float rimIntensity = rimDot * pow(NdotL, _RimThreshold);
rimIntensity = smoothstep(_RimAmount - 0.01, _RimAmount + 0.01, rimDot);
float4 rim = rimIntensity * (_RimColor-255);

return _Color * sample * (_AmbientColor+ light + specular + rim);
}
ENDCG
}

UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}
更新于

请我喝[茶]~( ̄▽ ̄)~*

Solvarg 微信支付

微信支付

Solvarg 支付宝

支付宝

Solvarg 贝宝

贝宝