unreal 延迟渲染_unreal多线程渲染 事件延迟 - CSDN
精华内容
参与话题
  • 我的专栏目录:小IVan:专题概述及目录​zhuanlan.zhihu.com简介:因为虚幻的架构,我们美术做一个效果只能使用材质编辑器。这让我很不舒服,稍微想做点特别点的效果就没办法了。我又是天天在公司用自研引擎的人,...

    我的专栏目录:

    小IVan:专题概述及目录zhuanlan.zhihu.com图标

    简介:

    因为虚幻的架构,我们美术做一个效果只能使用材质编辑器。这让我很不舒服,稍微想做点特别点的效果就没办法了。我又是天天在公司用自研引擎的人,这种限制让人很不舒服。所以我开始修改了虚幻的shadingmode之类的。但是感觉自己还是不满足,想调个多pass虚幻都不让我做,所以我打算加个pass什么的。但是虚幻加pass可不像unity那么简单,只有操刀去改源码了。然后我又反观了一下我前几篇博客,只简单讲了一下怎么改代码,没说原理。所以这个系列我打算系统说一下虚幻的一个架构。当然虚幻如此庞大,我也有很多不知道的地方。

    其实我写博客的目的很简单,就是想记录一下自己做的东西,有时候自己翻一下,再把问题再想一下,也许会有新的发现。虚幻的渲染方面的资料也是少得可怜,研究的人也少得可怜。大部分牛人都自己去造轮子去了。我只是个技术美术,造轮子的事情还是交给图形程序吧。不过研究虚幻4的确学到很多。如果有大牛看到我的文章中有错误,还请留言斧正。

    首先在看这个系列之前,你需要具备以下:

    (1)至少要敲过简单的渲染器,不管是拿dx敲还是拿gl敲或者vk之类的。

    (2)对虚幻引擎有一定了解,对虚幻的渲染有一定了解。可以看我前几篇文章,或许可以有所帮助。

    (3)C++基础。其实本人c++水平也是一般般(常常受到公司程序大牛的鄙视,不过我是美术)。

    (4)至少一块RTX显卡可以用来做实时光线追踪(2019年)

    随着引擎版本的更新,后续会逐步加入新版本。那么下面就正式开始吧!


    【概览虚幻4渲染管线】

    v2-22128d79c885d1fe1d99d8fe6d576fca_b.jpg
    v2-08f11139f8888ff018aee74a229ff90c_b.jpg

    首先,虚幻有很多个管线的。Mobile管线和Deferred管线。首先找到

    v2-b01943154ac4971cadb819c320827918_b.jpg

    在这个函数里你将会看到很多熟悉的函数名称

    v2-79365eb5ed9f7a86511ae8688a3d7cb5_b.jpg

    虚幻就是通过调用这些函数来一步步绘制的。是不是很眼熟?这个就是各大论坛啦,博客啦讲的虚幻渲染流程的真面目。

    下面就是官方的DrawOrder了。那么这个顺序是怎么来的呢。就是上面那个函数的调用顺序。

    v2-f9c233f06579279d759ee7f76d1d87d3_b.jpg

    再打开这个Render函数,你就将看到延迟渲染一帧所调用的各个函数。(反正我看了半天就看到个大概的渲染顺序之外,还是啥也不知道)

    v2-2f80522a5ef41b9858277cee2726f53d_b.jpg

    那么当我们把一个模型托到场景里,这个模型被渲染出来的整个流程到底是什么样的呢?这个流程其实是非常庞大的。下面我就来一个一个拆分。

    (1)第一步:资源准备阶段。这个阶段包括顶点缓冲区的准备,索引缓冲区的准备。这一步由场景代理管理完成。当然从磁盘里读取模型资源这些就涉及到StaticMesh这些了。想了解这一步可以去看我以前的博客,或者直接去看UPrimitiveComponent,UMeshComponent,UStaticMeshComponent,UCableComponent,UCustomMeshComponent。当你把这些源码全部研究一遍后,这个阶段算是了解了。这个阶段我不打算再描述了,因为已经有了很多现成的代码了。

    (2)第二步就是shader资源的准备了,这个又是一个非常大的话题了。可以去看我以前关于给改材质编辑器和加shadingmode的文章便可以有个大概的了解。这一步我还会进一步阐述。

    (3)第三步就是绘制了。

    我们先不看Render函数那些复杂的调用,我们把精力先集中到shader层面来。一张画面是怎么开始绘制的呢?


    v2-c1e60fc31db469462deaf519452720aa_b.jpg


    通过这个我们便能知道一个大概的绘制流程(千万别以为虚幻只有这几步,不过主要的大概的流程是这样)。先绘制那些深度啊,初始化视口啦我们先不管。我们来看下这个BasePass。这个BasePass干的事情就是把GBuffer画出来。

    v2-e9b47830309669b8e7b5b941e7842a79_b.jpg

    这里就是像素着色器的入口。绘制完这一步后,我们就有了GBuffer然后再绘制剩下的。环境遮罩骤就先不说了。来看看最重要的光照部分。

    光照部分的入口在这里:

    v2-636bcab8823640a0c6a27f53af6c68f8_b.jpg

    虚幻的TiledDeferredLighting的渲染方式。不知道这个的去看毛星云的RTR3的博客的光照那节,讲得特别好。这里给个传送门:

    blog.csdn.net/poem_qian

    这里会调用

    v2-c70eae1048c6162206d5b474bfe981cf_b.jpg

    GetDynamicLighting这个函数会调用

    v2-7fbb0cbfb3b9df9e669443140ec243e2_b.jpg

    这里会接着调用

    v2-f949410bac2fd37074974d1d7df2be3f_b.jpg

    看到这里就很熟悉了,看过前面我修改shadingmode的博客应该会对这里很熟悉。

    lighting绘制完了之后就会绘制一些反射啊之类的东西了,然后就是透明物体啊后期啊。这些后面会慢慢分析他们。我们先把两个最重量级的研究了。

    接下来我们研究一下fog渲染阶段。找到FogRendering.cpp你就会发现,其实绘制fog的是一个globalshader。前面绘制各个物体的是materialshader。

    v2-041f009f82343271db98d1c8f658acc7_b.jpg
    v2-912f6613411e7febc76d6a04a360f4b8_b.jpg

    你会发现绘制fog的是一个globalshader。虚幻一共有这么几种shader:Globalshader materialshader和meshshader。

    这篇博客只是一个概述性和引导性的。只是说明一下虚幻绘制的一个大概情况。下一卷我将演示一下怎么自己写个shader,引擎识别它,编译它,然后如何cpu和gpu进行信息交流的

    4.20的Unreal渲染模块有了较大改动。

    v2-ff846341921de5e2603cdf8fbb07e72d_b.jpg

    主要是为了配合引擎新增特性和性能优化。不过大体上的流程还是和上个版本的保持一致。

    为了给LTC让道,所以shader做了大面积重构。

    v2-8a8ebea188a277f2f7186ba2b9400533_b.jpg

    ShadingModel改为了IntergrateBxDF

    v2-a0306824caeff694627c0b10992d5a38_b.jpg

    下面会对绘制流水线详细写一遍,由于量巨大所以我会慢慢更新。

    (1)【InitView】

    v2-579f87c2f5d7426774e0faf91828f1ad_b.png
    v2-281e12fd30c5afbb307c2e38d89e02ed_b.jpg

    引擎代码注释写得非常简单:Initialize scene's views.Check visibility, build visible mesh commands, etc.

    这是渲染管线的开始,这步是为渲染管线准备绘制当前帧所需要各种资源。后面的管线就是判断一下画不画,绑定一下状态和RT然后就画画画就好了。这一阶段做的事情非常多也非常杂。首先来看看一些主要的

    ComputeVisibility

    v2-413887eb219612529fad23a791cdffe4_b.png

    可见性剔除有很多种技术,引擎会使用多种方法进行组合剔除,把没必要渲染的东西剔除干净,最大限度在渲染之前就做到最省。

    虚幻提供了几种剔除方法

    v2-fa3aa8b0d64ec933f51e6d53cf8c1962_b.jpg

    他们各有优劣,可以根据不同平台和情况进行选择。

    VisibilityMap

    在后面会把视口中可见性属性是非可见的物体剔除掉。

    v2-3e6a3d6795ee883095316aad2d84de6e_b.jpg

    PrecomputedVisibilit

    在场景中可以使用预烘焙的可见性数据。

    v2-338fa423f32cc89fc61d49d52a3f9c6d_b.jpg

    如果当前视口场景中有可见性烘焙数据就会启用可见性烘焙的剔除方式

    v2-90003f837c79f232abd9cd8d256c926b_b.jpg

    ViewFrustomCulled

    做完前面的步骤后,还会进行视锥体剔除,并且大部分情况下,视口会使用视锥体剔除

    v2-6a73aecb905f86fe35e609d48d22030d_b.jpg
    v2-a132e9e92fc49242fedcfcfdbf9bbf81_b.jpg

    进行视锥体剔除后可以减少大部分没必要绘制的图元

    v2-633af0986b124f9de75572fc72f934f1_b.jpg

    这时再配合各种其它的剔除方法就可以进一步剔除

    v2-9508c4c49a170086ad0324b21ab0952b_b.jpg
    v2-7a06cfb0ddb034c3de3fe90d41261999_b.jpg

    而这里的“其它的剔除方法”包括但不限于PrecomputedVisibility,Distance,DynamicOcclusion

    DistanceOcclusion

    v2-f03bccf5cee359508ffe4f35226c3ff3_b.jpg

    不在距离范围内就不绘制,非常简单有效的绘制方式。这种剔除方式挺适合地面上摆的小物件,摆的一些decal或者小道具,对大型建筑不适合。

    Hardware Occlusion Queries

    硬件的可见性剔除。这种方法将每帧的可见性检查作为每个Actor的查询发出。 Actor的可见度在一帧之后被回读 - 如果相机移动得非常快,有时会产生不利影响,导致它们“弹出”。 硬件遮挡的成本随着在GPU上执行的查询的数量而变化。 使用距离和预计算可见性方法可以减少GPU每帧执行的查询次数。

    在各种剔除后,在InitView的最后会根据这些数据建立MeshPass

    v2-f8f8a5da3c83bf414cc298ed873e4fc3_b.jpg

    (2)【EarlyZ-PrePass】

    v2-20b0db727695cf52011890e382b141f7_b.jpg
    v2-c4431b89c91a80c03c2b6262e15b2faf_b.png

    EarlyZ由硬件实现,我们的渲染管线只需要按照硬件要求渲染就可以使用earlyz优化了,具体步骤如下:

    (1)首先UE4会把场景中所有的Opaque和Mask的材质做一遍Pre-Pass,只写深度不写颜色,这样可以做到快速写入,先渲染Opaque再渲染Mask的物体,渲染Mask的时候开启Clip。

    (2)做完Pre-pass之后,这个时候把深度测试改为Equal,关闭写深度渲染Opaque物体。然后再渲染Mask物体,同样是关闭深度写,深度测试改为Equal,但是这个时候是不开启clip的,因为pre-pass已经把深度写入,这个时候只需要把Equal的像素写入就可以了。

    关于EarlyZ的具体详解可以去看参考文章【1】

    首先渲染prepass的第一步肯定是渲染资源的准备啦。primitive资源会在InitView的时候准备好。

    然后会再BeginRenderingPrePass函数中设置各种绘制管线的绑定,包括关闭颜色写入,绑定Render target

    v2-b7bc93523a89f8a71fdcbaff1c5f7741_b.jpg

    然后再调用draw之前会把各种UniformBuffer和渲染状态设置好

    v2-2335f9e9be8296914c75dcc0143dc20e_b.jpg
    v2-222b71e8428210b332c7af6630f59734_b.png

    然后调用draw

    v2-2bf33be4490056844784e7f7ca614789_b.png

    最后完成PrePass的绘制

    v2-f46c8f5ca6bfebefeeb5309fd4da63ba_b.jpg

    (3)【ShadowDepthPass】

    根据不同的灯光类型会绘制不同种类的shadowmap。总的来说绘制shadowmap的时候不会使用遮挡剔除。

    Unreal渲染shadowmap目前我就找到个视锥剔除

    v2-76d5a2f790384aa5c172157eda0fb760_b.png
    v2-4b239cf4bbdce108af1929b27542fa8e_b.jpg

    shadowdepthpass可能是在basepass之前,也可以是之后,具体看EarlyZ的方式

    v2-c1d630e5e5349a8133c907a4d845c0d7_b.png
    v2-7be01e95ea13f36f1a1e979637691570_b.jpg

    我们的灯光种类繁多大致可以分为两类,一类使用2Dshadowmap的,一类使用Cubemapshadowmap的

    v2-322e5c8413568369be9fa332612372c0_b.jpg

    上图的1部分就是渲染2DshadowMap,2部分渲染的就是Cubemapshadowmap,这一步只是渲染出shadowmap供后面的Lightingpass使用。

    (4)【BasePass】

    v2-975568166609af0c7721fbaca1464828_b.png

    BasePass使用了MRT技术一次性渲染出GBuffer。

    v2-f7018c22976e094d9a2faf24a82467bb_b.png

    再上一次GBuffer的数据分布

    v2-7122e9e374b7824897153f0d30716304_b.jpg

    BasePass把GBuffer渲染出来之后就可以供后面的LightingPass使用了。我们的材质编辑器再Surface模式下也是在生成MaterialShader为BasePass服务

    v2-08e5687122396117ca2ec8c91364cb1f_b.jpg

    这部分可以去看看我的材质编辑器篇有详细介绍。

    也是通过一系列设置绑定渲染状态资源等,最后调用dispatchdraw

    v2-7b3ca3b430be474df968dbefa78b3a31_b.jpg
    v2-7cfc98b15cddeae69f7ce2c082ff1554_b.jpg

    可以注意到,MRT0是SceneColor而不是BaseColor

    v2-5d21e50dd500c5a2767beee0e1d46af1_b.jpg

    Scene在BasePass中做了简单的漫反射计算

    v2-387c26c1874b87fcc347f1ae4e8a59db_b.png

    这一步用到了,这个测试场景我是烘焙过的,我把烘焙数据去掉,SceneColor其实是这样的:

    v2-8eaeaf082a3a834c4c171ed747c5d12f_b.jpg

    啥也没有黑的

    BasePass会在这个阶段把预烘焙的IndirectLiting计算到SceneColor这张RT上供后面的pass使用

    v2-e1057d96b87a69bd1b0348192e7d3743_b.png

    (5)【CustomDepthPass】

    v2-02c2ea20f0faf7498f929d3db4a53d1f_b.jpg
    v2-d3979c189f927d9df8ba9c0f1f8eec32_b.jpg
    v2-e840d7c19ad4236635107d43600857e5_b.jpg

    上面的图渲染了一个球的customdepth(在红圈处可以看到一个球,可能不是很明显哈)。CustomDepth没啥特别的,就是把需要绘制CustomDepth的物体的深度再绘制一遍到CustomDepthBuffer上。

    (6)PreLightingPass

    虚幻封装了一套方便画PostPass的机制,后面的绘制SSAO,Lighting,SSR,Bloom等各种pass都是用的这逃Context的机制。

    v2-dd100189736dd2fbc0bf7fcd04c602c7_b.jpg
    v2-27ce6dcd474432309e921ff6a4c5dd3a_b.jpg

    PreLighting这步主要是在用前面的GBuffer算decals和SSAO为后面的Lighting做准备。

    v2-3e9ecfb1b2b3b30bedbf036a96e95424_b.png

    SSAO使用的是FPostProcessBasePassAOPS这个C++shader类。

    v2-71ec0c87347da589f9fdd1a996245211_b.jpg

    对应的USF是PostProcessAmbientOcclusion

    v2-3bb3b9be4b24b7e6f72a81ac4374a49a_b.jpg

    并且使用Computeshader来加速计算。

    (7)【DirectLightPass】

    v2-9c628b0deac61c8f85fdf9e737bbee36_b.jpg

    LightPass也非常复杂,整个pass的代码有几千行,shader代码也有几千行非常恐怖的系统。我们先找到入口函数:

    v2-ae2cf511c90d31bdc8f1fd5b51e775e5_b.png

    (1)方向光

    根据不同的情况,使用不同的渲染策略

    渲染不同情况下的灯光大体分类如下。还会根据不同的渲染方式分类。

    v2-a1333d04a291ebbcb02b00e3aee9e20f_b.jpg

    比如一般的方向光:

    v2-e81159b5659a27db7d517ed13c75add0_b.png
    v2-d92700e7edb10534ee05525828eb2953_b.png
    v2-ea5721ab9ef2dd6b2142de91fc8d25fb_b.jpg

    在渲染方向光的时候因为不需要考虑分块,所以直接把每盏灯挨个画出来就可以了

    v2-24d0336562057e6775d29cc3c816ce87_b.png

    下面我只放了一盏方向光

    v2-61121b057c63138f11f098d20e221154_b.jpg

    下面我放三盏方向光:

    v2-1611d5f40ce987c51300b20a8a5bc5dd_b.jpg

    (2)TileDeferredLighting

    如果灯光不渲染阴影,并且灯光没用IES并且灯光数目达到80盏以上(4.22)并且启用了TileDeferred管线,那么虚幻4就会使用TileDeferredLight来计算光照,虚幻实现TileDeferrdLight使用的是一个Computeshader

    v2-921f7b112ed427ba1c620d175427af67_b.jpg
    v2-d48819345cfedd485228613f01978203_b.jpg
    v2-b6c3467da49e57487a68713c3b426481_b.png

    有很多灯光使用的潜规则。

    (8)【ScreenSpaceReflectionPass】

    v2-70188de95d3495fb079b443ae6c7dcf2_b.jpg
    v2-09ba59cff82192d6da7a5a162719a6f6_b.png


    (9)【TranslucencyPass】

    v2-d1f1d40bdd60db0e92b278cfa9728eae_b.jpg
    v2-94b0640d438e3161dbeaec70cf3f1582_b.jpg

    透明物体会放在最后渲染,但是在后期的前面。需要看是否在DOF(景深)后合并。

    对于这个上图的那个场景来说,透明物体渲染的buffer是长下面这样的:

    v2-6c05f557dc872163ce7f9b1f554222af_b.jpg

    最后在后期中组合

    v2-7aceba7b907363239ee4127cae52b7dd_b.jpg

    如果没有启用r.ParallelTranslucency透明物体只能挨个渲染。

    v2-f171cd98a584a4d84d496fdbf8b23ec7_b.jpg
    v2-bd2be1695a6910da54f2365ffaaf5b2b_b.jpg
    v2-0186407aafeca4d0bb4b0c89367d2d7b_b.jpg

    如果启用了就可以走上面的并行渲染分支。

    透明物体的渲染在实时渲染中一直比较迷,会有各种问题。比如排序等等。在默认情况下是走AllowTranslucentDOF的。AllowTranslucentDOF是什么意思呢,代码的注释里有解释。

    v2-2b17bd6e094be3f7032fc8b5a34a8d80_b.jpg

    Translucent物体的渲染有几种模式:

    v2-6b669646aa731d2e62198ecdd6f72c88_b.jpg

    这里的代码我们在BasePassPixelShader.usf里能找到

    v2-45338166686e8f83ea1ad2afe022a049_b.jpg

    对于非透明物体来说basepass是渲染GBuffer的,但是对于透明物体来说,BasePass是渲染基础的+Lighting的,会在这里一次性渲染完,如果我们想改透明物体的shading方式,就需要用在这里改了。


    Enjoy it


    Next:

    小IVan:虚幻4渲染编程(Shader篇)【第二卷:不用虚幻4Shader管线使用自己的shader】zhuanlan.zhihu.com图标

    参考文章:

    【1】fengliancanxue:深入剖析GPU Early Z优化

    【2】Visibility and Occlusion Culling

    展开全文
  • UE4 渲染流程

    千次阅读 2019-07-03 16:24:50
    在手游品质越发上扬的如今,已经有不少厂商开始使用一些性能更好的引擎,去尝试游戏制作了。而虚幻4引擎(以下简称UE4)就是其中之一,在这款...

    在手游品质越发上扬的如今,已经有不少厂商开始使用一些性能更好的引擎,去尝试游戏制作了。而虚幻4引擎(以下简称UE4)就是其中之一,在这款引擎中已经诞生了诸如《铁拳7》《地狱之刃》《帕拉贡》等一系列大作。对玩家而言,这些作品都是不折不扣的视觉盛宴。

    日本网站4Gamer曾刊登一篇文章,分享了使用UE4在图像渲染中会遇到的难点以及解决方法,分享人是该引擎的开发商Epic Games日本分公司的高级工程师篠山範明。

    在研讨会上,篠山首先展示了虚幻4的整体流程图,随后他对和流程图上各功能板块有关的技术进行了介绍。

    绘制物体缓冲的"Base Pass"时要注意的问题

    我们先来把整个流程分为不同的单元,在各个单元里进行深入解读。

    首先从上图左起第二个板块"Base Pass"开始。Base Pass等同于产生了物体缓冲(G-Buffer)。

    众所周知,UE4的绘制引擎采用了延迟渲染(Deferred Rendering)。所谓延迟渲染,是指将一个场景的几何体(3D模型、多边形)的光照、阴影、质感搁置到一旁,先着手于绘画,然后在后半段再对光照、阴影、质感进行处理的处理方式。

    即给人一种把原本的多边形先绘制出来的印象,实际上不仅要绘制多边形,前者的参数还需要配合后面光照和阴影的处理。其输出目标,在成为复数缓冲时具有普遍性,但是这里的缓冲我们称之为"物理缓冲"。

    为何要做这么麻烦的事情?其实延迟渲染有两个优点。第一个优点就是能将十分复杂的光照、阴影以每次一像素的方式进行处理。第二个优点是并不明确限定用于光照的动态光源数,所以可以进行丰富的光照渲染。

    现代游戏图像在绘制复杂的场景时需要大多的光源,而在移动复杂着色器的时候,最终其结果不是在画面上输出,而是通过像素着色器,处理像素的编写和撤销,导致耗时严重、性能下降。为了全力回避这一点而开发出的就是延迟渲染。

    物体缓冲是指使用后照明和后处理特效的中间过渡环节

    根据以上提到的这些,使用Base Pass输出物体缓冲需要注意的两点。

    第一点简而言之即"不绘制没进入视线的对象"。

    这种"投影剔除"(Frustum Culling),一般是通过CPU端来处理;为了整体覆盖被称为"包围球"(Bounding sphere)的各个3D对象,对象是否在视野内的判定标准,是通过预先设定的包围球来实行的。

    举一个包围球被错误(或是正确)设定的案子。这种情况下如果绘制没有被正确地剔除,会导致最终明明没有绘制,但作为GPU的绘制对象却投入了渲染管道(rendering pipeline),造成GPU产生多余的负担。

    什么程度的剔除会成功,可以通过Stat初始视图(Stat InitViews)指令的"视锥体裁剪基元(Frustum Culled Primitives)"进行确认。

    另外,实行强制冻结渲染(FreezeRendering)指令后移动镜头,就能够确认视野外绘制了什么。如果那个时点上,视野外本应剔除的3D对象被描绘了出来,就会显示出不能被剔除的理由。在这种情况下需要特别注意确认包围球的设置。

    强制冻结渲染能够看到此时点摄像机提出的结果

    Base Pass要注意的第二点,是"不计算多余的像素"。

    在图像处理的流程中,使用像素着色器实际处理前,会有运行深度测试(Z 测试)的"Pre Z 测试"这一步骤。从这里着手处理的像素,会因为被某个东西所遮挡而无法绘制出来,这时可以进行撤销处理。

    但是,像半透明对象这种会伴随α测试的绘制、视差遮蔽映射这种像素着色器处理后会重新编写深度值的情况,就不进行Pre Z测试,而通过处理实行分路迂回。

    运行α测试的隐藏(Masked)材料

    像素深度撤销(Pixel Depth Offset)可以变更像素深度(Pixel Depth)

    但是,就算是不透明的对象,设定回避Pre Z测试之后,便无法撤销本来能够撤销的Pre Z 测试。这种情况是因为虽然用了像素着色器处理,但是(之后的)Z测试失败,这一操作被撤销了,虽然绘制结果没有变得奇怪,不过性能会跌落到最坏结果。

    Z值的预阶段"Z预阶段"的注意点

    下一个主题是"Z预阶段(Z Pre Pass) "。UE4的渲染管道,是在Bass Pass的物体缓冲写出来之前,在仅预处理深度值(Z值)之后,运行Z预阶段。

    事先预处理深度值的目的,是将最终影像和同一深度缓冲的内容结果,在透视前获得。Z预阶段之后的Base Pass则是,参考预先得出的深度值缓冲进行Z预测试,因此通过在最终的画面里不留下像素痕迹(即编写后又被消去的像素),以回避像素着色器的运行。

    虚幻4只将背景对象这种静态对象计入Z预阶段,而动态对象则不计入Z预阶段,以上设定为默认设定。但是虚幻4可以按照客户要求来设定项目文件"早Z阶段(Early Z-pass)"和"动态早Z阶段(Movables in early Z-pass)"。

    或者通过勾选"作为遮光板使用(Use as Occluder)"可以设定各对象单位是否计入到Z预阶段之中。

    各项目的关闭渲染选项里面,有"作为遮光板使用"这一项目。在设定为默认为ON时,勾选为off,就能够调整各项目单位是否参与早Z

    通常默认设定应该就可以了,但是在多边形数很多的场景中,Z预阶段的运行本身会对GPU造成很大负担,所以这种场景下,上面提到的两个设定,通过选择on/off来比较性能可能会比较好。

    光照的前段处理"预照明"需要注意的点

    虚幻4中通过血溅和弹痕这种投射材质贴图来实行的印花式绘制,是在光照(Lighting)之前,即通过"预照明(Pre-Lighting)"部分来处理并设计的。对于后段的光照处理,可以将印花式绘制囊括在光照对象里。

    和印花绘制相同,"从所有方向插入有关假想环境光的遮蔽率"(Ambient Occlusion,环境光遮蔽)的处理,也能通过预照明来完成。

    与这种预光照绘制相关的麻烦已经成了常见问题,比如"印花被描绘得照明颜色过深"、"设置天窗后,印花下面变透明了"等等。

    从结论来说,这是"虚幻4的做法",当然《虚幻4》也提供了回避此类问题的对策。那就是"延迟贴花(DBuffer Decals)"功能。

    所谓延迟贴花(或称Deferred Decal),是指和将印花进行物体缓冲不同,而是使用被称作"延迟贴花"这一印花专用特殊缓冲来进行绘制,用物体缓冲进行光照和阴影处理之后,延迟贴花的内容也反映并实行了出来。印花的绘画结果统合到了物体缓冲之中后,也因此出现了上文提到的问题。为了回避这个问题,要准备专用的缓冲。

    但是,加上利用物体缓冲这一条件,绘制比之前的处理线程更多,绘制负担变高也成为其瓶颈。

    虽然导致负担变高了,但是应该实行印花表现而导入物体缓冲吗?还是说应该选择别的表现方式来回避延迟贴花,这需要开发者好好考虑后再做决定。

    通过光源周围的处理而改变性能的"照明"阶段

    接下来,篠山说明的是光照的阶段。虚幻4的光照分为"静态光照(Static)"、"固定光源(Stationary)"、"动态光照(Movable)"三种光照范畴。

    最先提到的静态光照,为通过全部事先计算过的光线映射来处理的静态光照。这一事先计算,可以使用专用的光照烘培,来计算将间接光都考虑在内的光照。

    其次是固定光源,固定光源的光照本身是以实际时间来运行的,但是只有阴影计算是事先进行了处理的。

    具体而言,固定光源在UE4的图像引擎内部会被当作一般的动态光源,但配置到场景里又成了基本不动的光源。因为它不动,所以也可以在阴影贴图中用于预先生成阴影。

    虽然有点复杂,但这种做法有个好处,就是配置的固定光源一组最多可以放置4个,其内部处理是稍有限制。

    固定光源预生成的阴影贴图中,一个光源能够分别对应αRGB中4条通道的像素格式。也就是说,第一个光源对应α通道,第二个光源对应R通道,以此类推。所以在αRGB中最多对应四个光源,一组光源的上限也就是四个。

    如果设置第五个固定光源,那么它将被当作动态光源来处理,即便是定义为固定光源,也不会提升其性能。

    固定光源在一张阴影贴图上最多设置4个,超过第五个将被视作动态光源

    而动态光源如前文所述,包括阴影生成在内,它将完全在运行时进行处理。

    我们之前说过延迟渲染下动态光源的数量不受限制,再来看它实际的性能。

    设置两组对比场景,一是将100个照射范围狭小的动态光源放置到同一场景内,二是将8个照射范围较大的光源放置到同一场景内,对比两者的负荷大小。

    得出的结果是后者的负荷更高。这里的负载大也可以看作是计算量大。而计算量的大小,取决于场景内各个像素受到多少个光源的照射。所以比起处理八个像素各自被一个光源照射,处理一个像素被八个光源照射的负荷要更高。

    负荷率大小:蓝>绿>红

    UE4可以通过光效复杂性(Light Complexity)功能来查看光源的处理负荷,所以在设计的时候,可以不依赖延迟渲染的特性,而通过精确计算光源负荷来构建场景。

    通过光效复杂性功能,就可以查看已设置的光源的负荷率

    光照反射存在最优解吗?

    不仅限于UE4,在所有即时游戏的美术中,需要不少设计技巧的就是光照反射(Reflection)。

    如果反射的材料是镜面反射更强的金属类,那么周围的场景就应该被映入其中,如果以材料的角度来看,就相当于受到了周围所有光源的照射。光照反射要应对的就是周围所有的光源,所以它是在表现材料材质的时候,关于真实程度的关键要素。

    在UE4当中,有三种反射生成方法来处理会引起镜像、映照等情况的材料,如下图所示。

    第一种是采用反射探头来生成静态反射。

    在场景的任意位置都可以预先设置坐标,然后可以进行全方位的透视,最后会生成立方环境贴图(CubeMap)材质。而这里的预生成坐标点,被称作反射探头(Reflection Probe)。

    静态反射就好比是反射探头处拍下的360°照片

    关键的问题在于:在反射探头处获得的全方位场景,应该影响到场景内多大的范围。

    依然采用对比分析,首先在一个场景里配置一个静态反射,将其设置为影响整个场景;再配置200个静态反射,设定为只能影响非常狭小的范围,可以看到两者的绘制负荷差距不大。

    但是在设置了200个静态反射的例子中,如果将各自的影响范围调大,符合就会急速增大。

    其原因与动态光源的例子相同。如果将多个静态光源的影响范围扩大,那么在绘制一个像素的时候,就必须参考计算多个静态光源的参数,负荷自然就增大了。

    稍微调大200个静态反射的影响范围,负荷就立刻增大

    其实,已经配置了相邻的反射探头时,再将两者的影响范围重叠的意义并不大。反射探头的设置以及其影响范围的设定如果不合情合理,那么就会增加很多无效的计算负荷。

    如下图实例的配置就更为合理:

    红圈:让整个场景都处于光照反射的影响范围内。

    覆盖各个房间的蓝圈:主要的静态反射,在这里可以定义大致的统筹性参数。

    绘制物件细节的绿圈:仅配置在能产生光照反射的特殊物件上。

    第二种是屏幕空间反射(Screen Space Reflection,简称SSR)。

    屏幕空间反射会根据透视图的结果,在画面坐标系中进行局部的光线跟踪,在运行时刻(Runtime)上实时生成计算结果。

    这种处理方式的好处是,即便仅截取场景中任意一瞬间的画面,也会精确地反映出动态角色以及动态光源影响下的光照反射。相对的缺点,就是对于画面外场景的影响,会被完全无视掉。

    使用SSR最典型的报错,就是暴露了这个缺点所造成的。弥补它的有效方法,就是结合静态反射来做处理。

    如右图,岩壁左侧被画面隔断的地方,应该在水面中被反射,但是因为岩壁被隔断在画面之外,所以无法被正确反射

    第三种是平面反射(Planar Reflection)。

    这是将场景准确的映入平面的光照反射处理手段。如下图实例,以水平面为反射面,从视点E来看右侧的岸边,那么相当于在水下的视点E'来透视上下颠倒的岸边的场景。所以被反射的场景需要进行两次绘制,光照反射处理的负荷必然会高出不少。

    又因为处理负荷比较高,所以平面反射常限定在水面等平面上使用,同时画面的品质非常高。由于这些特性,比较推荐在过场动画中使用平面反射的处理。比如《地狱之刃》在GDC 2016上放出的宣传片,其中就使用了平面反射的处理技术。

     

    关于半透明的各种问题

    不仅限于UE4,半透明物件的绘制在实时图形绘制领域都算是很难处理的问题。UE4在绘制半透明物件时也会遇到不少棘手的问题。

    离我们最近的问题,可以说就是粒子效果,可能是因为日本的画师都特别喜欢粒子效果,所以对它比较关心吧。

    UE4在绘制半透明粒子效果时,不会更新深度值(Depth)。

    将特效配置在场景中

    但深度值没有变化

    这种情况下会产生的问题就是,将深度值设为关键值时,后期处理会变得很奇怪。

    如下图所示,聚焦到中间的火焰时,利用景深来让图像增加朦胧感,但火焰的粒子效果在地平线上方的都被模糊了,下方则没有变模糊,这样的图像就非常奇怪。

    这就是因为火焰的粒子效果没有深度值,所以Z缓存(Z buffer)里只存在地面的制图深度值。再加上地平线上的背景里镜头非常的遥远,所以背景和火焰都被判断为离镜头非常遥远,就被做了模糊处理。模糊处理器是无法判断有没有火焰粒子效果的,于是就成了这副样子。

    为了解决这类问题,就要使用到独立透明度(Separate Translucency)功能。

    使用时,半透明粒子效果在绘制时仍然不会更新深度值,但它被分离到别的缓存中,与景深等后期处理分开。

    换句话说,就是将半透明物件与不透明物件的绘制分开,在后期处理时优先应用于不透明物件。

    在通常的后期处理中,粒子效果的绘制与普通场景的绘制是在同一缓存里处理的

    而利用独立透明度功能,就可以将粒子特效分离到另一个缓存里,并将其与后期处理分隔开

    对比两种处理效果的区别

    利用这个功能的确能够避免半透明粒子效果出现一些奇怪的模糊情况,但是却没法给它添加适当的模糊处理。所以即便能够避免问题,但解决不了实际的困难。

    所以即便是UE4,也会存在很多限制,而引擎的开发方还在试图解决这些问题。

    而在半透明绘制方面,还存在一个很棘手的问题,也就是绘制的负荷过高。首先可以思考一个问题:让画面整体的颜色都改变的后期处理,与近让画面一部分出现冒烟的粒子效果,哪边的处理负荷更高?

    简单的看,可能因为画面整体的像素数很多,所以可能是前者更高,但其实答案恰恰相反。

    乍一看,半透明粒子效果的烟雾仅占画面的一小部分,实际上它是经过多次重叠绘制而成的。查看粒子的驱动线的框架,原因就一目了然了。在画面的同一部分,烟雾的粒子改变大小并反复绘制了多次。

    我们可以用着色复杂性(Shader Complexity)功能的排错视图,来查看。

    在这个视图中,重复绘制的区域会用红色表示,可以借此判断产生问题的部分。越红则表示改区域中,粒子绘制的负荷越高,需要调整。

    降低粒子绘制负荷最有效且最简单的手段,就是用独立透明度功能,将粒子绘制分离到别的缓存重,用低分辨率进行绘制。

    可以将反复绘制、重合的半透明粒子用低分辨率绘制,再调整好合适的大小,与主透视图合成就可以了。如果将绘制半透明粒子的缓存降低为纵横各半的分辨率,那么简单算下来绘制负荷就能变为原先的1/4,要是再将其减半,就能变为1/16。

    在低分辨率的缓存里绘制,然后扩大并合成,就意味着粒子的轮廓会变得更加模糊,而原本就是半透明的粒子即便更模糊一些,产生的影响也不会有多少。但分辨率调得过低,也会暴露出分辨率不高的问题,所以选择缓存分辨率的时候要相当慎重,与负荷变化放在一起寻找最佳的配置。

    以上三张图就是在半透明物件的缓冲分辨率在100%、50%、10%的绘制状态下,绘制负荷的变化

    粒子绘制的符合降低方法还有一种,就是在粒子动画中,完全透明区域更多的时候可以用到的粒子剪影(Particle CutOut)功能。

    通常的粒子是由两个多边形构成的,而粒子剪影的原理,就是为了避开完全透明的区域,由多个多边形自动分割来进行绘制。

    虽然这样一来多边形的数量会增加,但由于能够避免像素着色器的无意义运行,所以在大量的粒子进行绘制时,这或许会减轻负荷。

    粒子剪影会自动分割多边形

    利用着色复杂性功能的排错试图,可以看到左侧的四边形粒子,与右侧的多边形粒子,在绘制时产生的重复绘制区域更少

    UE4中顺序被固定的后期处理

    后期处理就好比相片修饰一样,需要对最后的绘制结果进行加工处理。

    相片修饰通常是针对2D的照片,在3D游戏内的图像方面,由于需要利用透视图中附带的多种信息,对图像进行三维的加工,所以两者差距非常大。

    不进行后期处理(左)与进行后期处理(右)的区别

    UE4中预设了诸如色调、景深、光晕等加工图像的多种表现形式。

    而UE4比较有特色的是,能够将后期处理的效果,设置到3D场景内的指定位置,或者是特定的摄像头上,所以能够实现诸如"进入3D场景某个位置的时候就会有景深的表现",或是"在这个摄像头上绘制图像的时候需要棕色调"等效果处理。

    所以在用UE4的后期处理时,建议最好熟记处理的顺序,因为处理顺序无法改变,只能按部就班地进行。

    结语

    尽管文章到此结束了,但其实还有很多内容没有提到(几百页ppt),仅从提到的内容来看,也能发现,对于想要用UE4做好游戏的开发者来说,花时间打磨游戏的细节是必不可少的,而这份指南能切实的解决很多使用上的问题。

    感兴趣的读者可以访问下面的链接(PS:需要翻墙)。

    http://www.slideshare.net/EpicGamesJapan/cedec2016-unreal-engine-4

    转自https://blog.csdn.net/or_7r_ccl/article/details/81102771
    展开全文
  • 这是教程的第 2 部分,旨在帮助开发人员提升 Unreal Engine* 4 (UE4)...正向与延迟渲染 细节级别 LOD 生成 自动 LOD 生成 LOD 资料 实例化静态网格 分层实例化静态网格 遮挡 级联阴影贴图 编辑器优化正向与...

    这是教程的第 2 部分,旨在帮助开发人员提升 Unreal Engine* 4 (UE4) 的游戏性能。本教程对引擎内部和外部使用的一系列工具以及面向编辑器的最佳实践加以了概述,还提供了有助于提高帧速率和项目稳定性的脚本。

    编辑器优化
    正向与延迟渲染
    细节级别
    LOD 生成
    自动 LOD 生成
    LOD 资料
    实例化静态网格
    分层实例化静态网格
    遮挡
    级联阴影贴图
    编辑器优化

    正向与延迟渲染

    延迟渲染是 UE4 使用的标准渲染方式。虽然这种方式似乎是最佳的,但我们需要理解一些它对性能的重要影响,尤其是对于 VR 游戏和低端硬件的影响。在这些情况下使用正向渲染可能会更好。

    如欲了解更多关于正向渲染的效果,请参阅 Epic 文档。

    如果查看 Epic’s Marketplace 中的反射场景,我们可以看见延迟渲染和正向渲染之间一些明显的区别。
    图片描述
    图 13:延迟渲染的反射场景
    图片描述
    图 14:正向渲染的反射场景

    虽然正向渲染会因为反射、照明和阴影而导致丧失视觉保真,但剩余的场景从视觉上看没有改变,而性能的提高也许弥补了这种折衷。

    如果我们在英特尔 GPA 帧分析器工具内,使用延迟渲染查看场景的帧捕获,那么我们会看到该场景正在以 103.6 毫秒 (9 fps) 运行,照明和反射占据了大部分持续时间。
    图片描述
    图 15:使用英特尔® 高清显卡 530 的延迟渲染捕获反射场景

    通过查看正向渲染捕获,我们发现场景运行时间已经从 103.6 毫秒降低到 44.0 毫秒,或者说优化了 259%,其中大部分时间由基础通道和后处理占据,两者均可以进一步优化。
    图片描述
    图 16: 使用英特尔® 高清显卡 530 的正向渲染捕获反射场景

    细节级别

    UE4 内部静态网格拥有成千甚至上万的三角形,可以将 3D 艺术家想要加入他们作品的全部最小的细节展示出来。但是,当玩家远离这种模型时,即使引擎仍然在渲染全部三角形,他们也看不到任何细节。为了解决这个问题并优化游戏,我们可以使用细节级别 (LOD) 将该细节拉近,同时仍显示远处较弱的模型。

    LOD 生成

    在标准管道下,LOD 由 3D 建模人员在创建该模型时创建。由于这种方法可以对最终外观实现最大控制,UE4 现在加入了可生成 LOD 的极佳工具。

    自动 LOD 生成

    前往该模型的细节选项卡,可自动生成静态网格 LOD。在LOD Settings 面板选择需要创建的 LOD 数量。
    图片描述
    图 17: 创建自动生成的细节级别。

    点击 Apply Changes…查看全文
    了解更多相关内容,请关注CSDN英特尔开发专区

    Intel技术双周刊已全面开启:订阅请点击这里

    展开全文
  • 因为虚幻的架构,我们美术做一个效果只能使用材质编辑器。这让我很不舒服,稍微想做点特别点的效果就没办法了。我又是天天在公司用自研引擎的人,这种限制让人很不舒服。所以我开始修改了虚幻的shadingmode之类的。...

        因为虚幻的架构,我们美术做一个效果只能使用材质编辑器。这让我很不舒服,稍微想做点特别点的效果就没办法了。我又是天天在公司用自研引擎的人,这种限制让人很不舒服。所以我开始修改了虚幻的shadingmode之类的。但是感觉自己还是不满足,想调个多pass虚幻都不让我做,所以我打算加个pass什么的。但是虚幻加pass可不像unity那么简单,只有操刀去改源码了。然后我又反观了一下我前几篇博客,只简单讲了一下怎么改代码,没说原理。所以这个系列我打算系统说一下虚幻的一个架构。当然虚幻如此庞大,我也有很多不知道的地方。
        其实我写博客的目的很简单,就是想记录一下自己做的东西,有时候自己翻一下,再把问题再想一下,也许会有新的发现。虚幻的渲染方面的资料也是少得可怜,研究的人也少得可怜。大部分牛人都自己去造轮子去了。我只是个技术美术,造轮子的事情还是交给图形程序吧。不过研究虚幻4的确学到很多。如果有大牛看到我的文章中有错误,还请留言斧正。

    首先在看这个系列之前,你需要具备一下:
    (1)至少要敲过简单的渲染器,不管是拿dx敲还是拿gl敲或者vk之类的。
    (2)对虚幻引擎有一定了解,对虚幻的渲染有一定了解。可以看我前几篇文章,或许可以有所帮助。
    (3)C++基础。其实本人c++水平也是一般般(常常受到公司程序大牛的鄙视,不过我是美术哈哈哈)。

    那么下面就正式开始吧!
    首先,虚幻有很多个管线的。Forward和Tiled Based Deferred Lighting 还有专门适用于手机端的。我目前只研究了Deferred。首先找到。在这个函数里你将会看到很多熟悉的函数名称
    虚幻就是通过调用这些函数来一步步绘制的。是不是很眼熟?这个就是各大论坛啦,博客啦讲的虚幻渲染流程的真面目。

    下面就是官方的DrawOrder了。那么这个顺序是怎么来的呢。就是上面那个函数的调用顺序。

    再打开这个Render函数,你就将看到延迟渲染一帧所调用的各个函数。(反正我看了半天就看到个大概的渲染顺序之外,还是啥也不知道)


    那么当我们把一个模型托到场景里,这个模型被渲染出来的整个流程到底是什么样的呢?这个流程其实是非常庞大的。下面我就来一个一个拆分。
    (1)第一步:资源准备阶段。这个阶段包括顶点缓冲区的准备,索引缓冲区的准备。这一步由场景代理管理完成。当然从磁盘里读取模型资源这些就涉及到StaticMesh这些了。想了解这一步可以去看我以前的博客,或者直接去看UPrimitiveComponent,UMeshComponent,UStaticMeshComponent,UCableComponent,UCustomMeshComponent。当你把这些源码全部研究一遍后,这个阶段算是了解了。这个阶段我不打算再描述了,因为已经有了很多现成的代码了。

    (2)第二步就是shader资源的准备了,这个又是一个非常大的话题了。可以去看我以前关于给改材质编辑器和加shadingmode的文章便可以有个大概的了解。这一步我还会进一步阐述。
    (3)第三步就是绘制了。

    我们先不看Render函数那些复杂的调用,我们把精力先集中到shader层面来。一张画面是怎么开始绘制的呢?
    通过这个我们便能知道一个大概的绘制流程(千万别以为虚幻只有这几步,不过主要的大概的流程是这样)。先绘制那些深度啊,初始化视口啦我们先不管。我们来看下这个BasePass。这个BasePass干的事情就是把GBuffer画出来。

    这里就是像素着色器的入口。绘制完这一步后,我们就有了GBuffer然后再绘制剩下的。环境遮罩骤就先不说了。来看看最重要的光照部分。

    光照部分的入口在这里:
    虚幻的TiledDeferredLighting的渲染方式。不知道这个的去看毛星云的RTR3的博客的光照那节,讲得特别好。这里给个传送门:https://blog.csdn.net/poem_qianmo/article/details/77142101

    这里会调用
    GetDynamicLighting这个函数会调用

    这里会接着调用


    看到这里就很熟悉了,看过前面我修改shadingmode的博客应该会对这里很熟悉。
    lighting绘制完了之后就会绘制一些反射啊之类的东西了,然后就是透明物体啊后期啊。这些后面会慢慢分析他们。我们先把两个最重量级的研究了。

    接下来我们研究一下fog渲染阶段。找到FogRendering.cpp你就会发现,其实绘制fog的是一个globalshader。前面绘制各个物体的是materialshader。

    你会发现绘制fog的是一个globalshader。虚幻一共有这么几种shader:Globalshader  materialshader和meshshader。

    这篇博客只是一个概述性和引导性的。只是说明一下虚幻绘制的一个大概情况。下一卷我将演示一下怎么自己写个shader,引擎识别它,编译它,然后如何cpu和gpu进行信息交流的。

    展开全文
  • 我们还将快速了解Unreal是如何进行绘制网格的! 纯照明通道的EpicGame照片角色实例 绘制政策虚幻中的绘制策略更像是一个概念,而不是特定的类,因为它们并不都共享相同的基类。从概念上讲,绘制策略确定哪些着色器...
  • 无论是Unreal3、Crysis还是星际2,都已经支持或者准备支持这个技术。 不过因为国内这种环境,真正在项目中能用到的可能并不多,不知道这次星际2出来后,情况会不会有所变化。^_^ 本文是对Gems2这篇文章的一个补充...
  • 针对移动端特性的渲染优化(续)

    千次阅读 2018-03-20 11:20:26
    本文接着之前的文章《基于移动端tbdr特性gpu的渲染优化》,继续补充一些移动端渲染优化的点尽量使用...它涉及到对当前framelist data 的立即绘制(理论上framelist data越晚绘制越好,越利于延迟渲染),然后额外的f...
  • 在计算机图形学中,延迟渲染( Deferred Rendering) ,即延迟着色(Deferred Shading),是将着色计算延迟到深度测试之后进行处理的一种渲染方法。延迟着色技术的最大的优势就是将光源的数目和场景中物体的数目在...
  • 三年前开始接触ogre引擎,由于工作需要一直进行图形方面的研发和尝试,随着引擎技术的进步,ogre的与Cryengine3、Unreal3等一线图形引擎在画面上的差距越来越大,主要原因在于ogre目前的设计趋于一套开放性的架构,...
  • Unreal使用一些魔法来绑定C++的着色器表现与等价HLSL类,使用顶点工厂(Vertex Factory)来将顶点着色器的控制数据上传到GPU。从本章起,我们将使用Unreal的类名来讨论问题,让它们更容易被你自己查找。 我们将专注于...
  • 翻译:yarswang 转载请保留   如前所述,Unreal将编译给定着色器/材质的多个排列以应对不同的用例。 修改材质时,Unreal将查找该着色器使用的 .ush/.usf 文件并重新加载它们。 然后...
  • Unreal3 DirectX 11 中的延迟着色

    千次阅读 2011-12-28 12:02:47
    采用延迟着色后,渲染这些网格物体的时候会将诸如漫反射颜色这样的材质属性存储在渲染目标(被称为 GBuffer)中,但是没有进行光照。这样,在后续的‘延迟渲染中,每束光源都会在 Gbuffer 中查找给定像素的材质...
  • 翻译:yarswang 转载请保留   延迟着色基本通道 在第3章,我们完成了对C++方面的研究,并最终准备好了解GPU上的一切是如何工作的。 我们将深入研究顶点工厂如何控制公共基本顶...
  • Unreal Engine 3到Unreal Engine 4

    千次阅读 2015-07-02 19:38:32
    介绍Unreal Engine 4与Unreal Engine 3的一些不同点。
  • 作者:王文斓虚拟现实(VR)能够带给用户前所未有的沉浸体验,但同时由于双目渲染、低延迟、高分辨率、强制垂直同步(vsync)等特性使VR对CPU渲染线程和逻辑线程,以及GPU的计算压力较大[1]。如何能有效分析VR应用的性能...
  • 想用Unreal Engine 4 制作水墨国画风格的渲染效果,用后处理加上材质球的渲染效果。不知道有没有哪位大神有这方面的教程思路文档。 现在网上能查到的都是比较欧美手绘风格的教程或者案例,就是没有国画水墨风的渲染...
  • 看了unreal engine4的ElementalTech Demo和Featuresand Development Walkthrough两个视频,效果还是非常赞的。看来epic这几年是下了大力气了。...下面说说ue4的重要特性吧 ...1. 延迟渲染 Ue4完全...
  • 翻译:yarswang 转载请保留 添加新的着色模型 Unreal支持几种常见的着色模型,可满足大多数游戏的需求。Unreal支持广义的微面高光(microfacet specular)作为其默认的光照模型,但也具有...
1 2 3 4 5 ... 20
收藏数 770
精华内容 308
关键字:

unreal 延迟渲染