GPU PRO 4 - 5.1 An Aspect-Based Engine Architecture 笔记

本笔记仅为个人的理解,如果有误欢迎指出

An Aspect-Based Engine Architecture 一种基于方面的引擎架构

        不是很明白为什么GPU的书籍会有游戏引擎架构的文章。

        这里Aspect在文章中的意义更像是表述一个功能模块,在Java中有将Aspect翻译成切面,但是Java切面主要是横向的代码注入,与本文的概念不相符。

大多数系统架构都会考虑将各个功能封装成模块或者组件,在面向对象编程的思想下,这个封装是基于对象去实现的,本文则描述了一种在引擎层面的封装功能的架构思想,封装后的产物被称为Aspect,每一个Aspect负责提供一些功能子集,并通过一个通用的接口与引擎核心通信。

引擎核心:

        引擎核心的功能是保存游戏或者仿真时的数据结构以及相关状态,功能Aspect将会与这些数据进行交互。一般来说引擎核心会定义一些接口,外部的Aspect则通过接口访问当前的游戏数据

        

        用MVC架构的角度去理解的话引擎核心相当于M层,而各个Aspect则相当于C层。

        
        场景图、场景节点:

                与市面上大多数的引擎类似,游戏和仿真环境都抽象成场景概念,交互的数据都以树形的场景节点整合

        

        有虚幻,Unity等引擎经验的人都很熟悉,这就类似里面的场景以及节点,而Aspect则会处理这些数据。但是Node的结构文章中有特别说明,Node在这里设计的思路不是编程里习惯的想法用一个类来表示,在后面的内容中解释了Node的结构应该是一个Map或者Set容器的实例,这里的想法有点像Unity中面向数据的技术栈 (DOTS),这里则将类成员以及相关的值都转化到Map上。

        数据访问:

       用这种聚合的方式实现Node一个影响是没有一个直接访问Node内指定数据的结构,因此访问数据需要通过请求来完成,通过查询Node里面的内容并整合出一个访问接口让Aspect去处理。在多线程的环境下还需要通过添加锁来处理冲突问题,但一般是通过复制相关的数据到Aspect内部去处理

        其他的还有事件系统,这是耳熟能详的基本功能,这里不再赘述。

方面(Aspects):

        Aspect这个概念是这篇文章的核心。

        引擎核心存储着数据当前的状态以及发生的任何变更,核心不关心游戏的具体内容或是运作方式。这些操作都交由Aspect去处理。

        每个Aspect都是一个引擎的功能模块,他可能包括渲染、动画、物理、音频、甚至是游戏运行逻辑。每个Aspect都可以封装着第三方引擎、框架或者API。

        Aspect之间不应该有相互调用,这样会造成Aspect之间产生耦合与依赖,破坏了Aspect的封闭性。这就是简单的分层思想,同层的模块之间不能有任何联系,如果实在要跨Aspect协作,那这应该要放到上层或者在引擎核心处理。

        设计Aspect的时候应该避免一些类似当前的图形设备/上下文或窗口句柄之类的静态资源的共享,如果这些共享无法避免,则应该控制好访问的顺序,比如互斥锁之类的。  

        在这篇文章中Aspect要做到的是能够独立运行,所以才更容易维护与替换,所以每个Aspect都可以独立开发和测试,并通过引擎核心来互相交互,

        引擎则会通过一个单一的接口来管理所有的Aspect的生命周期,初始化、更新、关闭等

        

        场景解释(Scene Interpretation):

        这个概念比较抽象,按我的理解这个小节的主要作用是想说Aspect如何去处理场景里面的数据。

        每个Aspect都会维护一个内部结构,管理他所关注的Node。一般来说Aspect会查询Node上的一些属性值来去确定哪些Node是需要他去处理的,这部分应该是在下一节【节点接口】里面解释。比如物理Aspect则会处理每个Node里面刚体相关的数据,渲染Aspect则会处理节点里面关于网格材质相关的数据。

        当一个Aspect被注册到引擎上后,它会遍历所有场景图里面的Node,把Aspect所关注的Node收集到Aspect的内部里,后面Node上的变更事件则会通知到这个Aspect,以此同步自身的内部结构。

        

        节点接口(Node Interfaces):

        这个节点接口理解的不是透彻

        个人理解的是每个Aspect都会定义一个Interface用来给引擎核心判断当前Node是否符合Aspect这边的要求,同时Aspect也会用这个接口去同步数据到引擎核心侧

        

