码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Godot屏幕抖动效果原理与实现


    要用Godot实现屏幕抖动效果,调查了网上的一些实现方案,效果都很不满意,于是自己实现了一个。

    原理

    从渲染过程看,实际发生抖动的是场景相机。
    抖动过程对应物理学上的振动(物理量在某个定值附近反复变化),也称为震荡。
    一个物体振动时,其振幅逐渐减小最后停止振动,这种振荡运动是阻尼的。
    相机抖动符合阻尼振动的定义。

    要实现抖动效果,理论上既可以是相机在平衡位置(坐标)附近的振动,也可以是相机朝向(方向角)的振动。
    Godot的Camera3D类有h_offset和v_offset属性,用它们来实现振动是最方便的。

    根据物理学中阻尼运动的动力学方程(振动方程),可以解得质点的运动方程:
    阻尼振动的运动方程
    另外,过阻尼振动和临界阻尼振动的情况我们不需要,不作讨论。
    虽然运动方程是一维的,但是很容易扩展到多维。
    只要多维的系统参数相同,符合物理规律,最终表现效果就会比较“真实”。
    给定初始化条件(t=0, x=0)和(t=duration, x=0)可以进一步简化得到相机的运动方程,即相机坐标随时间变化的函数。

    GDScript 代码

    场景相机的附加脚本:

    extends Camera3D
    
    const amp = 1.5
    const cycle = 3
    const duration = 0.3
    const beta = 3 / duration
    const omega = 2 * PI / duration * cycle
    
    var a: Vector2
    
    func rnd_amp(amp_max: float):
    	return randf_range(amp_max / 2, amp_max) * [1, -1][randi() % 2]
    
    func _on_vibra_finished():
    	h_offset = 0
    	v_offset = 0
    
    func damped_vibra(t: float):
    	h_offset = a.x * exp(-beta * t) * sin(omega * t)
    	v_offset = a.y * exp(-beta * t) * sin(omega * t)
    
    func _on_Main_sig_bad():
    	a = Vector2(rnd_amp(amp), rnd_amp(amp))
    	var tween = create_tween()
    	tween.connect("finished", _on_vibra_finished)
    	tween.tween_method(damped_vibra, 0.0, duration, duration)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    以上代码适配Godot 4.1.3版本

    说明

    • 将外部信号sig_bad连接到场景相机脚本中的函数_on_Main_sig_bad();
    • 函数_on_Main_sig_bad()初始化振动过程参数,并触发tween的补间(多次插值)过程;
    • 系统会通过Tween机制每隔一段时间触发函数damped_vibra(),函数采用阻尼振动的运动方程来更新相机参数h_offset和v_offset,实现振动效果;
    • 当补间结束时,finished信号触发函数_on_vibra_finished(),重置相机参数h_offset和v_offset。

    参考

    知乎:阻尼运动、参变共振
    百度百科:阻尼振动
    Godot: Tween

  • 相关阅读:
    界面控件DevExpress BI Dashboard v23.1——支持全新的图标趋势指标
    C++ map clear内存泄漏问题
    Milvus 2.1 版本更新 - 简单可信赖、性能持续提升
    手把手教你实现buffer(四)——webrtc中的CopyOnWriteBuffer
    字符串习题总结3
    【树莓派不吃灰】命令篇② 常用文件管理命令
    动态规划--01背包问题详解
    介绍一下js的节流与防抖?
    中国范围逐月夜间灯光数据(2012-2021年)
    《向量数据库指南》——向量数据库内核面临的技术挑战及应对措施
  • 原文地址:https://blog.csdn.net/feiyunw/article/details/127642982
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号