1 原理

​ 当一个圆在地面上沿直线匀速滚动时,圆上固定点的运动轨迹称为旋轮线(或摆线、圆滚线)。本文实现的卷轴特效使用了旋轮线相关理论。

​ 以下是卷轴特效原理及公式推导,将屏幕坐标 (x) 映射到纹理坐标 (u)。

​ 注意:屏幕坐标 x 值域为 [0, ScreenWidth],这里已归一化到 [0, 1]。

​ 本文代码资源见→Unity3D Shader卷轴滚动特效

2 代码实现

​ RollEffect.cs

  1. using UnityEngine;
  2. [RequireComponent(typeof(Camera))] // 屏幕后处理特效一般都需要绑定在像机上
  3. public class RollEffect : MonoBehaviour {
  4. public float radius = 0.05f; // 圆半径
  5. public float rollSpeed = 0.8f; // 圆滚动角速度
  6. private Texture rollTex; // 滚动轴纹理
  7. private Texture backTex; // 底部背景纹理
  8. private float rollTime = 0; // 滚动时间
  9. private float maxRollTime; // 最长滚动时间
  10. private float rollDirection = 1; // 滚动方向(1: 向右, -1: 向左)
  11. private Material rollMaterial; // 滚动特效材质
  12. private bool enableRoll = false; // 滚动特效开关
  13. private void Awake() {
  14. rollMaterial = new Material(Shader.Find("Custom/Curl/Roll"));
  15. rollMaterial.hideFlags = HideFlags.DontSave;
  16. rollTex = Resources.Load<Texture>("RollTex");
  17. backTex = Resources.Load<Texture>("BackTex");
  18. }
  19. private void Update() {
  20. if (Input.GetMouseButton(0)) {
  21. rollTime = 0;
  22. maxRollTime = 1 / rollSpeed / radius;
  23. enableRoll = true;
  24. }
  25. }
  26. private void OnRenderImage (RenderTexture source, RenderTexture destination) {
  27. if (enableRoll) {
  28. rollMaterial.SetTexture("_RollTex", rollTex);
  29. rollMaterial.SetTexture("_BackTex", backTex);
  30. rollMaterial.SetFloat("_theta", rollSpeed);
  31. rollMaterial.SetFloat("_r", radius);
  32. rollMaterial.SetFloat("_t", rollTime);
  33. IncreaseTime();
  34. Graphics.Blit (source, destination, rollMaterial);
  35. } else {
  36. Graphics.Blit (source, destination);
  37. }
  38. }
  39. private void IncreaseTime() { // 时间自增
  40. rollTime += rollDirection * Time.deltaTime;
  41. if (rollTime > maxRollTime) {
  42. rollTime = maxRollTime;
  43. rollDirection = -rollDirection; // 反向卷轴
  44. } else if (rollTime < 0) {
  45. rollTime = 0;
  46. rollDirection = -rollDirection;
  47. }
  48. }
  49. }

​ 说明: RollEffect 脚本组件需要挂在相机上。

