47.动态效果-纹理动画-滚动的背景
47.1 知识点
知识补充:内置函数 frac
frac
是一个内置函数,用于计算数值的小数部分,其公式为:
frac(x) = x - floor(x)
特性及应用
- 主要作用是保留数值的小数部分。
- 对于正数,直接取小数部分:
frac(2.5) = 2.5 - 2 = 0.5
frac(3.75) = 3.75 - 3 = 0.75
- 对于负数,小数部分重新从 0 开始计数:
frac(-0.25) = -0.25 - (-1) = 0.75
frac(-3.75) = -3.75 - (-4) = 0.25
UV 坐标中的应用
- 保证 UV 坐标始终在
[0, 1]
范围内。 - 对 UV 值进行循环处理:
- 大于 1 的 UV 值从 0 开始重新取值。
- 小于 0 的 UV 值从 1 开始反向取值。
准备工作
- 导入滚动背景的美术资源。
- 准备测试场景,确保资源图片首尾循环连接。
利用纹理坐标实现滚动背景的原理
注意点
- 滚动背景的图片通常首尾循环相连,保证视觉上的无缝过渡。
基本原理
- 利用时间变量动态偏移 UV 坐标。
- UV 坐标超过 1 时,自动从 0 重新采样。
- UV 坐标小于 0 时,自动从 1 反向采样。
Shader 实现滚动背景
新建Shader,删除无用代码,保留骨架
Shader "Unlit/Lesson47_ScrollingBackground"
{
Properties
{
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
ENDCG
}
}
}
声明属性和属性映射,包括主纹理、U轴速度、V轴速度(两个速度的原因是因为图片可能竖直或水平滚动)
Properties
{
// 主纹理
_MainTex ("Texture", 2D) = "white" {}
// 水平滚动速度
_ScrollSpeedU ("ScrollSpeedU", float) = 0.5
// 竖直滚动速度
_ScrollSpeedV ("ScrollSpeedV", float) = 0.5
}
sampler2D _MainTex; // 主纹理采样器
float _ScrollSpeedU; // 水平滚动速度
float _ScrollSpeedV; // 竖直滚动速度
设置为透明Shader,修改渲染标签、关闭深度写入、进行透明混合,因为往往这种滚动背景图片都会有透明区域
Tags
{
// 渲染类型为透明
"RenderType"="Transparent"
// 渲染队列设置为透明队列
"Queue"="Transparent"
// 忽略投影器
"IgnoreProjector"="True"
}
Pass
{
// 关闭深度写入
ZWrite Off
// 设置混合模式为源颜色的透明度与目标颜色的反透明度进行混合
Blend SrcAlpha OneMinusSrcAlpha
//...
}
声明结构体,包括顶点和纹理坐标
struct v2f
{
// UV 坐标,用于纹理采样
float2 uv : TEXCOORD0;
// 顶点在裁剪空间中的位置
float4 vertex : SV_POSITION;
};
顶点函数把顶点坐标转换成裁剪空间,纹理uv坐标直接赋值
// 顶点着色器函数
v2f vert(appdata_base appdata_base)
{
// 创建结构体变量
v2f v2f;
// 将顶点从模型空间转换到裁剪空间
v2f.vertex = UnityObjectToClipPos(appdata_base.vertex);
// 获取顶点的原始 UV 坐标
v2f.uv = appdata_base.texcoord;
// 返回结构体变量
return v2f;
}
片元函数利用时间和速度对uv坐标进行偏移计算偏移后的uv坐标并进行采样
// 片元着色器函数
fixed4 frag(v2f v2f) : SV_Target
{
// 根据时间和滚动速度计算 UV 坐标的偏移量
// frac 函数用于获取小数部分,使得 UV 坐标在 0 到 1 之间循环变化
float2 scrollUV = frac(v2f.uv + float2(_Time.y * _ScrollSpeedU, _Time.y * _ScrollSpeedV));
// 使用计算后的 UV 坐标进行纹理采样并返回颜色值
return tex2D(_MainTex, scrollUV);
}
创建4个贴图的对应shader,调整v轴速度为0,可以看到滚动效果
总结
- 图片资源规范:滚动背景的资源必须首尾无缝衔接。
- 核心实现:使用
frac
函数将 UV 坐标限制在[0, 1]
范围内,实现循环滚动。 - 灵活调整:通过修改滚动速度控制背景滚动的方向和速度。
47.2 知识点代码
Lesson47_动态效果_纹理动画_滚动的背景.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson47_动态效果_纹理动画_滚动的背景 : MonoBehaviour
{
void Start()
{
#region 知识补充 内置函数frac
//内置函数 frac(参数)
//该函数的内部计算规则为:
//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方向取值
#endregion
#region 准备工作
//导入测试用资源
#endregion
#region 知识点一 分析利用纹理坐标制作滚动的背景的原理
//注意点:
//滚动的背景使用的美术资源图片,往往是首尾循环相连的
//基本原理:
//不停地利用时间变量对uv坐标进行偏移运算
//超过1的部分从0开始采样
//小于0的部分从1开始采样
#endregion
#region 知识点二 用Shader实现滚动的背景
//1.新建Shader,删除无用代码
//2.声明属性,属性映射
// 主纹理、U轴速度、V轴速度(两个速度的原因是因为图片可能竖直或水平滚动)
//3.透明Shader
// 往往这种滚动背景图片都会有透明区域
// 渲染标签修改、关闭深度写入、进行透明混合
//4.结构体
// 顶点和纹理坐标
//5.顶点着色器
// 顶点坐标转换,纹理坐标直接赋值
//6.片元着色器
// 利用时间和速度对uv坐标进行偏移计算
// 利用偏移后的uv坐标进行采样
#endregion
#region 总结
//Shader实现滚动的背景的关键点
//1.纹理图片必须按规范制作,“首尾相连”
//2.利用内置时间变量对纹理坐标进行偏移计算
#endregion
}
}
Lesson47_ScrollingBackground.shader
Shader "Unlit/Lesson47_ScrollingBackground"
{
Properties
{
// 主纹理属性
_MainTex ("Texture", 2D) = "white" {}
// 水平滚动速度属性
_ScrollSpeedU("ScrollSpeedU", float) = 0.5
// 竖直滚动速度属性
_ScrollSpeedV("ScrollSpeedV", float) = 0.5
}
SubShader
{
Tags
{
// 渲染类型为透明
"RenderType"="Transparent"
// 渲染队列设置为透明队列
"Queue"="Transparent"
// 忽略投影器
"IgnoreProjector"="True"
}
Pass
{
// 关闭深度写入
ZWrite Off
// 设置混合模式为源颜色的透明度与目标颜色的反透明度进行混合
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// 主纹理采样器
sampler2D _MainTex;
// 水平滚动速度
float _ScrollSpeedU;
// 竖直滚动速度
float _ScrollSpeedV;
struct v2f
{
// UV 坐标,用于纹理采样
float2 uv : TEXCOORD0;
// 顶点在裁剪空间中的位置
float4 vertex : SV_POSITION;
};
// 顶点着色器函数
v2f vert(appdata_base appdata_base)
{
// 创建结构体变量
v2f v2f;
// 将顶点从模型空间转换到裁剪空间
v2f.vertex = UnityObjectToClipPos(appdata_base.vertex);
// 获取顶点的原始 UV 坐标
v2f.uv = appdata_base.texcoord;
// 返回结构体变量
return v2f;
}
// 片元着色器函数
fixed4 frag(v2f v2f) : SV_Target
{
// 根据时间和滚动速度计算 UV 坐标的偏移量
// frac 函数用于获取小数部分,使得 UV 坐标在 0 到 1 之间循环变化
float2 scrollUV = frac(v2f.uv + float2(_Time.y * _ScrollSpeedU, _Time.y * _ScrollSpeedV));
// 使用计算后的 UV 坐标进行纹理采样并返回颜色值
return tex2D(_MainTex, scrollUV);
}
ENDCG
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com