【Unity3D】卷轴特效

这篇具有很好参考价值的文章主要介绍了【Unity3D】卷轴特效。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 原理

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

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

【Unity3D】卷轴特效

         注意:屏幕坐标 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 运行效果

【Unity3D】卷轴特效文章来源地址https://www.toymoban.com/news/detail-490490.html

4 推荐阅读

  • 渲染管线
  • 固定管线着色器一
  • 固定管线着色器二
  • 表面着色器
  • 顶点和片元着色器
  • 选中物体描边特效
  • 基于模板测试和顶点膨胀的描边方法
  • 水波特效
  • 半球卷屏特效
  • 激光灯、碰撞特效

到了这里,关于【Unity3D】卷轴特效的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity3D教程:2D游戏技能特效

    在我们的2D图形游戏中不可缺少大量的光影、技能特效,像Diablo II中的魔法效果的实现,幸好我们拥有强大的CPU来为我们实现Alpha混合与色彩饱和混合,接下来让我们来讨论一下如何用这些方法来实现我们游戏中所需要的技能特效。     一、Alpha混合特效     Alpha混合可以让我

    2024年02月01日
    浏览(54)
  • Unity3D粒子系统之制作火焰特效

    本文将会介绍如何使用Unity内的粒子系统制作烟雾效果。 如果想了解Unity粒子系统中的基础属性,可以看这篇博客:Unity3D粒子系统之基础属性介绍 先上预览图吧 用自己熟悉的绘画工具画一张类似这样的图片(相似即可,白灰色部分边缘不规则),注意一定要黑底。 将画好的

    2024年02月02日
    浏览(44)
  • Unity3D粒子系统之制作烟雾特效

    本文将会介绍如何使用Unity内的粒子系统制作烟雾效果。 如果想了解Unity粒子系统中的基础属性,可以看这篇博客:Unity3D 粒子系统之基础属性介绍 先附上预览图: 材质贴图 首先我们需要一张烟雾材质用的材质贴图,我是自己画的,可以参考下图自己画一张或者去网上找素材

    2024年02月02日
    浏览(52)
  • 【Unity3D赛车游戏优化篇】【十】汽车粒子特效和引擎咆哮打造极速漂移

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity游戏demo – 😶‍🌫️版本: Unity2021 😶‍🌫️适合人群:Unity初学者进阶 😶‍🌫️学习目标:3D赛车游戏的基础制作 😶‍🌫️技能

    2024年02月09日
    浏览(62)
  • 【Unity3d】【原理】【实践】协程的原理和实践

    原理 协程,需要从迭代器说起。 协程的执行,可以归结为,每帧执行一次迭代,直到迭代结束,返回。 迭代器,IEnumerator接口的实现。其中的核心迭代功能,在 bool MoveNext() 中,若返回为true,则表明当前未结束;若返回false,则表明当前迭代结束。 若迭代未结束,则需是的迭代

    2023年04月09日
    浏览(75)
  • Unity3d 制作一个简单的NPC对话系统

    ​ 最近在自己写一个比较小的项目,虽然自己是一个策划,但是程序方面我觉得也是很有必要学一学的。 ​ 经过了接近一年的学习,也终于是可以独自写一些小的系统了。 ​ 这次自己写了一个比较简单的NPC对话系统,供大家参考。 进入对话区域 开始对话 Inspector面板可调

    2023年04月08日
    浏览(44)
  • Unity3D中的C#协程(概念、使用方法、底层原理)

             Unity3D 中的协程是针对 Unity3D 框架和 C# 编程语言定制的 ,具有便捷的使用方式和良好的效率。其他语言Python、Lua等也支持协程,但是底层实现的细节可能不同。在 Unity3D 引擎中, 协程被 Unity3D 引擎的主循环所驱动 。         协程(Coroutine)是一种编程概念

    2024年02月08日
    浏览(51)
  • 【Unity3D赛车游戏】【二】如何制作一个真实模拟的汽车

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity游戏demo – 😶‍🌫️版本: Unity2021 😶‍🌫️适合人群:Unity初学者 😶‍🌫️学习目标:3D赛车游戏的基础制作 😶‍🌫️技能掌握

    2024年02月11日
    浏览(53)
  • Unity3D TCP网络通讯核心意涵与基本原理详解

    在Unity3D中,TCP网络通讯是一种常用的通讯方式,它可以实现可靠的数据传输和连接。 对惹,这里有一 个游戏开发交流小组 ,希望大家可以点击进来一起交流一下开发经验呀 本文将详细介绍Unity3D TCP网络通讯的核心意涵与基本原理,包括技术详解和代码实现。 一、TCP网络通

    2024年03月12日
    浏览(45)
  • 使用Unity3D创建一个立方体(Cube)游戏对象并启动Unity

    Unity3D是一个强大的游戏开发引擎,可以用来创建各种类型的游戏和交互应用程序。在本文中,我们将探讨如何使用Unity3D创建一个立方体(Cube)游戏对象,并启动Unity编辑器。 首先,确保你已经安装了Unity3D并且已经在你的计算机上成功启动。然后,按照以下步骤进行操作:

    2024年02月05日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包