​ Roll.shader

  1. Shader "Custom/Curl/Roll"
  2. {
  3. Properties
  4. {
  5. _MainTex ("mainTex", 2D) = "white" {}
  6. _RollTex ("rollTex", 2D) = "white" {}
  7. _BackTex ("backTex", 2D) = "white" {}
  8. }
  9. SubShader
  10. {
  11. Pass
  12. {
  13. ZTest Always
  14. Cull Off
  15. ZWrite Off
  16. Fog { Mode off }
  17. CGPROGRAM
  18. #pragma vertex vert_img // UnityCG.cginc中定义了vert_img方法, 对vertex和texcoord进行了处理, 输出v2f_img中的pos和uv
  19. #pragma fragment frag
  20. #pragma fragmentoption ARB_precision_hint_fastest
  21. #include "UnityCG.cginc"
  22. sampler2D _MainTex;
  23. sampler2D _RollTex; // 滚动轴纹理
  24. sampler2D _BackTex; // 底部背景纹理
  25. float _theta; // 圆滚动角速度
  26. float _r; // 圆半径
  27. float _t; // 滚动时间
  28. fixed4 roll(float rho, float v)
  29. { // 滚动变换, 将屏幕坐标映射到纹理坐标
  30. float trt = _theta * _r * _t;
  31. if (rho < trt - _r)
  32. {
  33. return tex2D(_BackTex, float2(rho, v));
  34. }
  35. else if (rho < trt)
  36. {
  37. float a = trt - rho;
  38. float phi = acos(a / _r);
  39. float u = trt - (UNITY_HALF_PI + phi) * _r;
  40. if (u > 0)
  41. {
  42. return tex2D(_RollTex, float2(u, v)) * pow(sin(phi), 2);
  43. }
  44. u = trt - (UNITY_HALF_PI - phi) * _r;
  45. return tex2D(_MainTex, float2(u, v)); // 刚开始卷动时会触发
  46. }
  47. else if (rho < trt + _r)
  48. {
  49. float a = rho - trt;
  50. float phi = acos(a / _r);
  51. float u = trt - (3 * UNITY_HALF_PI - phi) * _r;
  52. if (u > 0)
  53. {
  54. return tex2D(_RollTex, float2(u, v)) * pow(sin(phi), 2);
  55. }
  56. return tex2D(_MainTex, float2(rho, v)); // 刚开始卷动时会触发
  57. }
  58. else
  59. {
  60. return tex2D(_MainTex, float2(rho, v));
  61. }
  62. }
  63. fixed4 frag(v2f_img i) : SV_Target // uv坐标的计算不能在顶点着色器中进行, 因为屏后处理的顶点只有屏幕的4个角顶点
  64. {
  65. return roll(i.pos.x / _ScreenParams.x, i.uv.y);
  66. }
  67. ENDCG
  68. }
  69. }
  70. Fallback off
  71. }

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. Python Code_04InputFunction

    代码部分 # coding:utf-8 # author : 写bug的盼盼 # development time : 2021/8/28 6:55 present = input('你想要什么?') ...

  2. 凡是有但是-varchar和nvarchar的初步学习之一

    凡是有但是-varchar和nvarchar的初步学习之一 背景 高应用开发, 在涉及到国内国外的问题时,重要的事情有两个: 时区转换, 字符集转换. 时区转换虽然是很难理清楚, 各种规范不统一的事情 ...

  3. [转帖] 拒绝蛮力,高效查看Linux日志文件!

    https://www.cnblogs.com/codelogs/p/16410363.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 日常分析问题时 ...

  4. [转帖]数据库篇-MySql架构介绍

    https://zhuanlan.zhihu.com/p/147161770 公众号-坚持原创,码字不易.加微信 : touzinv 关注分享,手有余香~ 本篇咱们也来聊聊mysql物理和逻辑架构,还 ...

  5. 【转帖】16.JVM栈帧内部结构-局部变量表

    目录 1.局部变量表(Local variables) 1.局部变量表(Local variables) 1.局部变量表也称为局部变量数组或本地变量表. 2.局部变量表定义为一个数字数组,主要用于存储 ...

  6. [转帖]Optimizing Block Device Parameter Settings of Linux

    https://support.huawei.com/enterprise/en/doc/EDOC1000181485/ddbc0e8b/optimizing-block-device-paramet ...

  7. [转帖]tubostat

    TURBOSTAT(8) System Manager's Manual TURBOSTAT(8) NAME turbostat - Report processor frequency and id ...

  8. [转帖] 这grep咋还不支持\d呢(BRE,ERE,PCRE)

    https://www.cnblogs.com/codelogs/p/16060372.html 简介# 对于刚使用Linux不久的同学,肯定会遇到这个问题,就是用grep匹配数字时,发现\d匹配不了 ...

  9. [转帖]UTF8 和 AL32UTF8 的区别

    本文章向大家介绍UTF8 和 AL32UTF8 的区别,主要内容包括 .使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下.  UTF8 和 AL32UTF8 ...

  10. Ubuntu2204设置固定IP地址

    前言 Ubuntu每次升级都会修改一部分组件. 从1804开始Ubuntu开始使用netplan的方式进行网络设置. 但是不同版本的配置一直在升级与变化. 今天掉进坑里折腾了好久. 所以这边总结一下, ...