UintyShader动漫风格渲染效果
Tips:此博客部分基于Siki学院课程!!!
Unity版本
基于Unity2020.3.11LTS
漫反射光照效果
我们通常会在Unity制作的游戏中看到人物角色会有人物描边的效果,例如王者荣耀和原神,如下图所示:
初始效果
初始效果
代码部分
话不多说先上代码!!!
Shader "Unlit/CatToon"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {
}
_Diffuse("Color",Color) = (1,1,1,1)
}
SubShader
{
Tags {
"RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
//结构体
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
//输入结构
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
fixed3 worldNormal:TEXCOORD1;
fixed3 worldPos:TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Diffuse;
v2f vert (appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld,v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 albedo = tex2D(_MainTex,i.uv);
//漫反射
fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
float difLight = dot(worldLightDir,i.worldNormal)*0.5+0.5;//使用半兰伯特模型
fixed3 diffuse = _LightColor0.rgb *albedo *_Diffuse.rgb *difLight;
return float4( ambient + diffuse,1);
}
ENDCG
}
}
}
代码拆分
这一部分代码是Shader中的属性块,此处定义了一个图片纹理采样和基本颜色(白色(1,1,1,1)),此颜色将会用于后面参加漫反射的计算。
Properties
{
_MainTex ("Texture", 2D) = "white" {
}
_Diffuse("Color",Color) = (1,1,1,1)
}
第一个Pass通道中的定义部分,大致意思是定义了顶点着色和片元着色,然后引入了UnityCG和Lighting两个宏。
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
Pass通道中的结构体部分,值得注意的是每个结构体需要在后面加上分号 “;”(这是常见的代码报错原因)
//结构体
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Diffuse;
这一部分是片元着色器部分,使用了光照反射的半兰伯特模型。
fixed4 frag (v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 albedo = tex2D(_MainTex,i.uv);
//漫反射
fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
float difLight = dot(worldLightDir,i.worldNormal)*0.5+0.5;//使用半兰伯特模型
fixed3 diffuse = _LightColor0.rgb *albedo *_Diffuse.rgb *difLight;
return float4( ambient + diffuse,1);
}
最终效果
角色描边
原理
角色描边的原理是,在之前的Pass通道前,加一个Pass通道,画各个片元内的片元,并将边缘外扩形成片元效果,下面将用两种方法实现该效果。
代码部分
一样先上代码
Shader "Unlit/CatToon"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {
}
_Diffuse("Color",Color) = (1,1,1,1)
_Outline("Outline",Range(0,0.2)) = 0.1
_OutlineColor(