US3S9L3——滚动的背景
US3S9L3——滚动的背景
本章代码关键字
1 | frac() // 一般用于保留小数部分,但对负数使用会得到(1 - 小数部分) |
获取小数部分
CG 内置函数 frac(参数)
,一般用于保留数值的小数部分,但是负数时要注意,会得到 (1 - 小数部分)
该函数的内部计算规则为:frac(x) = x - floor(x)
,比如:
-
frac(2.5) = 2.5 - 2 = 0.5
-
frac(3.75) = 3.75 - 3 = 0.75
-
frac(-0.25) = -0.25 - (-1) = 0.75
-
frac(-3.75) = -3.75 - (-4) = 0.25
它的主要作用是可以帮助我们保证 uv 坐标 范围在 0~1 之间,相当于
- 大于 1 的 uv 值重新从 0 开始向 1 方向取值
- 小于 0 的 uv 值重新从 1 开始向 0 方向取值
分析利用纹理坐标制作滚动的背景的原理
注意点:滚动的背景使用的美术资源图片,往往是首尾循环相连的
基本原理:不停地利用时间变量对 uv 坐标进行偏移运算,超过 1 的部分从 0 开始采样,小于 0 的部分从 1 开始采样
以下图为例制作滚动背景:
用 Shader 实现滚动的背景
-
新建 Shader,删除无用代码
-
声明属性,属性映射
主纹理、U 轴速度、V 轴速度(两个速度的原因是因为图片可能竖直或水平滚动)
1
2
3
4
5
6Properties
{
_MainTex ("Texture", 2D) = "white" {}
_ScrollSpeedU("ScrollSpeedU", float) = 0.5
_ScrollSpeedV("ScrollSpeedV", float) = 0.5
} -
设置透明 Shader 相关内容
往往这种序列帧图集图片都会有透明区域,因此需要使用透明混合相关的设置,具体详见:US3S3L5——透明度混合
修改渲染标签的渲染类型为透明,队列为透明,并忽略投影机
关闭深度写入,开启混合,需要使用SrcAlpha OneMinusSrcAlpha
混合1
2
3
4
5
6
7
8
9
10
11
12
13SubShader
{
Tags { "RenderType"="Transparent" "IgnoreProjector"="True" "Queue"="Transparent"}
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
//...
ENDCG
} -
结构体
顶点和纹理坐标
1
2
3
4
5
6
7
8
9
10struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _ScrollSpeedU;
float _ScrollSpeedV; -
顶点着色器
顶点坐标转换,纹理坐标直接赋值
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 坐标进行偏移计算
- 利用偏移后的 uv 坐标进行采样
1
2
3
4
5
6fixed4 frag (v2f i) : SV_Target
{
// 利用时间来计算UV的偏移,因为时间一直在变化,因此最终的UV坐标也不停在变,使用frac是确保uv坐标处于0~1范围内
float2 scrollUV = frac(i.uv + float2(_Time.y * _ScrollSpeedU, _Time.y * _ScrollSpeedV));
return tex2D(_MainTex, scrollUV);
}
显示效果:
完整 Shader 代码如下:
1 | Shader "TeachShader/Lesson93_ScrollingBackground" |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 文KRIFE齐的博客!