[toc]
如何创建
右键 -> Shader -> Standard Surface Shader
# 一个基于 Lambert 的表面着色器
Shader “Custom/SimplestSurfaceShader”
{
Properties
{
_Color (“Color”, Color) = (1,1,1,1)
_MainTex (“Albedo (RGB)”, 2D) = “white” {}
}
SubShader
{
CGPROGRAM
// 定义表面函数名为 surf, 使用 Lambert
#pragma surface surf Lambert
//Input
struct Input {
float2 uv\_MainTex;
};
sampler2D \_MainTex;
fixed4 \_Color;
void surf(Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(\_MainTex, IN.uv\_MainTex) \* \_Color;
o.Albedo = c.rgb;
}
ENDCG
}
FallBack "Diffuse"
}
直接把漫反射光颜色传给 o 即可
# 在表面着色器中使用法线贴图
法线贴图的作用在于为每个顶点处重新赋值一个新的法线方向,以次用最少的消耗来模拟凹凸不平的效果
Shader “Custom/Bump”
{
Properties
{
_Color (“Color”, Color) = (1,1,1,1)
_MainTex (“Albedo (RGB)”, 2D) = “white” {}
_Normal(“Normal Map”,2D) = “bump” {}
_Bumpiness (“Bumpiness”,Range(0,1)) = 0
}
SubShader
{
CGPROGRAM
// 定义表面函数名为 surf, 使用 Lambert
#pragma surface surf Lambert
//Input
struct Input {
float2 uv\_MainTex;
float2 uv\_Normal;
};
sampler2D \_Normal;
fixed \_Bumpiness;
sampler2D \_MainTex;
fixed4 \_Color;
void surf(Input IN, inout SurfaceOutput o) {
//采样法线贴图并解包
fixed3 n = UnpackNormal(tex2D(\_Normal, IN.uv\_Normal));
n \*= float3(\_Bumpiness, \_Bumpiness, 1);
fixed4 c = tex2D(\_MainTex, IN.uv\_MainTex) \* \_Color;
o.Albedo = c.rgb;
o.Normal = n;
}
ENDCG
}
FallBack "Diffuse"
}
第二组纹理只需要 uv_Normal
即可获取到后缀为 Normal 的
由于法线贴图是压缩到 [0,1] 的,而法线范围是 [-1,1], 所以需要使用 UnpackNormal
函数来解压这个贴图重新映射到 [-1,1].
# 效果
# 流水线操作
# 顶点
尽管 Surface Shader 封装了完整的光照计算流程,但是仍然可以使用
vertex:vert
等函数自定义其中的部分流水线顶点膨胀效果
沿法线方向膨胀, UnityCG.cginc
编写 SurfaceShader 时会自动引用
Shader “Custom/Expand”
{
Properties
{
_Color (“Color”, Color) = (1,1,1,1)
_MainTex (“Albedo (RGB)”, 2D) = “white” {}
_Expansion(“Expansion”,Range(0,0.1)) = 0
}
SubShader
{
CGPROGRAM
// 添加自定义顶点修改函数 vert
#pragma surface surf Lambert vertex:vert
struct Input {
float2 uv\_MainTex;
};
sampler2D \_MainTex;
fixed \_Expansion;
fixed4 \_Color;
//顶点修改函数,输入/输出appdata\_full结构体
void vert(inout appdata\_full v) {
v.vertex.xyz += v.normal \* \_Expansion;
}
void surf(Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D(\_MainTex, IN.uv\_MainTex).rgb \* \_Color;
}
ENDCG
}
FallBack "Diffuse"
}