unreal 函数 渲染_unreal 调用蓝图中函数 - CSDN
  • 虚幻引擎 4 渲染流程分析http://www.52vr.com/article-2104-1.html UE4渲染系统结构解析...Unreal Engine 4 的渲染流程总复习http://gad.qq.com/article/detail/22342 虚幻引擎 4 渲染流...

    虚幻引擎 4 渲染流程分析 http://www.52vr.com/article-2104-1.html

    UE4渲染系统结构解析 http://www.yanglajiao.com/article/jiangdengc/60141724

    Unreal Engine 4 的渲染流程总复习 http://gad.qq.com/article/detail/22342

     

    虚幻引擎 4 渲染流程分析

      今天为大家带来的是转载自虚幻引擎爱好者王文涛的博客文章《虚幻引擎 4 渲染流程分析》,这篇文章通过 Renderdoc 的分析通俗地介绍虚幻引擎 4 的渲染过程。

     

          UE4作为当今商业引擎界的大佬,渲染和图形质量一直是首屈一指的水准,但是相对于unity来说UE4基本上是一套完整方案提供,不通过源码修改对渲染进行定制的可能性比较小,而且同时UE4这方面的文档很少,因此这篇文章就是想通过分析UE4的渲染过程,来给大家针对自己使用ue4开发的游戏的内容特点做出优化带来启发。

          我们使用Renderdoc对UE4(PC,DX11)截帧,UE4的版本为4.18. 可以看到UE4一帧画面的渲染过程如下

     

    145107y3oyc00vovchfcx3

     

          可以看到的是整个渲染流程还是很清晰明了的,接下来就会逐步分析每个过程。

     

    1.Z-Prepass
    UE4在deferred shading 过程之前这个,会有一系列的culling过程剔除掉不需要的像素或者几何体,基本上可以猜测是UE4是为了减轻后期在deferred shadinggbuffer 生成中的庞大计算量,第一遍的zpass会先渲染一遍场景中的几何,用于生产SceneDepthZ以及HZB buffer,格式为R24G8TYPELESS

     

    2.Compute light grid
    在Pre-Z之后UE4会把场景中的灯光按照屏幕空间分成相应的grid,类似于cluster shading的方法,注意这里的grid只考虑点光源,聚光灯,以及reflection captures,UE4这一步是通过compute shader实现的,所以只在sm>5.0的平台上有。具体shader代码在LightGridInjection.usf,阅读代码之后我们可以发现 UE4的灯光空间grid的划分是按照指数增长的。也就是每个grid的z随着距离会增长。

    在真正计算光照时,我们可以用GridIndex来快速决定某点是否受到灯光影响。Lightculling的方法在forward下对于提高灯光的渲染效率是十分有用的,但UE4在DS下仍然保有了这一个过程。其效果存疑,初步推测是为了和UE4新加的Forward renderer统一。

     

    3.Occlusion query
    这一步在light culling之后,和Pre-Z pass 不同的是,Occlusion query 主要在物体级别做culling。ue4同样使用的是hardware occlusion queries(GPU query)的技术。在这一个pass中,所有的不透明物体会被渲染为一个occluder(包围盒):

     

    145107p00w00ec5ue154da

    在根据深度计算query之后,query的数据会传回cpu,我们就可以计算每个物体有多少像素可见。这样我们就能知道物体最终是否会被渲染。

    在不透明物体的query pass之后。Unreal 还有一些其他的query pass,例如灯光(点光源)会有一个ShadowFrustumQUeries(一般是画一个球体)反射则有 PlanarReflection queries(一般是画一个 Cube)

     

    4.HZB generation
    接下来UE4会生成场景的Hi-z(Hierarchical Z),R16_Float 格式,这一步也就是对之前的zbuffer做连续的downsample。HZB buffer会在之后的计算中起到很多作用,特别是Image based 的lighting技术,例如SSR等等。

     

    5.ShadowMap 渲染 
    接下来的一步就是渲染shadowmap(shadowDepth,注意,这里指的是实时阴影的计算。根据UE4中灯光类型的不同,实时阴影的计算也有一定的差别。
    UE4中的灯光类 型分为stationary, static,moveable三种,相应的每种灯光cast realtime shadow的方式也不同。

    对于stationary light,静态物体的阴影会bake到static shadowmap,shadowmap只计算标记为动态物体的阴影,而对于dynamic light 会对所有物体投射阴影,而静态灯光不会产生实时阴影。

    ue4首先会渲染方向光的阴影,一般会渲染3split的cascade shadow ,所以我们能在截帧信息看到split0, split1和split2,注意cascade split数目在ue4中也是可以在方向光参数中设置的变量。

     

    145107aai4prszgyp4tyri

     

    之后是stationary light的shadow渲染,注意这里只针对场景中的moveable的物体。

    最后是对于movable light的渲染,对于movable的方向光,ue4仍然是cascade shadow map计算阴影,需要注意的是对于movable的点光源,ue4使用了cubemap shadowmap,在cubeshadowmap的第一个pass CopyCachedShadowMap中,ue4会直接cachecopy static物体的shadowmap,例如这个场景中

     

    145107os330cple77s7zy0

     

    圆柱体为static,其他两个物体设为movable,因此最后我们能看到Shadow 只画了两个几何体。

     

     

    145108y0d0p3jzp75j470p

     

    最后动态物体的shadow会添加在这个cubemap上面。

     

    145108tll283dyblp3p1a8

    145108sw4pnrztoa9na4oa

    注意 shadowcubemap使用了geometry shader来选择画在那个面上。

     

    6.G-prepass
    其实在g-prepass之前还会渲染一个volumtric fog(如果场景中有的话) 这里我们先跳过,
    G-prepass就是ue4中常说的basspass,这个bass会真正的渲染场景并产生我们在deferred shading 中需要的G-buffers:

     

    145109r7a2u4i5855aqq5h

     

    SceneColorDefferd:包含了间接光照信息,例如lightmap和lightprobe(ue4叫ILC)

     

    145109j2nbgfdfff2b7ee4

    场景Normal

     

    145109gkres65uprloj6cr

    场景Albedo颜色

     

    145109zltp7aezpzhlfpph

    PBR Specular信息

     

    除此之外还有针对特殊shading模型的特殊Custom Data RT(例如 头发的tangent sss等)和Pre baked shadow factors RT,一般情况下UE4的渲染需要5-6个RT输出,除了产生GBuffer的计算之外,在这一步UE4还会计算完间接光照的信息,主要包括采集lightmap信息(静态物体)和球谐函数信息(Indirect lighting cache或者Volumetric light map)
    UE4在4.18引入了新的半动态光照技术也就是Volumetric lightmap,相比于之前的 ILC机制,Volumetric lightmap能够更加细致的根据物体的空间位置对球谐函数probe做插值(ILC是每个物体做插值)

     

    145109xarl00rdol9d0groVolumetric lightmap的Texture3d

     

    7.Velocity rendering
    在basepass之后是Velocity rendering,Velocity buffer会渲染为一张R16B16UNorm,主要用于motion blur和TAA

     

    8.Pre-Lighting
    UE4在这一部分会计算DeferredDecal(屏幕空间贴花),和AmbientOcclusion, UE4的屏幕空间AO考虑了深度和Normal信息,UE4的SSAO分为两个Pass,第一个pass会计算一个四分之一分辨率的RT,使用的是四分之一分辨率的normal和depth, 注意这里就用了之前生成的HZB buffer,第二个pass会渲染一个全分辨率RT并与第一个combine.注意最后计算的结果会乘到SceneColorDeferred这个RT上.

     

    145109oa9ls1rbankhd1eb

     

    9.Lighting

    接下来就是光照的渲染部分,UE4在渲染灯光光照时会先处理translucent 物体的照明。

    在这之后会分别计算阴影灯光和非阴影灯光的standarddeferredlighting,

    在这个pass之后,SceneColorDeferred RT就会包含最后直接光照的结果

     

    145110sd5t5okpdto5pa81

     

    10.ImageBased lighting

    接下来UE4会渲染屏幕空间的一些光照效果,例如SSR(屏幕空间反射)还有ReflectionProbe等等

    SSR会用到我们之前生成的HZB,在屏幕空间做Zbuffer的raymarching ,同时ue4的SSR会每帧jitter和TAA结合来提高质量。当击中时SSR的shader会采样上一帧的RT来获得颜色

     

    145110q8m28uoebewruezz

     

    在SSR之后是ReflectionEnvironment Pass。这一步会结合场景中的反射球和之前的SSR结果会叠加到SceneColorDeferred这个RT中。

     

    11. Post Processing
    最后一步是UE4的Postprocessing,主要包括Temporal AA; Bloom;EyeAdaption等等这些可以自定义的内容。

    UE4 的TAA会经历两个pass,第一个pass会处理没被stencil的像素(例如有粒子特效的时候),会用到MainRT和velocity buffer,第二个pass会处理例如粒子这样stencilled的pixel。两个pass的区别在于混合当前RT和History buffer的blendfactor的不同,第一个pass的blendfactor会根据pixel的亮度距离等等变化,而第二个pass的blendfactor啧固定为0.25,也就是说第二个pass的像素会更多考虑当前像素,很可能这是为了减少TAA中很常见的ghosting effect

    注意:TAA的处理只包含动态的光照部分,也就是纯动态光照。

    145110gy1vvvmweheu4mme

     

    以上的分析还是省略了很多的细节,例如半透照明这种还没涉及。从整体的流程分析来看,UE4在设计渲染方案的时候还是最大限度的考虑了功能的最大化,UE4的DS renderer包含了非常齐全的光照特效,包括静态的lightmap,动态的lightprobe,屏幕空间的lighting,以及一些影视级别的渲染技术,例如头发的渲染模型等等,但同时为了功能UE4的计算任务是很繁重的,因此也就不难理解为什么UE4需要Pre-Z和Occlusion Culling去剔除掉不用的像素。当然,对于使用UE4制作游戏的团队来说,根据游戏内容特点,画面的艺术风格,渲染管线都没必要一成不变,例如对于一款开放世界的野外生存游戏。我们可以考虑省掉Pre-Z的过程,或者,只用地表去画Pre-Z,又或者对于NPR画面的游戏我们完全可以不需要6-7个RT去做Deferred shading。UE4应对这些定制化开发的需求的方法就是:开源。代码就在DeferredShadingRenderer.cpp里。

     

     

     

    展开全文
  • 想要更改引擎的渲染管线,为自定义的渲染模型添加宏,进行到设置渲染模型这一步却卡住了 ![参考代码](https://pic4.zhimg.com/80/v2-a2414e1a2f2ac128edfc3c482e0bc57b_720w.jpg) 原本在引擎的MaterialShared....
  • 我们还将快速了解Unreal是如何进行绘制网格的! 纯照明通道的EpicGame照片角色实例 绘制政策虚幻中的绘制策略更像是一个概念,而不是特定的类,因为它们并不都共享相同的基类。从概念上讲,绘制策略确定哪些着色器...

    https://medium.com/@lordned/unreal-engine-4-rendering-part-3-drawing-policies-89bb1a3c641b

    翻译:yarswang 转载请保留


    引言

    此篇我们将介绍绘制策略,绘制策略工厂以及它们如何与我们迄今为止学到的所有系统进行交互。我们还将快速了解Unreal是如何进行绘制网格的!

     

    纯照明通道的EpicGame照片角色实例

     

    绘制政策

    虚幻中的绘制策略更像是一个概念,而不是特定的类,因为它们并不都共享相同的基类。从概念上讲,绘制策略确定哪些着色器变体用于绘制某些内容,但它不会选择它绘制的内容与时机!我们将看两个绘制策略,一个用于Unreal的深度预传,另一个用于Unreal的基本传递,这要复杂得多。

    一个绘制策略类

     

    FDepthDrawingPolicy

    深度绘制策略是绘制策略可以有多么简单的一个很好的例子。在它的构造函数中,它要求材质为特定顶点工厂找到特定类型的着色器:

     

    VertexShader =InMaterial.GetShader<TDepthOnlyVS<false>>(VertexFactory->GetType());

     

    TDepthOnlyVSFMeshMaterialShader的一个实现,并使用适当的宏将自己声明为着色器。 虚幻的句柄试图编译材质/着色器/顶点工厂的所有可能的排列,所以它应该能够找到它。如果您的ShouldCache函数设置不正确,那么它将在此失败,引擎抛出一个断言并让你修复它!

     

    然后,它会查看它应该绘制的材料,以确定该材质是否启用了曲面细分(tessellation) - 如果它确实已启用,则深度绘制策略会查找外壳(hull)和域着色器(domainshader):

     

    HullShader= InMaterial.GetShader<FDepthOnlyHS>(VertexFactory->GetType());
    DomainShader =InMaterial.GetShader<FDepthOnlyDS>(VertexFactory->GetType());

     

    绘制策略还可以通过SetSharedStateSetMeshRenderState函数在着色器上设置参数,但它们通常只是将这些参数传递给当前绑定的着色器。

     

    FBasePassDrawingPolicy

    这是Unreal开始使用他们的宏和模板变得棘手的地方。我们来考虑一下延迟渲染中的基本通道。你有许多不同的材质使用不同的硬件功能(如曲面细分),使用不同的顶点工厂,你需要特定于灯光的变化。这是一个庞大的排列,Unreal使用几个宏来实现这一点。如果这没有多大意义,请不要担心。进行更改并不重要,知道它存在即可。

     

    他们首先会制作一个FBasePassDrawingPolicy模板名为template<typename LightMapPolicyType> class TBasePassDrawingPolicypublicFBasePassDrawingPolicy,构造函数只调用另一个模板函数。这反过来调用另一个模板函数,但这次是针对每种照明类型的特定枚举。

     

    现在他们知道他们所试图获得着色器的照明策略,他们使用与深度绘制策略相同的InMaterial.GetShader函数,但这次他们得到了一个模板化的着色器类!

     

    VertexShader= InMaterial.GetShader<TBasePassVS<TUniformLightMapPolicy<Policy>,false>>(VertexFactoryType);

     

    感谢你一路关注模板链,但重要的是要了解Unreal如何了解所有可能的实现。答案就是几个嵌套的宏!跳到BasePassRendering.cpp的顶部,我们来从头到尾看它们。

     

    第一个宏是IMPLEMENT_BASEPASS_VERTEXSHADER_TYPE,它通过创建新的typedef来为给定的LightMapPolicyTypeLightMapPolicyName注册顶点,外壳和域材质着色器(使用我们在Shaders一节中讨论过的IMPLEMENT_MATERIAL_SHADER_TYPE宏)。所以现在我们知道调用IMPLEMENT_BASEPASS_VERTEXSHADER_TYPE为我们注册顶点着色器。

     

    第二个宏是IMPLEMENT_BASEPASS_LIGHTMAPPED_SHADER_TYPE,它接受LightMapPolicyTypeLightMapPolicyName并调用IMPLEMENT_BASEPASS_VERTEXSHADER_TYPEIMPLEMENT_BASEPASS_PIXELSHADER_TYPE(我们没有谈到,但工作方式与顶点相同)。这个宏让我们为任何给定的LightMap创建一个完整的着色器链(顶点和像素)。最后,Unreal将此宏调用16次,传递LightMapPolicyTypesLightMapPolicyNames的不同组合。

     

    在之前调用InMaterial.GetShader<...>函数的过程中,其中一个函数为每个LightMapPolicyType都有一个大的switch语句,以返回正确的函数。因此,我们知道Unreal正在为我们宣布所有变体,因此GetShader能够做出正确的事情!

     

    绘图政策工厂

    因此我们知道绘制策略确定了给定材质和顶点工厂使用哪个特定着色器,这允许Unreal创建诸如“获取仅深度着色器”或“获得具有点光源代码的着色器”的策略。但是是什么生成了一个绘制策略,它如何知道要生成哪一个?它如何知道要绘制什么?这就是绘制策略工厂的用武之地。他们检查材质或顶点工厂的状态,然后可以创建正确的绘制策略。

    FDepthDrawingPolicyFactory

    我们使用FDepthDrawingPolicyFactory来作为(相对)简单的示例。 只有三个函数,AddStaticMeshDrawDynamicMeshDrawStaticMesh。 调用AddStaticMesh时,PolicyFactory将查看有关要绘制的材质和资源的设置,并确定要创建的相应绘制策略。然后,Unreal将该绘制策略放入即将绘制的FScene内的列表中。

     

    例如,FDepthDrawingPolicyFactory查看材质以查看它是否修改了网格位置。 如果它修改了网格位置,那么它会创建一个FDepthDrawingPolicy并将其添加到FScene内部的“MaskedDepthDrawList”中。 如果材质没有修改网格位置,那么它会创建一个FPositionOnlyDepthDrawingPolicy(它会查找不同的着色器变体!)并将其添加到FScene中的不同列表中。

     

    绘制策略工厂创建绘制策略

     

    FDepthDrawingPolicyFactory还能够绘制给定的网格批次,再次检查设置并创建绘制策略。但是,不是将其添加到列表中,而是通过RHI层为GPU设置状态,然后调用另一个绘制策略来实际绘制网格。

     

    告诉绘图政策工厂进行绘制

    最终我们知道了它的根源,并了解所有这些部分是如何发挥作用的。 还记得绘制策略或绘图政策工厂没有共享基类吗? 我们已经达到了“代码只是专门了解它们并在不同时间调用它们”的程度。

    FStaticMesh::AddToDrawLists

    我们的FDepthDrawingPolicyFactory有一个名为AddStaticMesh的函数,因此创建它的类与静态网格物体相关并不奇怪!调用AddToDrawLists时,它会检查资源和项目设置以决定如何处理它。它首先调用
    FHitProxyDrawingPolicyFactory :: AddStaticMesh,然后调用
    FShadowDepthDrawingPolicyFactory ::AddStaticMesh,然后调用
    FDepthDrawingPolicyFactory :: AddStaticMesh,最后调用
    FBasePassOpaqueDrawingPolicyFactory ::AddStaticMesh
    FVelocityDrawingPolicyFactory :: AddStaticMesh,哇!

     

    因此,我们知道何时将FStaticMesh标记为要添加到绘制列表中,它会创建各种绘制策略工厂(然后创建绘制策略并将其添加到正确的列表中)。调用此函数的具体细节并不重要(虽然请参阅FPrimitiveSceneInfo :: AddStaticMeshes并从那里开始),但我们知道必须告诉深度传递在基本传递之前绘制以及执行阴影,等等

    FDeferredShadingRenderer,这是一个庞大的类,可以处理按正确顺序绘制的所有内容。 FDeferredShadingRenderer:: Render启动整个过程并控制渲染操作的顺序。我们来看看基本绘图政策工厂; Render函数调用
    FDeferredShadingSceneRenderer :: RenderBasePass,后者又调用
    FDeferredShadingSceneRenderer ::RenderBasePassView调用
    FDeferredShadingSceneRenderer ::RenderBasePassDynamicData,它最终在循环中调用我们的
    FBasePassOpaqueDrawingPolicyFactory ::DrawDynamicMesh,每次都向它传递一个不同的网格。

     

    综述

    绘图策略为给定材质,顶点工厂和着色器组合找到正确的着色器排列。 开发人员根据策略指定着色器类型以完成不同的事情。 绘图策略工厂处理创建绘图策略并将其添加到适当的列表。最后,通过一个长链继承,FDeferredShadingRenderer :: Render最终循环遍历各个列表并调用它们的Draw函数。


    展开全文
  • (这当且仅当做Unreal的帮助文档)。 图形编程 模块 渲染器代码存在于其自身的模块中。此模块将编译为非单块版本的一个 dll 文件。这可以使迭代更快,因为在渲染代码变更时无需重新链接整个应用程序。渲染器...

    @author: 黑袍小道

    随缘查看

       

    说明

    由于搬山的渲染这部分担心自己理解错误,故而搬移官方下,后面整个完成再反过来更新

    (这当且仅当做Unreal的帮助文档)

       

    图形编程

    模块

    渲染器代码存在于其自身的模块中。此模块将编译为非单块版本的一个 dll 文件。这可以使迭代更快,因为在渲染代码变更时无需重新链接整个应用程序。渲染器模块取决于引擎,因为其拥有许多向引擎的回调。然而当引擎需要调用渲染器中的某些代码时,这会通过某个接口来完成,通常为 IRendererModule FSceneInterface

    场景代表

    UE4 中,渲染器所见的场景由基本组件和 FScene 中存储的多种其他结构的列表定义。将维护一个基元的八叉树,用于加速空间查询。

    主要场景类

    UE4 中拥有和游戏线程并行运行的渲染线程。

    主要的类为:

    描述

    UWorld

    包含多个可交互的 Actor 和组件的世界场景。关卡可以流送进入和退出世界场景,且程序中可以同时有多个世界场景处于激活状态。

    ULevel

    一同加载/卸载并保存在同一地图文件中的 Actor 和组件合集。

    USceneComponent

    需要添加到 FScene 中的任意对象的基础类,如光照、网格体、雾等。

    UPrimitiveComponent

    可渲染或进行物理交互的任意资源的基础类。也可以作为可视性剔除的粒度和渲染属性规范(投射阴影等)。与所有 UObjects 一样,游戏线程拥有所有变量和状态,渲染线程不应直接对其进行访问。

    ULightComponent

    代表光源。渲染器负责计算和添加其对场景的贡献。

    FScene

    UWorld 的渲染器版本。对象仅在其被添加到 FScene(注册组件时调用)后才会存在于渲染器中。渲染线程拥有 FScene 中的所有状态,游戏线程无法直接对其进行修改。

    FPrimitiveSceneProxy

    UPrimitiveComponent 的渲染器版本,为渲染线程映射 UPrimitiveComponent 状态。存在于引擎模块中,用于划分为子类以支持不同类型的基元(骨架、刚体、BSP 等)。实现某些非常重要的函数,如 GetViewRelevanceDrawDynamicElements 等。

    FPrimitiveSceneInfo

    内部渲染器状态(FRendererModule 实现专有),对应于 UPrimitiveComponent FPrimitiveSceneProxy。存在于渲染器模块中,因此引擎看不到它。

    FSceneView

    单个视图到一个 FScene 的引擎代表。视图可以通过对 FSceneRenderer::Render 的不同调用的不同视图来渲染(多编辑器视口)或通过对 FSceneRenderer::Render 的同一调用中的多个视图来渲染(分屏游戏)。为每个帧构建新视图。

    FViewInfo

    视图的内部渲染器代表,存在于渲染器模块中。

    FSceneViewState

    ViewState 存储有关在多个帧中需要的某个视图的私有渲染器信息。在游戏中,每个 ULocalPlayer 只有一个视图状态。

    FSceneRenderer

    为每个帧创建的类,用于封装跨帧的临时对象。

    下面按其所在的模块列出了各种主类。

    引擎模块

    渲染器模块

    UWorld

    FScene

    UPrimitiveComponent / FPrimitiveSceneProxy

    FPrimitiveSceneInfo

    FSceneView

    FViewInfo

    ULocalPlayer

    FSceneViewState

    ULightComponent / FLightSceneProxy

    FLightSceneInfo

    以及相同类(按哪个线程对其状态拥有所有权进行排列)。

    游戏线程

    渲染线程

    UWorld

    FScene

    UPrimitiveComponent

    FPrimitiveSceneProxy / FPrimitiveSceneInfo

      

    FSceneView / FViewInfo

    ULocalPlayer

    FSceneViewState

    ULightComponent

    FLightSceneProxy / FLightSceneInfo

       

    材质类

    描述

    FMaterial

    连接用于渲染的材质的接口。可用于访问材质属性(如混合模式)。包含被渲染器用于检索个体着色器的着色器地图。

    FMaterialResource

    UMaterial FMaterial 接口实现。

    FMaterialRenderProxy

    材质在渲染线程上的代表。可用于访问 FMaterial 接口和各个标量、向量和纹理参数。

    UMaterialInterface

    [abstract] 用于材质功能的游戏线程接口。用于检索用于渲染的 FMaterialRenderProxy 和用作来源的 UMaterial

    UMaterial

    材质资源。授权为节点图形。计算用于着色、设置混合模式等的材质属性。

    UMaterialInstance

    [abstract] UMaterial 的实例。使用 UMaterial 中的节点图形,但提供不同参数(标量、向量、纹理、静态切换)。每个实例都有一个父项 UMaterialInterface。因此,材质实例的父项可能是 UMaterial 或另一个 UMaterialInstance。这会形成一个链,最终通往 UMaterial

    UMaterialInstanceConstant

    只能在编辑器中修改的 UMaterialInstance。可以提供标量、向量、纹理和静态开关参数。

    UMaterialInstanceDynamic

    可以在运行时修改的 UMaterialInstance。可提供标量、向量和纹理参数。无法提供静态开关参数,且无法成为另一 UMaterialInstance 的父项。

       

    基元组件和代理

    基元(就是Prim)组件是可视性和相关性确定的基本单位。例如,遮蔽和视锥剔除都是按基元进行的。因此在设计系统时,考虑组件的大小十分重要。每个组件都有一个边界,用于多种操作,如剔除、阴影投射和光照影响确定。

    组件只有在注册之后才会对场景(以及渲染器)可见。

    更改组件属性的游戏线程代码必须调用组件上的 MarkRenderStateDirty(),将更改传播到渲染线程。

    FPrimitiveSceneProxy FPrimitiveSceneInfo

    FPrimitiveSceneProxy UPrimitiveComponent 的渲染线程版本,用于根据组件类型划分子类。

    它存在于引擎模块中,并在渲染通道中调用函数。

    FPrimitiveSceneInfo 是基元组件状态,为渲染器模块私有。

    重要的 FPrimitiveSceneProxy 方法

    函数

    描述

    GetViewRelevance

    在帧的开始从 InitViews 调用,并返回填充的 FPrimitiveViewRelevance

    DrawDynamicElements

    调用,以便在某代理相关的任何通道中绘制该代理。仅在代理表示自己拥有动态相关性时调用。

    DrawStaticElements

    调用以在基元与游戏线程相连时提交代理的 StaticMesh 元素。仅在代理表示自己拥有静态相关性时调用。

       

    场景渲染顺序

    渲染器按照其希望将数据整合给渲染目标的顺序处理场景。例如,仅 Depth 的通道会比 Base 通道先渲染,先填充 Heirarchical Z (HiZ),从而降低基础通道中的着色消耗。此顺序是按通道函数在 C++ 中调用的顺序静态决定的。

    相关性

    FPrimitiveViewRelevance 是说明通道与基元相关的信息。基元可能有存在不同相关性的多个元素,因此 FPrimitiveViewRelevance 相当于一个所有元素的相关性的逻辑 OR。这表示基元可以同时存在不透明和透明相关性,或动态和静态相关性;它们并非相互排斥。

    FPrimitiveViewRelevance 还会显示基元是否需要使用动态 (bDynamicRelevance) /或静态 (bStaticRelevance) 渲染路径。

    绘制规则

    绘制规则包括通过通道特定的着色器渲染网格体的逻辑。它们使用 FVertexFactory 接口来抽取网格体类型,并使用 FMaterial 接口来抽取材质详情。在最底层,一条绘制规则会负责一组网格体材质着色器以及一个顶点工厂,将顶点工厂的缓冲区与渲染硬件接口 (RHI) 绑定,将网格体材质着色器与 RHI 绑定,设置适当的着色器参数,然后执行 RHI 绘制调用。

    绘制规则方法

    函数

    描述

    Constructor

    从给定的顶点工厂和材质着色器地图,并存储这些引用。

    CreateBoundShaderState

    为绘制规则创建 RHI 边界着色器状态。

    Matches/Compare

    提供排列绘制规则与静态绘制列表中的其他项目的方法。Matches 必须比较 DrawShared 依赖的所有因素。

    DrawShared

    设置在从 Matches 返回 True 的绘制规则之间一致的 RHI 状态。例如,大多数绘制规则会为材质和顶点工厂排序,因此着色器参数只依赖可以设置的材质,并且可以绑定特定于该顶点工厂的顶点缓冲区。应尽可能在此处设置状态,而非在 SetMeshRenderState 设置,因为 DrawShared 在静态渲染路径中调用较少。

    SetMeshRenderState

    设置特定于此网格体的 RHI 状态,或 DrawShared 中未设置的任何项目。这比 DrawShared 调用的次数多得多,因此此处性能非常重要。

    DrawMesh

    实际发出 RHI 绘制调用。

       

    渲染路径

    UE4 拥有动态路径(能够提供更多的控制,但转换较慢)和静态渲染路径(缓存尽可能靠近 RHI 级别的场景转换)。差异基本上是整体上的,因为它们都在最底层使用绘制规则。应确保各个渲染通道(绘制规则)在需要时能够同时处理两个渲染路径。

    动态渲染路径

    动态渲染路径使用 TDynamicPrimitiveDrawer 并对每个要渲染的基元场景代理调用 DrawDynamicElements。需要使用动态路径来渲染的一组基元通过 FViewInfo::VisibleDynamicPrimitives 来跟踪。每个渲染通道都需要在此阵列上迭代,并调用各个基元上的 DrawDynamicElements。随后,代理的 DrawDynamicElements 需按需要组合出多个 FMeshElements,并将其随 DrawRichMesh TDynamicPrimitiveDrawer::DrawMesh 提交。这样最终会创建一个新的临时绘制规则,调用 CreateBoundShaderStateDrawSharedSetMeshRenderState 以及 DrawMesh

    静态渲染路径

    静态渲染路径通过静态绘制列表实现。网格体在连接到场景时会插入到绘制列表中。在插入过程中,将调用代理上的 DrawStaticElements,以收取 FStaticMeshElements。随后将随 CreateBoundShaderState 的结果创建并存储一个绘制规则实例。新的绘制示例将根据其 Compare Matches 函数排序,并插入到绘制列表中的适当位置(参见 TStaticMeshDrawList::AddMesh)。在 InitViews 中,包含静态绘制列表中的可见性数据的 bitarray 会初始化并传递到 TStaticMeshDrawList::DrawVisible(实际绘制绘制列表的地方)。DrawShared 只会对所有相互匹配的绘制规则调用一次,而 SetMeshRenderState DrawMesh 会对每个 FStaticMeshElement(参见 TStaticMeshDrawList::DrawElement)调用。

    静态渲染路径会将许多工作移动连接时间,这会大大加快渲染时的场景转换。在渲染线程上针对静态网格体时,静态绘制列表的渲染会快 3 倍,从而允许场景中出现多得多的静态网格体。由于静态绘制列表会在连接时间缓存数据,因此它们仅能缓存与视图无关的状态。很少重新连接但经常需要渲染的基元非常适合静态绘制列表。

    静态渲染路径可能会暴露出 bug,因为它每个状态桶只调用 DrawShared 一次。这些 bug 可能会很难发现,因为它们取决于场景中网格体的渲染顺序和连接顺序。特别的视图模式(如仅光照、无光照等)会强制所有基元使用动态路径,因此如果在强制动态渲染路径时 bug 消失,则其很可能是由于某绘制规则的 DrawShared / Matches 函数的错误实现而出现的。

    总体渲染顺序

    下面将说明从 FDeferredShadingSceneRenderer::Render 开始渲染一个帧时的控制流程:

    操作

    描述

    GSceneRenderTargets.Allocate

    按需要重新分配全局场景渲染目标,使其对当前视图足够大。

    InitViews

    通过多种剔除方法为视图初始化基元可见性,设立此帧可见的动态阴影、按需要交叉阴影视锥与世界场景(对整个场景的阴影或预阴影)。

    PrePass / Depth only pass

    RenderPrePass / FDepthDrawingPolicy。渲染遮挡物,对景深缓冲区仅输出景深。该通道可以在多种模式下工作:禁用、仅遮蔽,或完全景深,具体取决于活动状态的功能的需要。该通道通常的用途是初始化 Hierarchical Z 以降低 Base 通道的着色消耗(Base 通道的像素着色器消耗非常大)。

    Base pass

    RenderBasePass / TBasePassDrawingPolicy。渲染不透明和遮盖的材质,向 GBuffer 输出材质属性。光照图贡献和天空光照也会在此计算并加入场景颜色。

    Issue Occlusion Queries / BeginOcclusionTests

    提出将用于下一帧的 InitViews 的延迟遮蔽查询。这会通过渲染所查询物体周围的相邻的框、有时还会将相邻的框组合在一起以减少绘制调用来完成。

    Lighting

    阴影图将对各个光照渲染,光照贡献会累加到场景颜色,并使用标准延迟和平铺延迟着色。光照也会在透明光照体积中累加。

    Fog

    雾和大气在延迟通道中对不透明表面进行逐个像素计算。

    Translucency

    透明度累加到屏外渲染目标,在其中它应用了逐个顶点的雾化,因而可以整合到场景中。光照透明度在一个通道中计算最终光照以正确融合。

    Post Processing

    多种后期处理效果均通过 GBuffers 应用。透明度将合成到场景中。

    以上是相当简单概略的介绍。如需了解详情,请通读相关代码或输出的"profilegpu"日志。

    渲染硬件接口 (RHI)

    RHI 是平台特定的图形 API 之上的一个薄层。UE4 中的 RHI 抽象层尽可能低,这样大多数功能都能以与平台无关的代码写成,从而能够在支持所需功能层级的任何平台上运行。

    功能集将量化到 ERHIFeatureLevel 中,降低复杂程度。如果平台无法支持某个功能层级所需的全部功能,则其必须降低层级,直至能够全部支持。

    功能层级

    描述

    SM5

    通常对应于 D3D11 Shader Model 5,但由于 OpenGL 4.3 限制,仅有 16 种纹理可以使用。支持曲面细分、计算着色器和立方体贴图阵列。支持延迟着色路径。

    SM4

    对应 D3D11 Shader Model 4,这与 SM5 基本相同,但没有曲面细分、计算着色器和立方体贴图阵列。支持延迟着色路径。不支持眼适应,因为其使用计算着色器。

    ES2

    对应大多数 OpenGL ES2 移动设备支持的功能。使用削减向前着色路径。

    渲染状态分组

    渲染状态根据其影响的流程部分而分组。例如,RHISetDepthState 可设置所有与景深缓冲相关的状态。

    渲染状态默认值

    由于渲染状态数量众多,要在每次绘制之前对它们全部设置一遍是不现实的。为此,UE4 具有隐性设置的一组状态,它们被认为是设置为了默认值(因此在变更后必须恢复为默认值),另外还有一组少得多的状态需要显性设置。没有隐性默认值的状态有:

    • RHISetRenderTargets
    • RHISetBoundShaderState
    • RHISetDepthState
    • RHISetBlendState
    • RHISetRasterizerState
    • RHISetBoundShaderState 设置的着色器的任何依赖性

      其他所有状态均视为已设置为其默认值(即相关 TStaticState 的定义,如默认的蜡纸模板状态由 RHISetStencilState(TStaticStencilState<>::GetRHI()) 设置。

    展开全文
  • 本篇继续Unreal搬山部分的渲染模块的Shader部分, 主要牵扯模块RenderCore, ShaderCore, RHI, Materia. 可能分成N篇。 (这里放入的UE的模块框) (下一篇主要是UE灯光和着色简要[ush以及对应结构,和UE代码和...

    @author: 白袍小道

    转载悄悄说明下

    随缘查看,施主开心就好

       

    说明:

    本篇继续Unreal搬山部分的渲染模块的Shader部分,

    主要牵扯模块RenderCore, ShaderCore, RHI, Materia.

    可能分成N篇。

    (这里放入的UE的模块框)

    (下一篇主要是UE灯光和着色简要[ush以及对应结构,和UE代码和DX部分],然后是巴拉巴拉)

       

    前言:

    部分算法和流程的实现原理,和细节(往往这部分会成为优化的处理口)。

    梳理UEShader的结构,底层的接入,分层。

    UE着色使用和细节部分。

    对比反观差距和原因

       

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    第一部分、渲染管线和着色

    Shading Models

    描述物体的颜色如何根据表面等因素而变化 (例如方向,视图方向,和照明)

    1、通常具有控制外观变化的属性。

    2、控制这些变化的属性而决定了变化。

       

    评估

    设计着色实现时,需要根据计算结果进行划分他们的评估频率。

    首先,确定一个给定的结果在整个绘制调用中,计算总是不变的。在这种情况下,计算应用程序可以通过GPU计算(通常在CPU上)执行吗。着色器可以用于特别昂贵的计算。结果被传递给图形API通过统一着色器输入。

       

    说明

    1、虚拟机

    a\ 目前的着色语言都是 C-likelike 的着色语言,比如 HLSL,CG 和 GLSL GLSL,其被编译成独立于机器的汇语言 语言,也称为中间( IL )。

    这些汇编语言在单独的阶段,通常是驱动中被转化成实际机器 )。

    这些汇编语言在单独的阶段,通常是驱动中被转化成实际机器 语言。这样的安排可以兼容不同硬件实现些汇编被看做是定义一个作为着色译器.

    b\ 着色语言虚拟机可以理解为一个处多种类型寄存器 和数据源、预编了一系列指令的处理器。

    2、单指令多数据( SIMD), 寄存器.

    a\ 一次DrawCall会通过API做一次(一系列)的图元绘制,从而驱使图形管线运行。[如Draw,DrawInstance, …..]

    b\ 输入,输出和交接。

    c\ Shader的语句、加载和编译。

    DX10 虚拟机

      

       

    语法树

    划分

    1、顶点着色

    发生在图元装配后

    顶点着色器(VS)阶段处理来自输入汇编器的顶点,执行每个顶点的操作,如转换、蒙皮、变形和每个顶点的光照,并编制到输出结构交付给下一个管道。

    (顶点着色器总是操作单个输入顶点并产生单个输出顶点。顶点着色器阶段必须始终处于活动状态,以便管道执行。

    如果不需要顶点修改或转换,则必须创建一个直通顶点着色器并将其设置为管道。)

       

    a\ 输入和输出:

    每个顶点着色器输入顶点可以由16个32位向量组成(每个顶点最多4个分量),每个输出顶点可以由16个32位4分量向量组成。

    所有顶点着色器都必须至少有一个输入和一个输出,可以是一个标量值。

     

    b\ vertexshader阶段可以使用输入汇编程序生成的两个系统值:VertexID和InstanceID(参见系统值和语义)。

    由于VertexID和InstanceID在顶点级别都是有意义的,并且硬件生成的ID只能被输入到理解它们的第一阶段,因此这些ID值只能被输入到vertexshader阶段。

     

    c\ 顶点着色器总是在所有顶点上运行,包括带有邻接的输入基元拓扑中的相邻顶点。

    顶点着色器执行的次数可以使用VSInvocations管道统计从CPU查询。

       

       

    2、可选镶嵌

    描述:

    Direct3D 11运行时支持三个实现镶嵌的新阶段,它将低细节细分曲面转换为GPU上的高细节原语。

    镶嵌瓷砖(或分解)高阶表面成适合渲染的结构。

    通过在硬件中实现镶嵌,图形管道可以评估较低的细节(较低的多边形计数)模型和渲染较高的细节。

    虽然可以进行软件镶嵌,但是由硬件实现的镶嵌可以生成大量的视觉细节(包括对位移映射的支持),而不需要向模型大小添加视觉细节和刷新率。

       

    概括:镶嵌使用GPU计算更详细的表面从一个由四边形斑块,三角形斑块或等值线构成的表面。

       

    HullShader:

    一个可编程的着色器阶段,它产生一个几何贴片(和贴片常量),对应于每个输入贴片(四边形、三角形或直线).

    外壳着色器(每个补加点调用一次)将定义低阶表面的输入控制点转换为构成补加的控制点。

    ID3D11Device::

    CreateHullShader

       

    ID3D11DeviceContext::HSSetShader

      

      

    Tessellator

    一个固定的函数管道阶段,它创建表示几何patch的域的抽样模式,并生成一组较小的对象(三角形、点或线)来连接这些样本

    将一个域(四边形、三边形或直线)细分为许多较小的对象(三角形、点或直线)。将uv(和可选的w)坐标和表面拓扑(归一化的坐标域)输出到域着色器阶段。

    域着色器在每个tessellator阶段点调用一次,并计算表面位置。

      

    Domain

    一个可编程着色器阶段,计算对应于每个域样本的顶点位置

    域着色器计算输出补丁中细分点的顶点位置,其中每个tesselator阶段输出点运行一次,并且对tesselators阶段输出UV坐标、船体着色器输出补丁和船体着色器输出补删常量具有只读访问权限。

    ID3D11Device::

    CreateDomainShader

      

      

     

       

       

    3Geometry Shader

    几何着色器(GS)阶段运行应用程序指定的着色器代码,将顶点作为输入,并能够在输出上生成顶点。

    (不像顶点着色器操作单个顶点,几何着色器的输入是一个完整语义的顶点(两个顶点表示线,三个顶点表示三角形,或者单个顶点表示点)。

    几何体着色器还可以将边缘相邻基元的顶点数据作为输入(对于一条直线,额外的两个顶点,对于三角形,额外的三个顶点)。

    下图显示了一个三角形和一条有相邻顶点的直线。)

       

    a\ 可以使用由IA自动生成的SV_PrimitiveID系统生成的值。

    b\ 能够输出多个顶点,形成单个选定的拓扑(可用的GS阶段输出拓扑有:tristrip、linestrip和pointlist)。

    c\ 输出可以通过流输出阶段反馈到光栅化阶段和/或内存中的顶点缓冲区。提供给内存的输出被扩展到单独的点/线/三角形列表(它们将被传递给光栅化器)。

       

    4Pixel Shader

    像素着色器阶段(PS)支持丰富的着色技术,例如逐像素光照和后期处理。

    像素着色器是一个程序,它结合了常量变量、纹理数据、每个顶点值的插值和其他数据来产生每个像素的输出

    对于一个原语覆盖的每个像素,rasterizer阶段只调用一次像素着色器,但是,可以指定一个空着色器来避免运行一个着色器。

       

    a\ 当对纹理进行多采样时,每个覆盖的像素只调用一次像素着色器,同时对每个覆盖的多采样进行深度/模板测试。通过深度/模版测试的样本将使用像素着色器输出颜色进行更新。(所以适当减少)

       

    b\ 像素着色器固有函数产生或使用屏幕空间x和y的数量导数,导数最常用的用途是计算纹理采样的详细程度计算,在各向异性滤波的情况下,选择沿各向异性轴的样本。

    通常,硬件实现同时在多个像素(例如2x2网格)上运行一个像素着色器,以便在像素着色器中计算的量的导数可以合理地近似为相邻像素中同一执行点上的值的增量。

       

    c\ 输入:

    输入将被限制(超过会截取)在16(无配置Geo着色)or 32、 32位、4个组件。

    关键词:顶点属性,插值,覆盖,抽样,

       

    d\ 输出

    像素着色器最多可以输出8 32位4分量的颜色,如果像素被丢弃,则不输出颜色。像素着色器输出寄存器组件在使用之前必须声明;每个寄存器都允许有一个不同的输出-写入掩码。

    使用depth-write-enable状态(在输出合并阶段)来控制是否将深度数据写入深度缓冲区(或使用丢弃指令丢弃该像素的数据)。

    像素着色器还可以输出可选的32位、1个组件、浮点数、深度值来进行深度测试(使用SV_Depth语义)。

    深度值在深度寄存器中输出,并替换深度测试的插值深度值(假设启用深度测试)。无法在使用固定函数深度和着色器深度之间动态变化。

    像素着色器不能输出模板值。

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    第二部分、Unreal 着色器相关

    DX

    1、编译,读写

    D3DCompileFromFile(_In_ LPCWSTR pFileName,

    _In_reads_opt_(_Inexpressible_(pDefines->Name != NULL)) CONST D3D_SHADER_MACRO* pDefines,

    _In_opt_ ID3DInclude* pInclude,

    _In_ LPCSTR pEntrypoint,

    _In_ LPCSTR pTarget,

    _In_ UINT Flags1,

    _In_ UINT Flags2,

    _Out_ ID3DBlob** ppCode,

    _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorMsgs);

    D3DCompile(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,

    _In_ SIZE_T SrcDataSize,

    _In_opt_ LPCSTR pSourceName,

    _In_reads_opt_(_Inexpressible_(pDefines->Name != NULL)) CONST D3D_SHADER_MACRO* pDefines,

    _In_opt_ ID3DInclude* pInclude,

    _In_opt_ LPCSTR pEntrypoint,

    _In_ LPCSTR pTarget,

    _In_ UINT Flags1,

    _In_ UINT Flags2,

    _Out_ ID3DBlob** ppCode,

    _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorMsgs);

       

    D3DCompressShaders(_In_ UINT uNumShaders,

    _In_reads_(uNumShaders) D3D_SHADER_DATA* pShaderData,

    _In_ UINT uFlags,

    _Out_ ID3DBlob** ppCompressedData)

       

    D3DReadFileToBlob(_In_ LPCWSTR pFileName,_Out_ ID3DBlob** ppContents)

    D3DWriteBlobToFile(_In_ ID3DBlob* pBlob,_In_ LPCWSTR pFileName, _In_ BOOL bOverwrite)

       

    2、创建

    CreateVertexShader(

    _In_reads_(BytecodeLength) const void *pShaderBytecode,

    _In_ SIZE_T BytecodeLength,

    _In_opt_ ID3D11ClassLinkage *pClassLinkage,

    _COM_Outptr_opt_ ID3D11VertexShader **ppVertexShader)

    CreateXXXShader类似

       

    Unreal

    UnrealShader处理包括了:ush的包含,编译得到转储的着色器usf,平台编译器编译,创建和使用(绑定)。

    1、Global Shaders

    全局shader是用于操作固定几何体(如:full screen quad)的shader,并且它不需要与materials产生交互,例如:阴影过滤、后处理。

    这种类型的shader在内存中只有一份实例.

       

    2Materia

    材质由一些控制材质如何渲染的状态和一些控制材质如何与渲染Pass shader交互的材质输入(material inputs)组成。

       

    3、Vertex Factories 和 MeshTypes

    Material必须能够赋给各种类型的Mesh Types, 这个是通过和Vertex Factories 配合完成的。 一个FVertexFactoryType表示唯一的Mesh Type。

    一个FVertexFactory的实例存有每个几何体的数据,以便支持特定的Mesh Type。

       

    引擎内Shader位于:Engine\Shaders\Private(Public)

    (详细分析和说明在下一篇)

    使用部分

       

       

    ShaderCore

    FShader、FGlobalShader、

    FShaderType, FVertexFactory

    FShaderPipeline, FShaderTarget

       

       

       

       

       

    材质的编译

       

    过程说明:

    1、生成材质的Shader代码【只是Shader文件】

    2、构建编译环境,且添加相关文件路径

    3、编译[可以异步],成功就缓存起来

    3.1 创建了一个临时引用计数指针[主要是确保操作一个引用的着色器映射[或查找]将导致这个着色器映射被删除]

    3.2 往ShaderMapsBeingCompiled添加[占个位置]

    3.3 分配唯一编译ID,配置编译环境

    3.4 迭代处理所有顶点工厂的类型,编译这个材质和顶点工厂类型组合的所有网格材质着色器。---------FVertexFactoryType

    3.5 迭代处理所有材质Shader的类型 ------FShaderType

    3.6 迭代处理所有材质Shader管线的类型 ------FShaderPipelineType

    3.7 进入映射编译着色器

       

    类关系:

       

       

    展开全文
  • 目录 一、概述 1.1 数字人类的概要 1.1.1 数字人类的历史和现状 1.1.2 数字人类的制作流程 1.2 Unreal Engine的数字人类 1.2.1 Unreal Engine数字人的历史 1.2.2 《Meet Mi...
  • https://medium.com/@lordned/unreal-engine-4-rendering-part-4-the-deferred-shading-pipeline-389fc0175789 翻译:yarswang 转载请保留   延迟着色基本通道 在第3章,我们完成了对C++方面的研究,并最终准备...
  • BRDF作为比较流行的渲染算法,但凡成熟的引擎的都有此功能,我们自己写引擎也不例外,我在编写引擎时也会参考网上的一些资料,这也是学习的过程,先介绍BRDF,它是双向反射分布函数,说白了它是对于物体表面上光的...
  • 作者:王文斓虚拟现实(VR)能够带给用户前所未有的沉浸体验,但同时由于双目渲染、低延迟、高分辨率、强制垂直同步(vsync)等特性使VR对CPU渲染线程和逻辑线程,以及GPU的计算压力较大[1]。如何能有效分析VR应用的性能...
  • 目录 三、眼球渲染 3.1 眼球的构造及理论 3.1.1 眼球的构造 3.1.2 眼球的渲染理论 3.2 眼球的渲染技术 3.2.1 角膜的半透和光泽反射 3.2.2 瞳孔的次表面散射 3.2.3 瞳孔的缩放 ...
  • https://medium.com/@lordned/unreal-engine-4-rendering-part-2-shaders-and-vertex-data-80317e1ae5f3 翻译:yarswang 转载请保留 ...Unreal使用一些魔法来绑定C++的着色器表现与等价HLSL类,使用顶点工厂(Vertex...
  • UE4 渲染数据传输

    2020-02-17 11:39:47
    Unreal Mesh Drawing 内存中的mesh是如何进行渲染的,主要涉及几个重要的数据结构 UPrimitiveComponent PrimitiveSceneProxy FMeshBatch FMeshDrawCommand 存在于Game Thread内的数据UPrimitiveComponent ...
  • 目录 四、毛发渲染 4.1 毛发的构造及渲染技术 4.1.1 毛发的构造 4.1.2 Marschner毛发渲染模型 4.1.3 毛发的间接光照 4.2 毛发的底层实现 4.3 毛发的材质解析 4.3.1 头发(M_...
  • 翻译:yarswang 转载请保留   如前所述,Unreal将编译给定着色器/材质的多个排列以应对不同的用例。 修改材质时,Unreal将查找该着色器使用的 .ush/.usf 文件并重新加载它们。 然后...
  • 本文由@浅墨_毛星云出品,首发于...在基于物理的渲染中,几何函数(Geometry Function)是保证Microfacet BRDF理论上能量守恒,逻辑上自洽的重要一环。其描述了微平面自阴影的属性,表示具有半矢量法线的微平面(...
  • 本文根据小米互娱 VR 技术专家 房燕良在 MDCC 2016 移动开发者大会上的演讲整理而成,PPT 下载地址:... ...房燕良,从 2001 年开始,自主研发 3 代游戏引擎,发布游戏超过 10 款。代表作品有
  • 读过我前面一些博客的朋友对虚幻4的渲染流程有了一些大致的了解之后,那么我们现在可以开始着手开始修改虚幻4引擎了·。我们有些时候需要实现某些效果,就需要动手自己改引擎了。这是customnode或者是纯material无法...
  • Unreal engine的渲染模块是越来越复杂,最开始只有延迟管线,随后加入了mobile,现在又加了很多实时光线追踪的东西,各种DX12,VK新的RHI也纷纷加入。 虚幻4的4.22版本对渲染模块进行了较大重构,废弃了之前的...
  • 此为教程第三部分,旨在帮助开发人员利用 Unreal Engine* 4 (UE4) 提升游戏性能。本教程对引擎内部和外部使用的一系列工具以及面向编辑器的最佳实践加以概述,还提供了有助于提高帧速率和项目稳定性的脚本。脚本优化...
1 2 3 4 5 ... 20
收藏数 1,472
精华内容 588
关键字:

unreal 函数 渲染