ue4集合类型_UE4粒子系统渲染管线概述

cbd5660f73273dccf39df56fa9f19815.png

本文基于UE4版本4.25.3,对Cascade粒子系统的移动端渲染管线进行简单的概括和描述。

Game Thread部分

粒子系统Actor被Spawn(或所在的Level被加载)的时候,UParticleSystemComponent注册和初始化,并通过CreateSceneProxy函数注册和创建FParticleSystemSceneProxy。

UParticleSystemComponent的主要数据成员是TArray<struct FParticleEmitterInstance*> EmitterInstances,包含粒子系统的所有粒子发射器。每一个粒子发射器对应一个FParticleEmitterInstance,管理当前发射器下所有的粒子。

FBaseParticle为粒子数据结构,保存粒子的Location、Rotation、Size和Velocity等数据。FParticleEmitterInstance用uint8* ParticleData指向保存FBaseParticle类型数据集合的连续内存空间。

UParticleSystemComponent关联的所有粒子数据内存空间只由GameThread访问。在帧结束的时候通过UpdateDynamicData函数创建一份包含粒子内存数据的拷贝——FParticleDynamicData,并异步传递给FParticleSystemSceneProxy,供RenderThread渲染使用。

大部分情况下,UE4通过给渲染线程生成一份渲染数据拷贝和函数线程专用(比如函数后缀加_RenderThread)的方式来防止出现多线程渲染的Race Condition问题。

62e0f9fc5774557c062242705274182a.png
GameThread部分调用示意图

Render Thread部分

在FParticleDynamicData被GameThread传递过来之后,粒子系统的渲染真正开始。

粒子系统的渲染始于FParticleSystemSceneProxy::GetDynamicMeshElements函数,输出FMeshBatchs。FMeshBatch是FParticleSystemSceneProxy到MeshDrawCommand之间的一个中间数据结构,主要包含顶点数据流(FVertexStream)、IndexBuffer和材质等。

粒子系统渲染用到的顶点数据流主要有两个:索引为0的几何数据流和索引为1的Instanced数据流,由FParticleSpriteVertexFactory创建和关联。几何数据流描述每个粒子的几何结构为4个顶点构成的单位大小的正方形。Instanced数据流为粒子数据集合,用于以Instanced的方式绘制这些粒子正方形。

Instanced数据流由FParticleDynamicData初始化而来。因为FParticleDynamicData的数据内容主要是GameThread使用的FBaseParticle类型数据集合的拷贝,所以RenderThread通过FDynamicSpriteEmitterData::GetVertexAndIndexData函数把原类型数据集合转换成渲染使用的FParticleSpriteVertex类型数据集合。FParticleSpriteVertex定义了需要传入GPU的顶点数据结构,与ParticleSpriteVertexFactory.ush 定义的顶点输入类型FVertexFactoryInput对应。

为什么GameThread和RenderThread要分别定义粒子数据结构?GameThread对粒子的抽象是一个Pivot点,更新的是这个Pivot点的位置、旋转和Size等信息。而RernderThread把粒子点几何化为一个4个顶点,2个面构成的单位正方形,渲染的时候基于粒子Pivot点的位置、旋转和Size等信息把粒子的4个顶点计算并绘制出来。

FMeshBatch生成后,进入到MeshDrawCommand的构建阶段。FMeshBatch与MeshDrawCommand可理解为一对n的关系,n的值取决于该Mesh会被多少个EMeshPass处理。比如,产生实时阴影的不透明Mesh会被DepthPass、CSMShadowDepth和BasePass 三个EMeshPass处理来分别构建MeshDrawCommand。

为什么需要定义不同的EMeshPass?不同的EMeshPass绘制关联的顶点数据流,Shader和渲染状态等不一样,比如DepthPass的绘制只需要设置顶点位置数据流(PositionOnlyStream),关联的Shader主要功能为Vertex的空间变换和Pixel的深度输出,不用做光照计算等。

对粒子系统来说,一般不写场景深度,不产生阴影,所以DepthPass和CSMShadowDepth的MeshDrawCommand构建过程会被过滤掉。BasePass的构建始于FMobileSceneRenderer::SetupMobileBasePassAfterShadowInit函数,在关联好Shader,设置好TaskContext渲染状态等之后,调用BuildMeshDrawCommands函数真正进行MeshDrawCommand的构建。

