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】卷轴特效的更多相关文章

  1. Unity3d学习 预设体(prefab)的一些理解

    之前一直在想如果要在Unity3d上创建很多个具有相同结构的对象,是如何做的,后来查了相关资料发现预设体可以解决这个问题! 预设体的概念: 组件的集合体 , 预制物体可以实例化成游戏对象. 创建预设体 ...

  2. Unity3d入门 - 关于unity工具的熟悉

    上周由于工作内容较多,花在unity上学习的时间不多,但总归还是学习了一些东西,内容如下: .1 根据相关的教程在mac上安装了unity. .2 学习了unity的主要的工具分布和对应工具的相关的功 ...

  3. TDD在Unity3D游戏项目开发中的实践

    0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...

  4. warensoft unity3d 更新说明

    warensoft unity3d 组件的Alpha版本已经发布了将近一年,很多网友发送了改进的Email,感谢大家的支持. Warensoft Unity3D组件将继续更新,将改进的功能如下: 1. ...

  5. Unity3D框架插件uFrame实践记录(一)

    1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...

  6. Unity3D 5.3 新版AssetBundle使用方案及策略

    1.概览 Unity3D 5.0版本之后的AssetBundle机制和之前的4.x版本已经发生了很大的变化,一些曾经常用的流程已经不再使用,甚至一些老的API已经被新的API所取代. 因此,本文的主要 ...

  7. 山寨Unity3D?搜狐畅游的免费开源游戏引擎Genesis-3D

    在CSDN上看到了<搜狐畅游发布3D游戏引擎Genesis-3D 基于MIT协议开源>(http://www.csdn.net/article/2013-11-21/2817585-cha ...

  8. 从Unity3D编译器升级聊起Mono

    接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识. Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的M ...

  9. Unity3D和Egret3D的基情

    Unity3D依靠多平台发布这个核心特点,目前如日中天,屌丝引擎之王绝无来者.Egret白鹭引擎,也着实在微信上刷了一屏又一屏.这二者似乎风马牛不相及,但是这个无处不搞基的年代,让一切皆有可能. U3 ...

  10. Egret3D研究报告(二)从Unity3D导出场景到Egret3D

    Egret3D暂时没有场编的计划,但是我们知道unity3D是一个很好的场编. 有一些游戏即使不是使用Unity3D开发,也使用Unity3D做场编.这里就不点名了,而且并不在少数. 我们就这么干. ...

随机推荐

  1. 2023年江苏“领航杯”MISC一个很有意思的题目(别把鸡蛋放在同一个篮子里面)

    别把鸡蛋放在同一个篮子里面 题目附件:https://wwzl.lanzoue.com/i6HmX16finnc 1.题目信息 解压压缩包打开附件,获得5141个txt文档,每个文档都有内容,发现是b ...

  2. 07 - HTTP

    HTTP 强烈推荐学习:HTTP | MDN 一 .基础概念 请求和响应报文 客户端发送一个请求报文给服务器,服务器根据请求报文中的信息进行处理,并将处理结果放入响应报文中返回给客户端. 请求报文结构 ...

  3. [转帖]MySQL如何进行索引重建操作?

    MySQL如何进行索引重建操作? - 潇湘隐者 - 博客园 (cnblogs.com) 在MySQL数据库中,没有类似于SQL Server数据库或Oracle数据库中索引重建的语法(ALTER IN ...

  4. [转帖]存储器分级:L1 Cache 比内存和 SSD 快多少倍?

    目录 1.为什么会有存储器分级策略? 2.存储器分级策略 2.1 存储器的级别 2.2.1 L1-Cache 2.2.2 L2-Cache 2.2.3 L3-Cache 3.内存 4.SSD 和硬盘 ...

  5. [转帖]062、监控指标之PD

    PD相关 Grafana 监控 PD -> PD Dashboard 是否存在异常状态的TiKV Grafana 监控 PD -> Region health 大表清理后,出现了大量的空r ...

  6. [转帖]使用 goofys 挂载 S3 bucket 为文件系统

    https://xie.infoq.cn/article/7f178e0a1315f758d77c6c2bb 背景 公司的 gitlab 目前都是直接存储在物理盘上,为了确保数据不会丢失,需要重复多次 ...

  7. [转帖]kafka 配置认证与授权

    https://www.cnblogs.com/yjt1993/p/14739130.html 本例不使用kerberos做认证,使用用户名和密码的方式来进行认证 1.服务端配置 1.0 配置serv ...

  8. [转帖]Redis中的Lua脚本

    最近琢磨分布式锁时接触到的知识点,简单记一下. 文章目录 1. Redis中的Lua 2. 利用Lua操作Redis 3. Lua脚本的原子性 4. 关于 EVALSHA 5. 常用`SCRIPT` ...

  9. [转帖] Linux文本命令技巧(下)

    https://www.cnblogs.com/codelogs/p/16060108.html 简介# 前一篇介绍了Linux中一些基本的文本命令与使用技巧,但是结合场景过少,本篇结合工作中一些常见 ...

  10. bcc工具的简要学习

    摘要 继续补充假期落下的内容. 其实有很多知识需要学习, 自己掌握的还是偏少一些. bcc的全貌 # 注意 bcc 需要较高的内核. 3.10 系列的内核基本不可用. argdist drsnoop ...