UnityShader学习——内置时间变量及其应用

本文介绍了Unity Shader中内置的时间变量及其在纹理动画和顶点动画中的应用,如序列帧动画、滚动背景、流动的河流、广告牌效果等。通过Shader关键代码展示了如何利用时间变量创建动态视觉效果,同时讨论了顶点动画性能下降的处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内置时间变量

动画效果往往都是把时间添加到一些变量的计算中,以便在时间变化时画面也可以随之变化。Unity Shader提供了一系列关于时间的内置变量来允许我们方便地在Shader中访问运行时间,实现各种动画效果。表11.1给出了这些内置的时间变量。
在这里插入图片描述

时间变量应用

1.纹理动画

纹理动画在游戏中的应用非常广泛。尤其在各种资源都比较局限的移动平台上,我们往往会使用纹理动画来代替复杂的粒子系统等模拟各种动画效果。

(1)序列帧动画
  • 原理:最常见的纹理动画之一就是序列帧动画。依次播放一系列关键帧图像,当播放速度达到一定数值时,看起来就是一个连续的动画。
  • 优点:灵活性很强,我们不需要进行任何物理计算就可以得到非常细腻的动画效果。
  • 缺点:由于序列帧中每张关键帧图像都不一样,要制作一张出色的序列帧纹理所需要的美术工程量也比较大。

要想实现序列帧动画,我们先要提供一张包含了关键帧图像的图像,由于是透明纹理,因此需要勾选该纹理的Alpha Is Transparency属性)。下面的图像包含了8 × 8张关键帧图像,它们的大小相同,而且播放顺序为从左到右、从上到下(在Unity中纹理坐标竖直方向的顺序(从下到上逐渐增大)和序列帧纹理中的顺序(播放顺序是从上到下)是相反的 )。

在这里插入图片描述 在这里插入图片描述

我们需要在每个时刻计算该时刻下应该播放的关键帧的位置,并对该关键帧进行纹理采样。

Shader关键代码如下:

Shader "Unity Shaders Book/Chapter 11/Image Sequence Animation" {
   
	Properties {
   
		_Color ("Color Tint", Color) = (1, 1, 1, 1)
		//包含了所有关键帧图像的纹理
		_MainTex ("Image Sequence", 2D) = "white" {
   }
		//该图像在水平方向和竖直方向包含的关键帧图像的个数
    	_HorizontalAmount ("Horizontal Amount", Float) = 4
    	_VerticalAmount ("Vertical Amount", Float) = 4
    	//控制序列帧动画的播放速度
    	_Speed ("Speed", Range(1, 100)) = 30
	}
	SubShader {
   
		//由于序列帧图像通常是透明纹理,我们需要设置Pass的相关状态,以渲染透明效果
		Tags {
   "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}		
		Pass {
   
			Tags {
    "LightMode"="ForwardBase" }			
			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha			
			
			CGPROGRAM			
			......			
			fixed4 frag (v2f i) : SV_Target {
   
				//【1】把_Time.y和速度属性_Speed相乘来得到模拟的时间
				//并使用CG的floor函数对结果值取整来得到整数时间time
				float time = floor(_Time.y * _Speed);  
				//【2】每个时刻需要播放的关键帧在纹理中的位置,是该关键帧所在的行列索引数
				//使用time除以_HorizontalAmount的结果值的商来作为当前对应的行索引
				float row = floor(time / _HorizontalAmount);
				//除法结果的余数则是列索引
				float column = time - row * _HorizontalAmount;
				//【3】使用行列索引值来构建真正的采样坐标
				//把原纹理坐标i.uv按行数和列数进行等分,得到每个子图像的纹理坐标范围
				//使用当前的行列数对上面的结果进行偏移,得到当前子图像的纹理坐标
				half2 uv = float2(i.uv.x /_HorizontalAmount, i.uv.y / _VerticalAmount);
				uv.x += column / _HorizontalAmount;
				uv.y -= row / _VerticalAmount;//对竖直方向的坐标偏移需要使用减法

				fixed4 c = tex2D(_MainTex, uv);
				c.rgb *= _Color;
				
				return c;
			}
			
			ENDCG
		}  
	}

	FallBack "Transparent/VertexLit"
}
(2)滚动背景

很多2D游戏都使用了不断滚动的背景来模拟游戏角色在场景中的穿梭,这些背景往往包含了多个层(layers)来模拟一种视差效果。而这些背景的实现往往就是利用了纹理动画。

Shader关键代码:

	Properties {
   
		//第一层(较远)和第二层(较近)的背景纹理
		_MainTex ("Base Layer (RGB)", 2D) = "white" {
   }
		_DetailTex (
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值