最终效果
默认效果
不然不做处理,我们的模型默认效果
简单粗暴,使用Unlit/Texture
最粗暴的方式就是直接使用Unlit材质,在贴图上表现出卡通效果。
我们把材质球的shader全部改成Unlit/Texture(也就是无光照模型,直接显示贴图纹理)
效果,当然,这过于简单了,缺点很明显,没有光照效果。
基于光照模型的卡通渲染UnityToonShader——仅支持内置渲染管线
基于光照模型的卡通渲染,在GitHub上有一个项目,地址:https://github.com/Sorumi/UnityToonShader
ToonMultiStepsShader.shader代码我复制下来了
Shader "Toon/Basic/MultiSteps"
{
Properties
{
// Colors
_Color ("Color", Color) = (1, 1, 1, 1)
_HColor ("Highlight Color", Color) = (0.8, 0.8, 0.8, 1.0)
_SColor ("Shadow Color", Color) = (0.2, 0.2, 0.2, 1.0)
// texture
_MainTex ("Main Texture", 2D) = "white" { }
// ramp
_ToonSteps ("Steps of Toon", range(1, 9)) = 2
_RampThreshold ("Ramp Threshold", Range(0.1, 1)) = 0.5
_RampSmooth ("Ramp Smooth", Range(0, 1)) = 0.1
// specular
_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
_SpecSmooth ("Specular Smooth", Range(0, 1)) = 0.1
_Shininess ("Shininess", Range(0.001, 10)) = 0.2
// rim light
_RimColor ("Rim Color", Color) = (0.8, 0.8, 0.8, 0.6)
_RimThreshold ("Rim Threshold", Range(0, 1)) = 0.5
_RimSmooth ("Rim Smooth", Range(0, 1)) = 0.1
}
SubShader
{
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Toon addshadow fullforwardshadows exclude_path:deferred exclude_path:prepass
#pragma target 3.0
fixed4 _Color;
fixed4 _HColor;
fixed4 _SColor;
sampler2D _MainTex;
float _RampThreshold;
float _RampSmooth;
float _ToonSteps;
float _SpecSmooth;
fixed _Shininess;
fixed4 _RimColor;
fixed _RimThreshold;
float _RimSmooth;
struct Input
{
float2 uv_MainTex;
float3 viewDir;
};
float linearstep(float min, float max, float t)
{
return saturate((t - min) / (max - min));
}
inline fixed4 LightingToon(SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{
half3 normalDir = normalize(s.Normal);
half3 halfDir = normalize(lightDir + viewDir);
float ndl = max(0, dot(normalDir, lightDir));
float ndh = max(0, dot(normalDir, halfDir));
float ndv = max(0, dot(normalDir, viewDir));
// multi steps
float diff = smoothstep(_RampThreshold - ndl, _RampThreshold + ndl, ndl);
float interval = 1 / _ToonSteps;
// float ramp = floor(diff * _ToonSteps) / _ToonSteps;
float level = round(diff * _ToonSteps) / _ToonSteps;
float ramp ;
if (_RampSmooth == 1)
{
ramp = interval * linearstep(level - _RampSmooth * interval * 0.5, level + _RampSmooth * interval * 0.5, diff) + level - interval;
}
else
{
ramp = interval * smoothstep(level - _RampSmooth * interval * 0.5, level + _RampSmooth * interval * 0.5, diff) + level - interval;
}
ramp = max(0, ramp);
ramp *= atten;
_SColor = lerp(_HColor, _SColor, _SColor.a);
float3 rampColor = lerp(_SColor.rgb, _HColor.rgb, ramp);
// specular
float spec = pow(ndh, s.Specular * 128.0) * s.Gloss;
spec *= atten;
spec = smoothstep(0.5 - _SpecSmooth * 0.5, 0.5 + _SpecSmooth * 0.5, spec);
// rim
float rim = (1.0 - ndv) * ndl;
rim *= atten;
rim = smoothstep(_RimThreshold - _RimSmooth * 0.5, _RimThreshold + _RimSmooth * 0.5, rim);
fixed3 lightColor = _LightColor0.rgb;
fixed4 color;
fixed3 diffuse = s.Albedo * lightColor * rampColor;
fixed3 specular = _SpecColor.rgb * lightColor * spec;
fixed3 rimColor = _RimColor.rgb * lightColor * _RimColor.a * rim;
color.rgb = diffuse + specular + rimColor;
color.a = s.Alpha;
return color;
}
void surf(Input IN, inout SurfaceOutput o)
{
fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = mainTex.rgb * _Color.rgb;
o.Alpha = mainTex.a * _Color.a;
o.Specular = _Shininess;
o.Gloss = mainTex.a;
}
ENDCG
}
FallBack "Diffuse"
}
- 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
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
将shader导入Unity工程中
把材质球的shader改为Toon/Basic/MultiSteps,
调整一下高光、阴影、渐变阈值、镜面、边缘等参数
效果演示,可以看到模型受光照影响了
基于光照模型的二次元渲染UnityURPToonLitShaderExample——仅支持URP渲染管线
升级URP项目可以看我这篇文章:【unity小技巧】为啥我们的模型材质显示粉色?unity普通项目升级URP项目
GitHub地址:https://github.com/ColinLeung-NiloCat/UnityURPToonLitShaderExample
演示效果
将整个文件导入unity‘中
修改人材质为SimpleURPToonLitExample(With Outline)
如果材质丢失贴图了,记得手动赋值贴图即可
效果
如果我不希望面部显示不那么黑且更加精致,可以勾选下面这个选项
效果
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~



评论记录:
回复评论: