【Unity3D】卷轴特效
1 原理
当一个圆在地面上沿直线匀速滚动时,圆上固定点的运动轨迹称为旋轮线(或摆线、圆滚线)。本文实现的卷轴特效使用了旋轮线相关理论。
以下是卷轴特效原理及公式推导,将屏幕坐标 (x) 映射到纹理坐标 (u)。

注意:屏幕坐标 x 值域为 [0, ScreenWidth],这里已归一化到 [0, 1]。
本文代码资源见→Unity3D Shader卷轴滚动特效。
2 代码实现
RollEffect.cs
using UnityEngine;
[RequireComponent(typeof(Camera))] // 屏幕后处理特效一般都需要绑定在像机上
public class RollEffect : MonoBehaviour {
public float radius = 0.05f; // 圆半径
public float rollSpeed = 0.8f; // 圆滚动角速度
private Texture rollTex; // 滚动轴纹理
private Texture backTex; // 底部背景纹理
private float rollTime = 0; // 滚动时间
private float maxRollTime; // 最长滚动时间
private float rollDirection = 1; // 滚动方向(1: 向右, -1: 向左)
private Material rollMaterial; // 滚动特效材质
private bool enableRoll = false; // 滚动特效开关
private void Awake() {
rollMaterial = new Material(Shader.Find("Custom/Curl/Roll"));
rollMaterial.hideFlags = HideFlags.DontSave;
rollTex = Resources.Load<Texture>("RollTex");
backTex = Resources.Load<Texture>("BackTex");
}
private void Update() {
if (Input.GetMouseButton(0)) {
rollTime = 0;
maxRollTime = 1 / rollSpeed / radius;
enableRoll = true;
}
}
private void OnRenderImage (RenderTexture source, RenderTexture destination) {
if (enableRoll) {
rollMaterial.SetTexture("_RollTex", rollTex);
rollMaterial.SetTexture("_BackTex", backTex);
rollMaterial.SetFloat("_theta", rollSpeed);
rollMaterial.SetFloat("_r", radius);
rollMaterial.SetFloat("_t", rollTime);
IncreaseTime();
Graphics.Blit (source, destination, rollMaterial);
} else {
Graphics.Blit (source, destination);
}
}
private void IncreaseTime() { // 时间自增
rollTime += rollDirection * Time.deltaTime;
if (rollTime > maxRollTime) {
rollTime = maxRollTime;
rollDirection = -rollDirection; // 反向卷轴
} else if (rollTime < 0) {
rollTime = 0;
rollDirection = -rollDirection;
}
}
}
说明: RollEffect 脚本组件需要挂在相机上。
Roll.shader
Shader "Custom/Curl/Roll"
{
Properties
{
_MainTex ("mainTex", 2D) = "white" {}
_RollTex ("rollTex", 2D) = "white" {}
_BackTex ("backTex", 2D) = "white" {}
}
SubShader
{
Pass
{
ZTest Always
Cull Off
ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma vertex vert_img // UnityCG.cginc中定义了vert_img方法, 对vertex和texcoord进行了处理, 输出v2f_img中的pos和uv
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _RollTex; // 滚动轴纹理
sampler2D _BackTex; // 底部背景纹理
float _theta; // 圆滚动角速度
float _r; // 圆半径
float _t; // 滚动时间
fixed4 roll(float rho, float v)
{ // 滚动变换, 将屏幕坐标映射到纹理坐标
float trt = _theta * _r * _t;
if (rho < trt - _r)
{
return tex2D(_BackTex, float2(rho, v));
}
else if (rho < trt)
{
float a = trt - rho;
float phi = acos(a / _r);
float u = trt - (UNITY_HALF_PI + phi) * _r;
if (u > 0)
{
return tex2D(_RollTex, float2(u, v)) * pow(sin(phi), 2);
}
u = trt - (UNITY_HALF_PI - phi) * _r;
return tex2D(_MainTex, float2(u, v)); // 刚开始卷动时会触发
}
else if (rho < trt + _r)
{
float a = rho - trt;
float phi = acos(a / _r);
float u = trt - (3 * UNITY_HALF_PI - phi) * _r;
if (u > 0)
{
return tex2D(_RollTex, float2(u, v)) * pow(sin(phi), 2);
}
return tex2D(_MainTex, float2(rho, v)); // 刚开始卷动时会触发
}
else
{
return tex2D(_MainTex, float2(rho, v));
}
}
fixed4 frag(v2f_img i) : SV_Target // uv坐标的计算不能在顶点着色器中进行, 因为屏后处理的顶点只有屏幕的4个角顶点
{
return roll(i.pos.x / _ScreenParams.x, i.uv.y);
}
ENDCG
}
}
Fallback off
}
3 运行效果

