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. PC 网页 布局图

  2. Cloudquery的学习安装与使用

    Cloudquery的学习安装与使用 下载 官方下载地址: https://www.cloudquery.club/download https://pan.baidu.com/s/1a7XOrnMU ...

  3. [转帖]TiKV 缩容不掉如何解决?

    TiKV节点缩容不掉,通常遇到的情况: 1.经常遇到的情况是:3个节点的tikv集群缩容肯定会一直卡着,因为没有新节点接受要下线kv的region peer. 2.另外就是除缩容tikv外,剩下的KV ...

  4. [转帖]技术分享 | 国产麒麟 arm 上编译安装 xtrabackup8

    原创 发布于 2022-07-19 13:29:29 3220 举报 作者:王向 爱可生 DBA 团队成员,负责公司 DMP 产品的运维和客户 MySQL 问题的处理.擅长数据库故障处理.对数据库技术 ...

  5. [转帖]Rust在windows下安装以后cargo build Error: linker `link.exe` not found

    D:\rust\runoob-greeting\greeting>cargo build error: linker `link.exe` not found | = note: 系统找不到指定 ...

  6. [转帖]企业nginx简单配置

    https://www.jianshu.com/p/6a3e298b31be 第五章 企业简单应用 网站访问方式 1.基于域名访问www.baidu.com 基于IP地址访问172.16.1.7配置文 ...

  7. [转帖]一行Python代码实现同一局域网内的文件共享

    在不同的设备之间传输文件除了数据线,网盘传输外是否还有其他优雅的方法?我们可以使用一行Python代码使局域网内的所有设备都可以访问并下载文件夹内的文件. 要求: 电脑中安装配置好python 访问的 ...

  8. [转帖]CKA 真题

    https://segmentfault.com/a/1190000021380185   1.列出pod并排序 kubectl get pod --sort-by .metadata.name 题目 ...

  9. [转帖] Linux命令拾遗-剖析工具

    https://www.cnblogs.com/codelogs/p/16060472.html 简介# 这是Linux命令拾遗系列的第五篇,本篇主要介绍Linux中常用的线程与内存剖析工具,以及更高 ...

  10. 工单 工序外协 更改PR/PO

    工序外协详解介绍'https://blog.csdn.net/weixin_43814706/article/details/113586961' 需求:创建工序委外的工单时更改对应PR/PO 行文本 ...