前言

最近在写游戏引擎,在这里将主要记录一下如何架构跨平台的 Rendering Pipeline

在大部分人眼中,这就是 Rendering Pipeline,但是其实这只能说是 Shader Pipeline,真正的渲染管线远比这更加复杂。

光栅化的渲染管线

固定的渲染管线

这是早期架构的渲染管线,因为引擎的交互还不完善,所以暂时不需要考虑动态的情况。

Rendering/
    RenderingInterface.hpp

    Platform/
        Windows/
            WindowsRenderingPipeline.hpp
            WindowsRenderingPipelineState.hpp
            DirectXInterface.hpp

        Android/
            AndroidRenderingPipeline.hpp
            AndroidRenderingPipelineState.hpp
            OpenGLInterface.hpp

GameObject/
    GOManage.hpp

    Mesh/
        StaticMesh.hpp

Rendering

对于引擎来说,渲染模块将只暴露出以下几个接口。

1
2
3
4
5
6
7
8
9
PreInit();
Init();
PostInit();

Tick();

InitExit();
Exit();
PostExit();

WindowsRenderingPipeline.hpp

继承 RenderingInterface 同时调用 DirectXInterface 中提供的 API

Init

主要是根据 Windows 传入的命令对 DirectX 进行初始化。

具体有创建驱动器和工厂(保证创建出驱动器),再用驱动去创建围栏(同步 CPUGPU),命令队列,堆(存储视图,视图记录了数据在相应缓冲中的偏移地址和长度,是一种数据标识符)以及交换链。

之后再调用 WindowsRenderingPipelineState 创建管线状态对象(PSO)。

Tick

Tick 其实没什么要讲的,就跟画画一样,清除、绘制和等待。

就是绘制之前要更新数据,关于 GPUCPU 在读写数据时怎么保证安全就是另外的问题了。

Exit

WindowsRenderingPipelineState.hpp

  1. 创建根签名,绑定常量缓冲区描述表的起始地址到寄存器中。

  2. 构建 Shader

  3. 提交模型数据至 buffer 中需要遍历 GOManage.hpp 中储存 GameObject 的数组获得顶点数据和索引,用 OpenGL 的话说就是 VAOVBOIBO

  4. 构建常量描述堆(存放常量缓冲区视图)。

  5. 构建常量缓冲区,目前来说,所有的 GameObject 共用一个常量缓冲区,通过为每一个 GameObject 创建一个常量缓冲区视图来分割常量缓冲区,相机的视角投影矩阵单独存放在一个常量缓冲区中。

  6. 最后是一些设置,包括配置光栅化状态,混合模式等等。

动态的渲染管线

动态的渲染管线估计会参考这篇文章他们的引擎

光线追踪的渲染管线

Mesh Pipeline