实现:

        这个引擎架构的一个关键原则是Node不是一个实例化的类而是一个容器,文章给的示例如下:

        

        通过这种Map的形式将Node的成员属性以及相关数据的实例化关联起来

        对应的属性接口类则是如下设计:

方面的更新:

        方面执行相关逻辑的时候会先向引擎申请锁以确保不会出现脏数据的情况,对于数据访问的管理引擎核心则是通过锁来完成,每次Aspect处理完数据后都要将锁交还给核心。

        

例子:受到物体受到伤害时改变颜色

        假如子弹击中游戏中的一个角色并导致目标的材质值改变时可能发生的一系列操作:

        1,在物理方面的更新过程中,子弹与角色的相交被检测到,这里便会生成一个事件并推送到事件队列中。完成这些操作后同步数据到引擎核心。

        2,逻辑方面更新的时候,在事件队列里获得了碰撞事件,并调用子弹和角色的碰撞事件处理脚本函数,并更新相关的相关数据,比如生命值,颜色属性,子弹还会从当前场景中被移除。完成这些操作后同步数据到引擎核心。

        3,渲染方面更新的时候,则按照当前的数据渲染出物体

        目前这个面向方面思想设计的引擎实现的有Cohort Studios’ proprietary engine。

分析:

        与所有设计一样,基于方面构建引擎有其优势和局限性。基于方面的架构将各个功能模块化,这有益于开发过程,但其僵化的结构和间接访问方式也对效率产生了限制。

优势:基于方面构建引擎的优势包括:

  • 提倡数据驱动的开发理念,有助于吸引资产创作者和设计师参与。
  • 高度模块化的即插即用架构允许对引擎进行快速更改。
  • 模块化特性有助于更快地追踪和调试错误。
  • 封装加速了第三方API的集成。
  • 着色器和脚本输入的直连使得开发新图形技术和原型游戏功能更容易、更快速。
  • 功能知识和管理的去中心化让开发有更多的操作空间。

局限性: 以下是一些局限性:

  • 在各个方面内部创建重复或冗余数据,以及在核心中存储数据所使用的聚合结构,可能会显著降低内存效率。
  • 方面的异步特性可能使程序员难以处理,因为因果关系在代码中很少直接相邻。
  • 试图在多个执行线程上的各个方面之间保持完全自主,需要额外的机制来协调更新顺序。

  个人总结:

        本文更像是讲述的一种在数据高度集中的情况下如何将各个功能在引擎层面中封装成模块,这种引擎的特点就是数据被管理到引擎核心中,功能模块化后对于引擎的修改会更加方便,因为只需要关注当前模块的功能即可。

        这边文章个人觉得核心想法的理解难度不高,涉及的技术难点也不多,主要是各个概念的定义让人摸不着头脑。

参考链接:

【什么是面向切面编程AOP? - 欲眼熊猫的回答 - 知乎】

【在Unity中简单使用AOP为方法添加自定义属性】

【DOTS 技术深度解析】

Read more

(保姆级教程)通过官方API搭建一个自己的QQ群聊机器人

(保姆级教程)通过官方API搭建一个自己的QQ群聊机器人

