US3S8L11——Shader代码动态生成程序纹理
US3S8L11——Shader代码动态生成程序纹理
Shader代码动态生成程序纹理
本章使用知识点包括:
国际象棋棋盘格规则:格子的行列编号同奇同偶则为白色,不同则为黑色
数学知识回顾
- 两个奇数相加结果为偶数
- 两个偶数相加结果为偶数
- 一个奇数和一个偶数相加的结果是奇数
向下取整计算
Shader 中的内置函数 floor()
(属于 UnityCG.cginc),该函数需要传入一个数值 floor(数值)
,会对传入数值向下取整
比如:
-
floor(2.6)
返回2
-
floor(0.4)
返回0
-
floor(-2.3)
返回-3
Shader 代码动态计算国际象棋棋盘格纹理
-
新建 Shader,删除无用代码
-
声明属性
- 平铺数量(行列数):
_TileCount
- 格子颜色1:
_Color1
- 格子颜色2:
_Color2
1
2
3
4
5
6Properties
{
_TileCount("TileCount", Float) = 8
_Color1("Color1", Color) = (1, 1, 1, 1)
_Color1("Color2", Color) = (0, 0, 0, 0)
} - 平铺数量(行列数):
-
v2f
结构体顶点和uv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
float _TileCount;
float4 _Color1;
float4 _Color2;
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
}; -
顶点着色器
- 顶点坐标转换
-
uv
直接赋值
1
2
3
4
5
6
7v2f vert (appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
} -
片元着色器
uv * 行列数
将 0 ~ 1 范围 变为 0 ~_TileCount
范围- 利用
floor
得到行列格子编号 - 利用奇偶相加规律得到 0、1 值,0 代表同奇或同偶,1 代表不同
- 利用该值决定该像素使用哪种颜色
1
2
3
4
5
6
7fixed4 frag (v2f i) : SV_Target
{
float2 uv = i.uv * _TileCount; // 将uv坐标从 0~1 范围 变为 0~_TileCount 范围
float2 posIndex = floor(uv); // 得到当前uv坐标所在格子的索引位置
float value = (posIndex.x + posIndex.y) % 2; // 这里的结果只会是0或1,如果是0即为同偶或同奇,1即为不同
return lerp(_Color1, _Color2, value); // 因为value只会是0或1,故lerp的值也是在两个颜色里二选一
}
显示效果:
完整 Shader 如下:
1 | Shader "TeachShader/Lesson89_ShaderPT" |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 文KRIFE齐的博客!