【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】激光灯、碰撞特效

    1 需求描述         本文将模拟激光灯(或碰撞)特效,详细需求如下: 从鼠标位置发射屏幕射线,检测是否与物体发生碰撞 当与物体发生碰撞时,在物体表面覆盖一层激光灯(或碰撞)特效         本文代码见→激光灯、碰撞特效 2 原理         获取屏幕射线与物体

    2023年04月25日
    浏览(37)
  • Unity3D粒子系统之制作烟雾特效

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    2024年02月05日
    浏览(71)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包