所有相关EMeshPass的MeshDrawCommand构建好之后,开始MeshDrawCommand的提交和绘制。BasePass的绘制始于FMobileSceneRenderer::RenderMobileBasePassBasePass函数,然后根据构建阶段生成的TaskContext渲染状态设置PipelineState,根据MeshDrawCommand关联的顶点数据流设置StreamSource等,最后调用RHICmdList::DrawIndexedPrimitive完成绘制。

构建MeshDrawCommand阶段引擎默认是渲染线程起Work线程来并发执行,可以设置Console命令r.MeshDrawCommands.ParallelPassSetup=0来关掉并发,最后的Mesh绘制可以设置r.RHIThread.Enable=0来关掉RHI线程平台相关的绘制API的调用,这样上述所有阶段都在RenderThread依次顺序执行,方便调试。

7a2ef308fac2f16fc769f49d95aec57f.png
RenderThread部分调用示意图

PS:UE4引擎的代码量巨大,流程庞杂,单扣一个小细节就可能要研究上好几天,想要用短短几页文字把渲染管线描述清楚难度很大,而且还需要一些写作技巧使得描述不失偏颇,有点理解官网文档的“言简意赅”了(doge~~~

参考文献:

  1. Mesh Drawing Pipeline
  2. Threaded Rendering

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460413.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ip反查MAC地址

打开DOS命令提示符窗口&#xff0c;在窗口中输入命令“nbtstat -a IP”&#xff0c;如以上面查到的“10.10.3.21”为例&#xff0c;输入“nbtstat -a 10.10.3.21”转载于:https://www.cnblogs.com/jtm789/p/3715535.html

2、Sprite,SpriteBatch,Texture,TextureRegion的初步认识

昨天搭建了环境&#xff0c;今天就初步接触这个4个控件&#xff08;Sprite&#xff0c;SpriteBatch&#xff0c;Texture&#xff0c;TextureRegion&#xff09; 1、SpriteBatch 这个吗&#xff0c;我没有看api文档&#xff0c;偶是直接看土豆的博客学习的&#xff0c;我看了代码…

nedc和epa续航里程什么意思_NEDC、WLTP和EPA续航里程哪种最真实,用车注意事项都有什么...

我的理解是&#xff1a;从目前来看&#xff0c;衡量一款新能源电动汽车的性能指标&#xff0c;其中最为关键的就是车辆的续航里程&#xff0c;而这个续航里程使用不同的测试方法又会有不同的表现。从现有的续航里程测试标准来看&#xff0c;主要有NEDC、WLTP、EPA三种方式&…

javascript系列之执行上下文

写在前面&#xff1a;一 直想系统的总结一下学过的javascript知识&#xff0c;喜欢这门语言也热爱这门语言。未来想从事前端方面的工作&#xff0c;提前把自己的知识梳理一下。前面写了些 DOM的知识&#xff0c;略觉水平有限。没几个月就要开赴找工作的前线&#xff0c;奈何自己…

linux系统在虚拟机中迁移的技术难点

linux系统在虚拟机迁移中的技术难点通常我们期望虚拟机的迁移能够全部自动化或者部分自动化完成&#xff0c;但实际上Linux系统在P2V&#xff08;Physical to virtual 物理到虚拟&#xff09;和V2V&#xff08;virtual to virtual&#xff09;的迁移中可能遇到一些困难。1.磁盘…

Altium Designer 09简易教程(一)

【写的不好请谅解】 1、首先需要先准备好软件&#xff0c;这个大家就直接去网上找一下&#xff0c;安装也不难&#xff0c;如果有需要也可以给我留言哈嘻嘻嘻&#xff1b; 2、打开ad09&#xff1b; 3、大家会发现整个界面都是英语&#xff0c;可能看起来有点累吧&#xff0c;就…

莒南机器人_莒南42项重点建设项目公布!一定有你关注的

10日&#xff0c;县发改局公布莒南县2020年重点建设项目表&#xff01;涉及工业、服务业、基础设施、现代农业等行业&#xff0c;共42项。详↓工业1、山东钢铁集团永锋临港有限公司临港先进优特钢产业基地一期项目投资方&#xff1a;山东钢铁集团永锋临港有限公司建设地点&…

配置Mysql实现主从复制与读写分离

环境说明 主从复制使用mysql自带的master与slave机制&#xff1b;读写分离使用mysql-proxy实现&#xff01; 有服务器三台&#xff1a;s1,s2,s3。 s1为web服务器&#xff0c;装有httpd&#xff0c;php&#xff0c;mysql&#xff0c;mysql-proxy。 s2为主数据库服务器&#xff0…

js两个小技巧【看到了就记录一下】

1、不声明第三个变量实现交换 var a1,b2; a[b,ba][0];//执行完这句代码之后 a的值为2 b的值为1了 2、&&和||的用法 &#xff08;学会了立马感觉高大尚了吧&#xff09; var day(new Date).getDay()0; //传统if语句 if (day) {alert(Today is Sunday!); }; //运用逻辑…

c语言题目集合

转自&#xff1a;http://blog.csdn.NET/oqqhutu12345678/article/details/69524383 1. 用预处理指令#define 声明一个常数&#xff0c;用以表明1年中有多少秒&#xff08;忽略闰年问题&#xff09; #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 2. 写一个“标准”宏M…

arduino 土壤温湿度传感器_嫌arduino太贵?太大?试试ATTINY85!DIY温湿度计入门级教程...

ATTINY85做主控&#xff0c;OLED显示的温湿度计。简介&#xff1a;通过Arduino开发环境&#xff0c;对ATTINY85进行编程&#xff0c;利用DH11温湿度传感器&#xff0c;在SSD1306(128*64)OLED显示屏上显示温度和湿度。材料&#xff1a;ATTINY85DHT11SSD1306 (12864 OLED)电池盒纸…

认识事件冒泡和事件捕获

一.事件冒泡就是多个元素同时响应了同一个事件&#xff0c;前提是这些元素都绑定了这一个事件。这只是我的定义&#xff0c;感觉好理解些。 称它为冒泡&#xff0c;是因为事件会按照DOM元素的层次结构依次执行&#xff0c;就像水泡一样不断浮向顶端。所以称之为事件冒泡。 这个…

BSD配置SSH服务

转载&#xff1a;因为是在vmware上装的FreeBSD&#xff0c;用vmware console把玩系统有点麻烦&#xff0c;就是想起可以开启FreeBSD系统的SSH服务器&#xff0c;再用ssh客户端软件(putty)来更省事一点。以下是配置过程&#xff0c;备忘1&#xff0e;开机启动ssh服务,编辑/etc/r…

计算abc=a!+b!+c!

根据题目&#xff0c;即求abca!b!c! 下面我们设计算法&#xff1a; 设三位数为n,取出每一位数分别放在a、b、c中 通过定义形参&#xff0c;求每位数的阶乘&#xff0c;通过函数返回值返回 主函数中&#xff0c;调用返回值&#xff0c;每一位的阶乘相加与该三位数比较&#xff0…

docker选择安装位置_自定义WSL的安装位置,别再装到C盘啦

本文使用 Zhihu On VSCode 创作并发布为了用docker,今天才决定更新到win10 2004打算另外装一个WSL2的发行版折腾docker和GPU&#xff0c;发现之前装WSL到非系统盘的教程找不到了。现在网上也没找到有这方面的东西&#xff0c;干脆自己写一个留作记录吧~WSL(Windows Subsystem f…

[讨论帖] 程序员如何赚外快?

昨天的一篇文章一个程序员如何快速赚到一百万&#xff1f;引起了大家的热门讨论&#xff0c;现在另开一个贴&#xff0c;讨论一下如何赚钱。 -------------------------- 挣外快需要的是大量的业余时间和强大的意志&#xff0c;如果你是个每天工作十几个小时天天累得像狗一样的…

求两个数的最大公约数和最小公倍数

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 [plain] view plaincopy #include <stdio.h> int main() { int a, b, num1, num2, tmp; printf("Input a & b:"); scanf("%d %d",&num…

XP系统中没有Internet信息服务windows组件解决办法

1. 检查本机是否有iis2.dll&#xff08;或者iis.dll&#xff09;和iis2.inf&#xff08;或者iis.inf&#xff09;文件 iis2.dll&#xff08;或者iis.dll&#xff09;的存放路径为&#xff1a;c:\Windows\system32\setup\iis2.dll&#xff1b; iis2.inf&#xff08;或者ii…

24安装失败 spss win10_教你win10系统显卡驱动安装失败的解决方法「系统天地」

我们日常在对电脑的使用过程中&#xff0c;经常都会遇到这样或那样的问题。比如说win10系统显卡驱动安装失败该怎么办呢&#xff1f;别着急&#xff0c;还有小编在呢&#xff1f;接下来小编就来告诉大家win10电脑系统显卡驱动安装失败怎么解决。详细教你win10系统显卡驱动安装失…

自定义字符串函数:strlen,strcat,strcpy,strcmp

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 计算字符串长度函数strlen&#xff1a; int mystrlen(char *s) {int count 0;char *p s;if (!p){return count;}while (*p ! \0){count;p;}return count; }1234567891011121314151617181912345678…