目前的3D引擎的渲染帧和逻辑帧都是在一个线程上运行的,在网络游戏中大量玩家聚集,繁重的骨骼动画计算和粒子计算极大的拖累了渲染帧数,有两种有效措施:1、控制同屏显示人数,但玩家体验不好 2、帧数低于某值时减少动画Tick频率,但带来的问题是动画不连贯。
        如果考虑使用多线程优化,最容易想到的就是采用平行分解模式,将骨骼动画计算和粒子计算写成两个for循环,然后用OpenMP将其多线程化,但事实上这样并不会提高多少效率,这两者计算仍然要阻滞渲染帧,线程的创建也有一定的消耗。于是我想到了一种极端的解决方案,采用任务分解模式,将渲染和逻辑完全分离到两个线程去,互不影响,当然这样线程同步会是大问题,毕竟线程的数量和BUG的数量是成正比的。
        我们首先来分析下这两个线程分别需要做什么工作,需要那些数据。渲染线程需要获取实体的位置、材质等信息,并交给GPU渲染,逻辑线程需要更新实体的位置、材质、骨骼动画等数据,很显然一个写入一个读取,这为我们实现一个没有线程同步的多线程3D渲染系统提供了可能。
        为了让读取和写入不需要Lock,我们需要为每一份数据设计一个带有冗余缓存的结构,读取线程读取的是上次写入完成的副本,而写入线程则向新的副本写入数据,并在完成后置上最新标记,置标记的操作为原子操作即可。以Vector为例,这个结构大致是这样的:

struct VectorData 
{
        Vector4f    m_pVector[DATACENTER_CACHE];
        int         m_iIndex;

        VectorData()
    {
            memset( m_pVector, 0, DATACENTER_CACHE * sizeof(Vector4f) );
            m_iIndex = 0;
        }

        void    Write( Vector4f& rVector )
    {
            int iNewIndex = m_iIndex == DATACENTER_CACHE - 1 ? 0 : m_iIndex + 1;
            m_pVector[iNewIndex] = rVector;
            m_iIndex = iNewIndex;
        }

        Vector4f&    Read()
  {
            return m_pVector[m_iIndex];
        }
};

当然我们可以用模板来写这个结构,让其适用于int,float,matrix等多种数据类型,余下的工作就简单了,将所有有共享数据的类的成员变量都定义为以上这种数据类型,例如我们可以定义:
        SharedData<Matrix4f>  m_matWorld;
        在渲染线程中调用pDevice->SetWorldMatrix( m_matWorld.Read() );
        在逻辑线程中调用m_matWorld.Write( matNewWorld );

需要注意的是,这种方案并非绝对健壮,当渲染线程极慢且逻辑线程极快的情况下,有可能写入了超过了DATACENTER_CACHE次,而读取却尚未完成,那么数据就乱套了,当然真要出现了这种情况,游戏早已经是没法玩了,我测试的结果是渲染帧小于1帧,逻辑帧大于10000帧,尚未出现问题。
        FlagshipEngine采用了这一设想,实际Demo测试结果是,计算25个角色的骨骼动画,从静止到开始奔跑,单线程的情况下,帧数下降了20%~30%,而使用多线程的情况下,帧数完全没有变化!

