UE4 Shader&绘制过程笔记

先声明这是一篇记录自己学习的笔记,原文链接:
虚幻4渲染编程(Shader篇)【第十卷:绘制策略】 - 知乎 (zhihu.com)

正如作者所说,部分内容有一点过时,但我觉得对于把握UE的shader一些基本原理,数据传输,存取等还是很有帮助的,所以我们不要把版本放在心上,大胆的了解学习UE中对渲染的处理逻辑。

现在正式开始:

Shader的生成:
1. Shader一定是在使用之前就编译好的(未来不知道会怎样),从某种角度上说shader可以认为是预编译好的资源,不同的程序不同的环境平台我们需要不同的Shader,也就是说我们一个效果会有很多个shader,要用的时候需要根据不同条件(Level&Macros)去取对应的出来;

2. Shader C++类和Shader一定要区分开。Shader C++类是在CPU端管理控制shader的,shader是在GPU上跑的;

3. Shader的定义,编译,使用是三个分开的过程,不能混在一起看作是一套连贯的线性过程。

UE4的shader C++类型:

Material Shader:允许多份实例,给单个模型用

Mesh Material Shader:允许多份实例,给单个模型用

例如:材质编辑器负责填充一个叫Material Template的模板,Compile的时候,材质编辑器可视化节点便会填充这个MaterialTemplate.usf生成一个函数库HLSL Code。这还没完,compile操作会根据材质编辑器里的各种宏,各种绘制状态,游戏的高中低配分级等条件,编译出很多份Shader,放在FMaterial的ShaderMap中。有一个宏,材质编辑器就会编译出两份shader,有两个宏,就会编译出4个,呈指数型上涨。

这些宏由:Common.usf传递

绘制需要对Shader做两件事:将Shader编译&将ShaderCode放到ShaderMap中(有很多种类,可理解为一个容器)

Global Shader:只允许存在一份,给全局场景用(Scene Render)

使用IMPLEMENT_MATERIAL_SHADER_TYPE等宏实现C++ shader与shader的绑定,其实里边调用的还是IMPLEMENT_SHADER_TYPE

这个宏会把shader文件路径(可能是虚拟路径),类型等于C++的Shader类型进行绑定,结果存到ShaderMap:

IMPLEMENT_SHADER_TYPE(, FLensDistortionUVGenerationVS/*Shader C++类名,决定类型*/, TEXT("/Plugin/LensDistortion/Private/UVGeneration.usf"), TEXT("MainVS"), SF_Vertex)

有了这种绑定就能够通过shader C++类找到ShaderMap获得对应的shadercode

在书写shader C++类的时候可能还使用SetDefault为shader压入过一些宏,这样子就可能使用这种宏来控制渲染的线路,这个宏在shader编译的时候是通过MaterialEnvironment传递的

DrawingPolicy数据管理:这个过程已经被MeshDrawPipeline取代了

虽然被取代了但是还是可以了解一下,新的Pipeline更加简洁

1.StaticMesh(绘制状态不发生改变,而非静止):DrawList

将模型资源放入场景=》RenderScene:: AddPrimitive函数=》Scene->AddPrimitiveSceneInfo_RenderThread=》FPrimitiveSceneInfo::AddToScene函数=》PrimitiveSceneInfo::AddStaticMeshes函数=》FStaticMesh::AddToDrawLists函数=》根据情况把FStaticMesh加入到各个DrawingPolicyFactory(组织数据)=》各个DrawingPolicyFactory::AddStaticMesh函数=》FScene::DrawList=》在StaticMeshDrawList中完成添加和link

静态模型Draw的时候就直接调用DrawList进行绘制,在DrawList里的DrawingPolicy就已经初始化好了。

StaticDrawList里面储存了DrawingPolicy:

a).DrawingPolicy可以用来在ShaderMap中查找到对应的shader,于是我们绘制时需要使用的shader有了;

b).模型资源放入场景=》DrawingPolicyFactory创建一个batchmesh=》DrawingPolicyFactory创建数个DrawingPolicy分享这个batchmesh=》sort这些DrawingPolicy,绘制时直接取出(SortBasePassStaticData)

2.DynamicMesh

创建DrawingPolicy=》初始化(从MaterialShaderMap拿出Sahder)=》Draw=》RHIComList调用底层

使用shader实际就是将shader取出参与绘制,这个过程没有与shader对象完全写死,而是分离开,方便shader与不同的绘制场景进行组合,重利用,极大地提高了自由度,这部分对shader的使用进行组织和利用的代码就称为DrawingPolicy(负责DrawCall)和DrawingPolicyFactory(组织数据)——参考GlobalShader

UE4整个绘制过程:

Editor阶段:准备渲染资源,模型贴图动画的导入,场景的搭建(场景的搭建过程其实是DrawList的构建过程,各种LightMap,SH的烘焙过程等等)

Runtime阶段:SceneRender类=》CreateSceneRenderer=》Render=》SceneContex(GBuffer)=》InitView(抽取各种渲染数据:GetDynamicData等)=》各种Pass(如BassPass:写Gbuffer——区分静态与动态模型,分配渲染顺序,调用DrawList,DrawingPolicy)

你可能感兴趣的:(UE4随笔,ue4,图形渲染,游戏引擎)