简介 用官方api做了一个qq群聊机器人的demo,有获取天气、简单编辑待办、从本地发送图片等功能。 建了个群,欢迎来交流( QQ群号:710101225 重新写了个基于nonebot框架的教程,个人认为比官方sdk更容易开发:https://blog.ZEEKLOG.net/Clovertaa/article/details/145452834 获取 机器人demo GitHub仓库:GitHub - ClovertaTheTrilobita/SanYeCao-bot: 一个基于官方API的QQ群聊机器人 官方SDK GitHub仓库:GitHub - tencent-connect/botpy: QQ频道机器人PythonSDK 教程 前置需求 本项目使用conda环境和git操作。如果未安装这两个工具请首先移步 史上最全最详细的Anaconda安装教程-ZEEKLOG博客 Git 详细安装教程(详解 Git 安装过程的每一个步骤)_git安装-ZEEKLOG博客 (这俩教程我粗略看了下感觉挺好的,如果不适合你那烦请自行百度了qwq) 一

AI 辅助开发实战:机器人工程本科毕设的高效实现路径

作为一名刚刚完成机器人工程本科毕设的过来人,我深刻体会过那种在算法调试、软硬件集成和紧张deadline之间反复横跳的焦虑。我的毕设题目是“基于视觉的移动抓取机器人系统”,听起来很酷,但做起来每一步都是坑。幸运的是,这次我尝试引入AI辅助开发工具,它们像一位不知疲倦的协作者,帮我渡过了许多难关。这篇文章,我就想和大家分享一下,如何将AI工具融入你的毕设开发流程,实现高效、稳定的系统构建。 1. 背景痛点:那些年我们踩过的坑 在开始之前,我们先来盘点一下机器人工程毕设中那些让人头疼的共性难题。理解了这些痛点,才能明白AI工具的价值所在。 1. 算法调试的“黑盒”困境:无论是SLAM建图还是视觉识别,调参过程往往依赖经验和大量试错。比如调整ORB-SLAM2的特征点数量、匹配阈值,或者YOLO模型的置信度阈值,手动修改代码、编译、运行、观察结果,循环往复,效率极低。 2. 多线程与异步控制的复杂性:机器人系统通常需要多个任务并发执行,如传感器数据采集、核心算法运算、运动控制指令下发。手动编写稳健的多线程或ROS异步回调逻辑,极易出现数据竞争、死锁或回调堆积问题。 3. ROS生

801-203_各无人机厂家对RemoteID支持情况汇总

1. 大疆DJI 参考链接:大疆无人机RemoteID支持情况 DJI航拍无人机的RID广播信息包含以下信息: 1. ID等身份认证 2. 无人机的纬度、经度、几何高度和速度 3. 控制站的纬度、经度和几何高度的指示 4. 时间信息、紧急状态信息 支持RID的航拍无人机型号 大疆无人机支持RID型号列表 序号无人机机型支持情况备注1DJI Mavic 4 Pro支持2DJI Flip支持3DJI Air 3S支持4DJI Neo支持WIFI直连模式下和脱控模式下不支持5DJI Mini 4K支持V01.07.0400 及以后6DJI Avata 2V01.00.0300 及以后7DJI Mini 4 Pro支持V01.00.0400 及以后8DJI Air 3支持V01.00.1200 及以后9DJI Mini 3支持V01.

Vivado 使用教程

Vivado 使用教程

目录 一、创建工程 二、创建文件 三、编写代码 四、仿真验证 五、配置管脚 六、生成Bitstream文件并烧录 一、创建工程 1.左边创建(或打开)工程,右侧可以快速打开最近打开过的工程。 2.来到这一步,命名工程并设置工程的存放路径(这里以D触发器为例) 3.选择RTL点击next。会来到添加文件环节(可以在这里添加.v等文件,不过后面再添加是一样的)直接点击next。 4.选择芯片型号(根据开发板选,这里随便选的),完成后点next会弹出信息概要,finish完成。         二、创建文件 完成上述步骤会进入当前界面: 1.工程管理器add sourse添加(创建)设计文件,创建文件后选择Verilog语言并命名。 2.定义端口(可选),若在这定义后,