3D引擎多线程:渲染与逻辑分离相关推荐

  1. 3D引擎多线程:资源异步加载

    本文原创版权归 博客园 flagship 所有,如有转载,请详细标明作者及原文出处,以示尊重! 作者:flagship 原文:3D引擎多线程:资源异步加载 资源异步加载恐怕是3D引擎中应用最为广泛的多 ...

  2. 多线程渲染(Multithreaded- rendering)3D引擎实例分析 : FlagshipEngine

    原文地址:http://www.cppblog.com/flagship/category/9250.html 1. 开篇:关于FlagshipEngine 首先要感谢旗舰工作室的倒掉,让我可以名正言 ...

  3. 多线程渲染(Multithreaded- rendering)3D引擎实例分析 : FlagshipEngine

    1. 开篇:关于FlagshipEngine 首先要感谢旗舰工作室的倒掉,让我可以名正言顺的使用FlagshipEngine这个 名字,话说这个实验引擎,当初只是我的大学毕业设计,工作之后实在太忙,写 ...

  4. ios跨线程通知_一种基于Metal、Vulkan多线程渲染能力的渲染架构

    快手Y-tech  原创最新技术干货分享 随着3D渲染场景规模越来越复杂,单线程渲染架构在满足业务性能要求时已经捉襟见肘,因此,多线程渲染显得愈发重要.本文首先介绍了新一代图形渲染接口Metal.Vu ...

  5. 艾迪普发布新一代国产化“3D引擎+工具+平台”,加速释放数字内容生产力

    ‍数据智能产业创新服务媒体 --聚焦数智 · 改变商业 艾迪普的2023新产品发布会在5月20日在北京隆重举行,该发布会以"向新出发 智见未来"为主题,艾迪普重磅推出了新一代实时三 ...

  6. ActionScript最新3D引擎项目(转载)

    2019独角兽企业重金招聘Python工程师标准>>> 3D引擎 注:对于3D引擎,渲染的效率和支持的渲染功能是很重要的,然而 在短短的文章中根本不可能做详细的介绍,特别是截图,很可 ...

  7. 虚幻引擎之多线程渲染机制

    虚幻引擎之多线程渲染机制 文章目录 虚幻引擎之多线程渲染机制 一.前言 二.游戏线程与渲染线程的交互 2.1 ENQUEUE_RENDER_COMMAND宏 2.2 渲染线程 2.3 数据交互 2.3 ...

  8. 3D引擎中的渲染模块

    渲染是3D引擎不可缺少的模块,这两天在思考如何把这个部分设计好. 首先明确需求,最起码的因该是把图形API进行抽象风装,这样引擎只调用经过抽象的渲染接口,这样便于扩展到其他图形API上,简单来说就是把 ...

  9. 3D引擎渲染管理系统概览

    3D引擎渲染管理系统, 目前由: RendererScene, RendererSubScene, RendererSceneGraph, RenderProcess, RenderingCacheP ...

最新文章

  1. Python中的defaultdict函数
  2. phpRedisAdmin 安装
  3. 体脂数C语言switch,c语言switch语句
  4. Eclipse 导入项目到git@osc中
  5. Python教程-python字典中key的灵活使用fromkeys()
  6. 网站导航(URL 映射和路由)
  7. 【转】世界顶级人工智能会议的总结
  8. 【数学建模】数学建模学习4---动态规划(例题+matlab代码实现)
  9. 微信api接口调用-触发推送微信群聊列表
  10. 【信号与系统】DTFT离散时间傅里叶变换
  11. web前后端分离系统之间的单点登录
  12. 浅谈工业网络架构及安全
  13. Python3 实现简易局域网视频聊天工具
  14. IIS SSL客户端证书(忽略/接受/必须)之三——思考验证(3)
  15. 眼睛疲劳及干涩的防治
  16. 搭建SpringBoot+Vue 项目 完整流程
  17. 【Mo 人工智能技术博客】python玩转信号处理与机器学习入门
  18. mysql coreseek_Linux下PHP+MySQL+CoreSeek中文检索引擎配置
  19. 【JAVA学习笔记】
  20. IP-Guard应用攻略-软件中心协助IT人员管理终端软件

热门文章

  1. SPT20 协议_过户协议书模板五篇
  2. Accelerated C++ Chapter4.1 用函数来计算学生成绩
  3. cups 设置打印机纸张_惠普打印机打印模糊怎么办 惠普打印机打印模糊解决【方法】...
  4. eclipse+java+selenium+testNG搭建自动化测试框架
  5. git status怎么操作_Git 基本操作
  6. 爬虫python名词解释_python爬虫
  7. bp神经网络matlab实例蚊子,bp神经网络matlab实例
  8. java 定时任务哪个好_java目前常用的几种定时任务
  9. 存储过程和函数的区别?
  10. PCL学习笔记01:在Ubuntu上安装PCL