虚幻4渲染编程(UI篇)【第一卷:Slate框架综述】_cpongo7的博客-程序员秘密

我的博客目录:

小IVan:专题概述及目录

Slate概述:

虚幻4有自己的UI框架Slate。引擎的编辑器也是用它写的。当然Slate也可以用来写游戏UI。作为美术我觉得有必要具备写UI的能力,这样就可以顺畅地开发工具和游戏UI效果了,比如要制作3D UI,UI上各种闪动的效果,都需要对UI有全面掌握。


首先先把目光投向下图四个模块

v2-a83098a5e973544adf97a1e94a4edb34_b.jpg

这四个模块分别是Slate,SlateCore,SlateRHIRenderer,UMG。Slate和SlateCore共同构筑了逻辑层部分,SlateRHIRenderer则是渲染部分。UMG是在Slate和SlateCore上面的封装层,方便客户端调用,这也是为啥可以不费吹灰之力就能在unreal中用UserWidget开发一套UI的原因。在Unreal中UI就是铺在屏幕表面的面片,也是走顶点像素着色器,甚至还有后期,这和Unreal的SceneRendering的架构差不多。都是逻辑层负责组织资源,然后通知渲染层渲染。

下面就来捋一下整个Slate的渲染 , 我使用的引擎版本是4.20

首先EnginLoop会调用FSlateApplication的DrawWindows,开始了Slate的绘制,注意这里只是逻辑层

v2-7a078d713292604f084fa4ce350d4ec0_b.jpg

然后在PrivateDrawWindows中会初始化一个DrawWindowArgs的东西,它由DrawBuffer和WidgetsToVisualizeUnderCursor等数据组成。在DrawBuffer中存了绘制所需的ElementList。

v2-741a648ce9b2dde5390623aa07305fcd_b.png

打开SlateDrawBuffer你将会看到:

v2-1a300102dbe424177796bcb89943ee8b_b.jpg

在开启绘制之前,需要把UI的图元全部压入这个DrawList才行。于是下面会执行DrawWindowAndChild

v2-d896ef058e28c239da6e2cb28abad832_b.jpg

这里会层层调用,最终会调用到具体一个UI控件的OnPaint函数,这里拿SImage做例子

v2-34b6b602c4736797f0cbe2a18381c6d8_b.jpg

v2-5b9bb39cb3730dff6c747c0c63384cf7_b.jpg

最终会把图元的类型加到List里。具体的顶点和index会在后面的Batcher里真正添加

v2-f3103cc6557dafa0f5b6107e55357bf1_b.jpg

v2-2b5f0d53795118012f6448730fd1c7fd_b.jpg

下面是Unreal在batcher中添加图元

v2-8fc1445c652aaad57b685db67eca57fa_b.jpg

v2-822c8bf29ca5a926175e2a9e1bce17ab_b.jpg

于是这样就完成了UI数据的搜集。完成搜集之后就可以开始渲染啦,下图的标注2就是渲染部分的开始。

v2-d36ac5dc3a81f00506dc373df67f680a_b.jpg

既然有要渲染肯定就需要渲染器啊,FSlateRenderer就是渲染Slate的基础渲染器。

v2-d8e6d71c7955328e42cfb1b14ad83bd2_b.jpg

FSlateRHIRenderer是FSlateRenderer的子类,DrawWindows是Slate渲染的入口

v2-c8a680323622cd6bfd2914955ff8af9d_b.jpg

在DrawWindow中会向渲染层发送绘制命令。

v2-c71280a8fe069c3fada7b696bbe5b9d2_b.jpg

在DrawWindow_RenderThread中是使用之前准备好的DrawList来绘制。

v2-599cfe53e8103da0bd92d00eedd9555d_b.png

在DrawWindow_RenderThread中完成最终的绘制

v2-d1cc43d12933f6cc7ae8cf1af1964455_b.jpg

在Slate流程清晰后,可以再来看看UMG,随便打开一个UMG的代码可以看到

v2-1406a0421ff0b12f08fa2c7f74b5471c_b.jpg

UMG就是对Slate的一个简单封装。


于是现在一切流程清晰后,可以得到如下结论:

【1】如果想新建一个自己的UI类型,直接派生一个SWidget子类然后重载OnPaint,然后再在UMG层建一个与之对应的简单封装即可。

【2】如果想要在UI上做一些花样,比如动态UI,3D UI可以在渲染层的vertexshader或者pixleshader上做文章,可以自己给UI写一些特殊shader。

【3】想要优化UI,也是在渲染层做优化,不过unreal的UI已经自带batch,剔除等优化操作了。

Enjoy it !

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cpongo7/article/details/100779724

