游戏引擎Flax Engine分析(五)渲染

2021SC@SDUSC 


一、简述

         这一篇博客进一步看GPUShader部分,然后再看继承自GPUShaderProgram的几个类 ,也就是GPU着色器的功能。

二、分析 

        GPUShader接口继承自 GPUResource,是带有着色器程序的 GPU 资源,可以在 GPU 上运行,并能够使用纹理、顶点和其他资源执行渲染计算。

GPUShaderProgramsContainer _shaders;
GPUConstantBuffer* _constantBuffers[MAX_CONSTANT_BUFFER_SLOTS];

        GPUShaderProgramsContainer表示具有排列和自定义名称的着色器程序集合。 

        GPUConstantBuffer用于将参数传递给 GPU 上的着色器的常量缓冲区对象。

        接口内预定义的方法:

(1)

virtual bool Create(class MemoryReadStream& stream);

        创建着色器资源并从字节加载其数据。 

        stream是带有已编译着色器数据的流。

        返回值,如果不能创建状态则为真,否则为假

(2)

        Get着色器的几个方法,这里只举其中一个例子:

API_FUNCTION() FORCE_INLINE GPUShaderProgramVS* GetVS(const StringAnsiView& name, int32 permutationIndex = 0) const
    {
        return static_cast<GPUShaderProgramVS*>(GetShader(ShaderStage::Vertex, name, permutationIndex));
    }

        获取顶点着色器。

        name为着色器程序名, permutationIndex着色器排列索引,缺省值为0。

        返回着色器对象。

(3)

FORCE_INLINE bool HasShader(const StringAnsiView& name, int32 permutationIndex = 0) const
    {
        return _shaders.Get(name, permutationIndex) != nullptr;
    }

        确定指定的着色器程序是否在着色器中。_shaders是上述声明的着色器集合。

        name为着色器程序名, permutationIndex着色器排列索引,缺省值为0。

        返回值,着色器有效返回真,否则为假。

        接下来我们再继续深入,看一下着色器集合GPUShaderProgramsContainer:

Dictionary<int32, GPUShaderProgram*> _shaders;

       首先是数据结构, Dictionary是带有映射键值对的无序字典模板。然后是主要方法:

void Add(GPUShaderProgram* shader, int32 permutationIndex);
GPUShaderProgram* Get(const StringAnsiView& name, int32 permutationIndex) const;

        Add向集合中加入新的着色器,Get使用着色器名和索引获取集合中的着色器,查找失败时返回null 。然后是根据给定着色器程序名和排列索引计算哈希值:

static uint32 CalculateHash(const StringAnsiView& name, int32 permutationIndex);

        GPUShader暂时介绍到这里,接下来我们看继承自GPUShaderProgram的几个类 。


        Shader是运行在GPU上的一组指令,这里仅介绍各个着色器的功能,不涉及具体实现。

着色器: 

  1. 着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。
  2. 在最简配置下,至少都得有两个着色器:一个叫顶点着色器(vertex shader),它将作用于每个顶点上;另一个叫片段着色器(fragment shader),它将作用于每一个采样点。我们采用4倍抗锯齿,因此每个像素有四个采样点。
  3. 如果我们打算从一个着色器向另一个着色器发送数据,我们必须在发送方着色器中声明一个输出,在接收方着色器中声明一个类似的输入。当类型和名字都一样的时候,OpenGL就会把两个变量链接到一起,它们之间就能发送数据了(这是在链接程序对象时完成的)。

(1)GPUShaderProgramVS* VS (Vertex Shader)顶点着色器程序

        顶点着色器是一组指令代码,这组指令代码在顶点被渲染时执行。 同一时间内,只能激活一个顶点着色器。当渲染一个顶点时,API会执行你在顶点着色器中所写的指令。依靠这种方法,你可以自己控制每个顶点,包括渲染,确定位置,是否显示在屏幕上。

(2)GPUShaderProgramHS* HS 船体着色器程序(Hull Shader外壳着色器)

         Hull Shader为曲面细分中的一种技术手段, 生成细分输出面片的顶点,更新所有逐顶点或逐面片的属性值; 设置细分层次因数,以控制生成图元的属性值。

(3)GPUShaderProgramDS* DS 域着色器程序(Domain Shader)

       域着色器用于计算细分图元的顶点位置,它对Tessellator的每个输出点运行一次,能够只读访问其输出的uvw标量坐标,同时使用hull shader的两项输出数据。所有的顶点信息都会在这里计算,会涉及到大量运算。 域着色器同样为曲面细分的其中一部分,有关曲面细分着色器的相关知识可参考:https://blog.csdn.net/ifenghua135792468/article/details/106851708/

(4)GPUShaderProgramGS* GS 几何着色器程序(Geometry Shader)

        一般只使用了顶点和片段着色器,这也是基本和必须的两个着色器,而几何着色器是一个可选的着色器,其位于顶点和片段着色器之间。

  几何着色器接收来自顶点着色器的一个片元的一组顶点,然后可以对其进行变换,可以输出新的不同类型的片元,也可以增加顶点数,其功能非常强大。

(5)GPUShaderProgramPS* PS 像素着色器程序 (Pixel Shader,也叫Texture Shader纹理着色器,Fragment Shader片元着色器)

        片元着色器的作用是处理由光栅化阶段生成的每个片元,最终计算出每个像素的最终颜色。归根结底,实际上就是数据的集合。这个数据集合包含每一个像素的各个颜色分量和像素透明度的值。

        到这里,管道状态初始化过程中涉及到的部分基本分析完毕,接下来我们将继续回到2D渲染后面的部分。 


         2D渲染服务:

class Render2DService : public EngineService

        首先看EngineService,引擎服务对象。首先看其主要方法;

static EngineServicesArray& GetServices();

        获取所有已注册服务的列表,管理的对象是所有引擎提供的服务。返回对象如下:

typedef Array<EngineService*, FixedAllocation<128>> EngineServicesArray;

        EngineService此外还有相关排序 ,这里不再赘述。

        我们回到Render2DService,构造器继承自其父类EngineService,初始化服务名称。进行初始化工作以及关闭工作,主要是异步加载GUI着色器。


        这篇博客暂时到这,后续将继续分析 2D渲染服务的其他部分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值