4 推荐阅读
声明:本文转自【Unity3D】卷轴特效
【Unity3D】卷轴特效的更多相关文章
- Unity3d学习 预设体(prefab)的一些理解
之前一直在想如果要在Unity3d上创建很多个具有相同结构的对象,是如何做的,后来查了相关资料发现预设体可以解决这个问题! 预设体的概念: 组件的集合体 , 预制物体可以实例化成游戏对象. 创建预设体 ...
- Unity3d入门 - 关于unity工具的熟悉
上周由于工作内容较多,花在unity上学习的时间不多,但总归还是学习了一些东西,内容如下: .1 根据相关的教程在mac上安装了unity. .2 学习了unity的主要的工具分布和对应工具的相关的功 ...
- TDD在Unity3D游戏项目开发中的实践
0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...
- warensoft unity3d 更新说明
warensoft unity3d 组件的Alpha版本已经发布了将近一年,很多网友发送了改进的Email,感谢大家的支持. Warensoft Unity3D组件将继续更新,将改进的功能如下: 1. ...
- Unity3D框架插件uFrame实践记录(一)
1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...
- Unity3D 5.3 新版AssetBundle使用方案及策略
1.概览 Unity3D 5.0版本之后的AssetBundle机制和之前的4.x版本已经发生了很大的变化,一些曾经常用的流程已经不再使用,甚至一些老的API已经被新的API所取代. 因此,本文的主要 ...
- 山寨Unity3D?搜狐畅游的免费开源游戏引擎Genesis-3D
在CSDN上看到了<搜狐畅游发布3D游戏引擎Genesis-3D 基于MIT协议开源>(http://www.csdn.net/article/2013-11-21/2817585-cha ...
- 从Unity3D编译器升级聊起Mono
接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识. Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的M ...
- Unity3D和Egret3D的基情
Unity3D依靠多平台发布这个核心特点,目前如日中天,屌丝引擎之王绝无来者.Egret白鹭引擎,也着实在微信上刷了一屏又一屏.这二者似乎风马牛不相及,但是这个无处不搞基的年代,让一切皆有可能. U3 ...
- Egret3D研究报告(二)从Unity3D导出场景到Egret3D
Egret3D暂时没有场编的计划,但是我们知道unity3D是一个很好的场编. 有一些游戏即使不是使用Unity3D开发,也使用Unity3D做场编.这里就不点名了,而且并不在少数. 我们就这么干. ...
随机推荐
- 07-verilog & sytem verilog
一.数据类型 二值逻辑变量 bit 不赋值的时候,变量初始默认为0 x或z的值会转变为0 bit vector--bit矢量 bit [msb,lsb] variable_name = [initia ...
- 【Linux】技术收集
Linux进程间通信(六)---信号量通信之semget().semctl().semop()及其基础实验 https://blog.csdn.net/mybelief321/article/deta ...
- 处理命令行main函数args参数
引用 System.CommandLine 库(需要显示预览版才能看到) var fileOption = new Option<FileInfo?>( name: "--fil ...
- [转帖]shell编程:变量的数值计算实践(五)
https://www.cnblogs.com/luoahong/articles/9224495.html 算术运算符 变量的数值(整数)计算 1)(())用法:(此方法很常用)** 范例:sh ...
- [转帖]nginx中的if和else语法
https://www.dyxmq.cn/it/nginx/nginx-if.html nginx支持if语法,语法和平常的代码格式差不多: 1 2 3 if ($xxx = xxx) { ...
- [转帖]龙叔学ES:Elasticsearch XPACK安全认证
https://juejin.cn/post/7081994919237287950 本文已参与「新人创作礼」活动,一起开启掘金创作之路. Elasticsearch往往存有公司大量的数据,如果安全不 ...
- [转帖]5、kafka监控工具Kafka-Eagle介绍及使用
https://zhuanlan.zhihu.com/p/628039102 # Apache Kafka系列文章 1.kafka(2.12-3.0.0)介绍.部署及验证.基准测试 2.java调 ...
- [转帖]jcmd命令详解
1 基本知识 jcmd 是在 JDK1.7 以后,新增了一个命令行工具. jcmd 是一个多功能的工具,相比 jstat 功能更为全面的工具,可用于获取目标 Java 进程的性能统计.JFR.内存使用 ...
- [转帖]021系统状态检测命令sosreport
https://www.cnblogs.com/anyoneofus/p/16467677.html sosreport命令用于收集系统配置及架构信息并输出诊断文档.
- 2024年最新的Python操控微信教程
自从微信禁止网页版登陆之后,itchat 库实现的功能也就都不能用了,那现在 Python 还能操作微信吗?答案是:可以! 在Github上有一个项目叫<WeChatPYAPI>可以使用 ...