智能推荐

一些比较好的资源_tagging.pui_普通网友的博客-程序员秘密

om Cubie ,CubieBoard(类树莓派)的设计者http://www.fendou.info/tag/cubieboard/LevelDB关键实现图解http://www.wzxue.com/leveldb%E5%9B%BE%E8%A7%A3/电子商务系统的设计、开发、部署、运维及其解决方案http://www.entlib.com/迷你

基于zookeeper实现分布式锁_小码农叔叔的博客-程序员秘密

引言在程序开发过程中不得不考虑的就是并发问题。在java中对于同一个jvm而言,jdk已经提供了lock和同步等。但是在分布式情况下,往往存在多个进程对一些资源产生竞争关系,而这些进程往往在不同的机器上,这个时候jdk中提供的已经不能满足。分布式锁顾明思议就是可以满足分布式情况下的并发锁。 下面我们讲解怎么利用zk实现分布式锁。ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务...

Yii1.1 CGridView 简单使用_weixin_33966365的博客-程序员秘密

Yii1.1 CGridView 简单使用配置model文件,返回CActiveDataProvider对象。public function search(){ $criteria=new CDbCriteria; $criteria->compare('title',$this->title,true); $criteria->compare...

pytorch 两层神经网络的实现(含relu激励方程的反向传播推导过程)_两个神经网络拼接到一起pytorch_Sudan_大树的博客-程序员秘密

神经网络的典型处理如下所示:定义可学习参数的网络结构(堆叠各层和层的设计);数据集的制作和输入;对输入进行处理(由定义的网络层进行处理),主要体现在网络的前向传播;计算loss ,由Loss层计算;反向传播求梯度;根据梯度改变参数值,最简单的实现方式(SGD)为:weight = weight - learning_rate * gradient使用pytorch和auto_g...

网络表示学习(network represention learning)_喜欢打酱油的老鸟的博客-程序员秘密

https://www.toutiao.com/a6679280803920216589/2019-04-13 15:40:481.传统:基于图的表示(又称为基于符号的表示)如左图G =(V,E),用不同的符号命名不同的节点,用二维数组(邻接矩阵)的存储结构表示两节点间是否存在连边,存在为1,否则为0。缺点:长尾分布下大部分节点间没有关系,所以邻接矩阵非常稀疏,不利...

【 HDU - 2546 】G - 饭卡 (贪心 + 01背包)_如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买_黑桃️的博客-程序员秘密

电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。Input多组数据。对于每组数据:第一行为正整数n,表示菜的数量。n<=1000。第二行包括n个正整数,表示每种菜的价格。价格不超过50。第三行包括一个正整数m,

随便推点

域环境下的渗透_maxiaoqiang1的博客-程序员秘密

<br />在进行内网渗透,尤其是在比较大型的网络环境下,很可能会遇到域这样一种特殊的网络环境,而在域环境下的内网渗透又将是另外一片天地。 <br />       首先还是先简要看一下域的概念吧: <br />       域 (Domain) 是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件 和打印机等设备资源,使不同的域之

C++ openssl ECDSA签名_arm89782的博客-程序员秘密

1、Openssl库安装及交叉编译下载openssl库,https://www.openssl.org/source/将库文件解压到本地文件后进行配置:a、config配置:进入解压后的目录,执行 ./config shared --prefix=/usr/local/openssl --openssldir=/usr/local/其中shared 为生成动态连...

Bundle 的使用_bundle使用_a15838319826的博客-程序员秘密

bundle的认识:        一种存放字符串和Parcelable类型数据的map类型的容器类,通过存放数据键(key)获取对应的各种类型的值(value),而且必须通过键(key)获取。bundle的用法:       Bundle相当于Map类,就是一个映射,用Bundle绑定数据,便于数据处理        它主要作用于Activity之间的数据传递. bund

Nature综述:Rob Knight手把手教你分析菌群数据(全文翻译1.8万字)_刘永鑫Adam的博客-程序员秘密

本文转载自“热心肠先生”,己获授权。导读自然微生物综述(2017 IF:31.851)于2018年5月23日在线发表了Rob Knight亲自撰写(一作兼通讯)的微生物组领域研究方法综述...

Java枚举类(举例)_重复的昵称的博客-程序员秘密

枚举类使用enum关键字定义枚举表示一种事物的多种可能|所有可能|所有情况注意:所有的枚举类都隐式继承自java.lang.Enum类枚举中的所有成员|实例|字段 都是,默认public static final,都是当前类型的一个实例public class Employee { //员工编号 private int id; //员工姓名 private Strin...

推荐文章

热门文章

相关标签