MY BLOG DIRECTORY:
YivanLee:专题概述及目录INTRODUCTION:
虚幻引擎由于它的高度封装性,导致我们无法随心所欲控制模型的绘制,不像unity直接定义两个pass就能控制模型画两遍。作为TA无法随心所欲控制引擎的绘制肯定是不行的,所以这节将在4.22的新渲染架构MeshDrawPipeLine上对引擎进行改造。
对MeshDrawPipeLine不熟悉的话可以去看我前面的文章。MeshDrawPipline
先上效果吧:
我在PrePass之后添加了我自己的MeshDrawPass渲染我自定义的MobileVolumeLightZ。下面就来实现它。
首先我们要做的核心事情如下:
【1】构造我们需要的MeshDrawCommand
【2】调用我们的MeshDrawCommand进行绘制
MAIN CONTENT:
【构造MeshDrawCommand】
自定义MeshDrawPass第一步是为我们的MeshDrawPass添加一个通道,在MeshDrawProcessor.h中添加我们自己的MeshDrawPass
然后再到GetMeshPassName中加对应代码:
MeshDrawCommand是一个渲染命令,包含了一次DrawCall所需要的所有资源,VertexBuffer,IndexBuffer,Shaders等等。首先找到
FMeshPassProcessor::BuildMeshDrawCommands
这个函数是所有Pass的MeshDrawCommands的生成函数。我们只需要把生成它所需要的资源填进来就可以了,它自己就会帮我们把生成好的Command填到View.ParallelMeshDrawCommandPasses里,我们到时候直接在Render函数里调它们就可以了。从参数可以看到,需要生成一个Command需要Batchmesh数据,各种渲染状态,PassFeature等等,这些信息包含了一次DrawCall所需要的所有资源。这些资源分散在各个地方,我们需要把它们搜集起来一起打包仍给这个生成函数。这个收集工作就需要找一个对象来负责,它就是FMeshPassProcessor
所以第一步我们先在引擎的如下目录下建两个文件分别是
MobileVolumeLightPassRendering.h
MobileVolumeLightPassRendering.cpp
然后声明一个我们的FMeshPassProcessor类
#pragma once
#include "MeshPassProcessor.h"
class FPrimitiveSceneProxy;
class FScene;
class FStaticMeshBatch;
class FViewInfo;
class FMobileVolumeLightPassProcessor : public FMeshPassProcessor
{
public:
FMobileVolumeLightPassProcessor(
const FScene* Scene,
const FSceneView* InViewIfDynamicMeshCommand,
const FMeshPassProcessorRenderState& InPassDrawRenderState,
const bool InbRespectUseAsOccluderFlag,
const bool InbEarlyZPassMoveabe,
FMeshPassDrawListContext* InDrawListContext
);
virtual void AddMeshBatch(
const FMeshBatch& RESTRICT MeshBatch,
uint64 BatchElementMask,
const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy,
int32 StaticMeshId /* = -1 */
)override final;
private:
void Process(
const FMeshBatch& MeshBatch,
uint64 BatchElementMask,
uint32 StaticMeshID,
const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy,
const FMaterialRenderProxy& RESTRICT MaterialRenderProxy,
const FMaterial& RESTRICT MaterialResource,
ERasterizerFillMode MeshFillMode,
ERasterizerCullMode MeshCullMode
);
FMeshPassProcessorRenderState PassDrawRenderState;
const bool bRespectUseAsOccluderFlag;
const bool bEarlyZPassMoveable;
};
这里有个核心函数AddMeshBatch,这个函数必须重载,因为这个函数将会从引擎底层拿到BatchMesh,Material等资源。Process函数负责把拿到的资源塞给BuildMeshDrawCommands来生成MeshDrawCommand。先暂时不管FMobileVolumeLightPassProcessor的函数实现。FMobileVolumeLightPassProcessor是负责资源递送的,模型数据(VB和IB)和视口UniformBuffer数据等引擎都为我们准备好了,但是Shader数据得我们自己准备,毕竟我们想要自定义渲染效果。下面新建一个usf文件
#include "Common.ush"
#include "/Engine/Generated/Material.ush"
#include &#