2021SC@SDUSC
一、简述
这篇博客我们继续分析Render2D部分,通过分析源代码的方式学习一些基础知识和编程经验。
二、分析
FORCE_INLINE Render2DVertex MakeVertex(const Vector2& point, const Vector2& uv, const Color& color, const RotatedRectangle& mask, const Vector2& customData)
{
return
{
point,
Half2(uv),
color,
customData,
mask,
};
}
上面这个函数主要作用就是初始化一个Render2DVertex结构体,我们来看一下这个结构体的具体内容:
struct Render2DVertex
{
Vector2 Position;
Half2 TexCoord;
Color Color;
Vector2 CustomData;
RotatedRectangle ClipMask;
};
几个属性:位置(二维向量),然后是一个Half2类型的纹理坐标,也就是一个二维向量,然后是颜色,自定义数据,剪切蒙版
这里我们看一下纹理坐标:
在材质节点中,TextureCoordinate缩写为TexCoord。
TextureCoordinate直译过来是纹理坐标。既然是纹理的坐标,那么它作为一个二维向量也就很容易理解了。
默认情况下,TextureCoordinate二维向量的每一个分量,取值范围都是0~1。
坐标(0,0)对应纹理的左上角,坐标(1,1)对应纹理的右下角。
当渲染物体表面时,像素在物体上的坐标,同样按照纹理坐标的计算方式。
比如一个平板,处于中心的点的坐标为(0.5,0.5),当渲染这个像素时,则取对应纹理的(0.5,0.5)坐标处的像素,直接贴过去。
这样就把纹理对应到物体表面了。
下面我们看一下初始化GPU管道状态这个函数:
bool CachedPSO::Init(GPUShader* shader, bool useDepth)
这里不再粘贴具体代码,主要设计到CachedPSO这个结构体,和GPUPipelineState::Description这个结构体,我们先看CachedPSO:
struct CachedPSO
{
bool Inited = false;
bool UseDepth;
GPUPipelineState* PS_Image;
GPUPipelineState* PS_ImagePoint;
GPUPipelineState* PS_Color;
GPUPipelineState* PS_Color_NoAlpha;
GPUPipelineState* PS_Font;
GPUPipelineState* PS_BlurH;
GPUPipelineState* PS_BlurV;
GPUPipelineState* PS_Downscale;
GPUPipelineState* PS_LineAA;
bool Init(GPUShader* shader, bool useDepth);
void Dispose();
};
类GPUPipelineState使用单个对象描述完整图形管道状态,继承自类GPUResource,这个类是所有 GPU 资源的基类。
然后是结构体GPUPipelineState::Description,管道状态描述
API_STRUCT() struct Description
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Description);
API_FIELD() bool DepthWriteEnable;
API_FIELD() bool DepthTestEnable;
API_FIELD() bool DepthClipEnable;
API_FIELD() ComparisonFunc DepthFunc;
API_FIELD() GPUShaderProgramVS* VS;
API_FIELD() GPUShaderProgramHS* HS;
API_FIELD() GPUShaderProgramDS* DS;
API_FIELD() GPUShaderProgramGS* GS;
API_FIELD() GPUShaderProgramPS* PS;
API_FIELD() PrimitiveTopologyType PrimitiveTopologyType;
API_FIELD() bool Wireframe;
API_FIELD() CullMode CullMode;
API_FIELD() BlendingMode BlendMode;
public:
API_FIELD(ReadOnly) static Description Default;
API_FIELD(ReadOnly) static Description DefaultNoDepth;
API_FIELD(ReadOnly) static Description DefaultFullscreenTriangle;
};
bool DepthWriteEnable 启用/禁用深度写入
bool DepthTestEnable 测试启用
bool DepthClipEnable 深度剪辑启用
ComparisonFunc DepthFunc 深度函数(将深度数据与现有深度数据进行比较的函数)
GPUShaderProgramVS* VS 顶点着色器程序
GPUShaderProgramHS* HS 船体着色器程序
GPUShaderProgramDS* DS 域着色器程序
GPUShaderProgramGS* GS 几何着色器程序
GPUShaderProgramPS* PS 像素着色器程序
PrimitiveTopologyType PrimitiveTopologyType 输入原语拓扑
bool Wireframe 如果使用线框渲染则为真,否则为假
CullMode CullMode 原语剔除模式
BlendingMode BlendMode 颜色混合模式
Description Default 默认描述
Description DefaultNoDepth 完全不使用深度缓冲区的默认描述
Description DefaultFullscreenTriangle 全屏三角形渲染的默认描述。
(1)深度函数DepthFunc属于枚举类ComparisonFunc,枚举了比较函数的模式:
API_ENUM() enum class ComparisonFunc : byte
{
Never = 1,
Less = 2,
Equal = 3,
LessEqual = 4,
Greater = 5,
NotEqual = 6,
GreaterEqual = 7,
Always = 8,
API_ENUM(Attributes="HideInEditor") MAX
};
Never:绝不通过比较
Less:如果源数据小于目标数据,则比较通过。
Equal:如果源数据等于目标数据,则比较通过。
LessEqual 如果源数据小于或等于目标数据,则比较通过。
Greater 如果源数据大于目标数据,则比较通过。
NotEqual 如果源数据不等于目标数据,则比较通过。
GreaterEqual 如果源数据大于或等于目标数据,则比较通过。
Always 总是通过比较。
(2)GPUShaderProgramVS,GPUShaderProgramHS,GPUShaderProgramDS,GPUShaderProgramGS,GPUShaderProgramPS都继承自接口GPUShaderProgram,是可以在GPU上运行的小程序。接口内声明的属性如下:
StringAnsi Name;
ShaderBindings Bindings;
ShaderFlags Flags;
GPUShader* Owner;
StringAnsi在Flax中这样定义:将文本表示为 ANSI 字符序列。 容器使用单个动态内存分配来存储字符数据。 字符序列始终以空字符结尾。
ShaderBindings着色器程序元数据容器。 包含有关着色器使用的资源的描述。
ShaderFlags描述用于着色器编译的着色器函数标志。有四种标志:a.默认设置;b.隐藏着色器, 它将存在于源代码中并将被解析但不会为渲染而编译;c.禁用着色器编译器执行的任何快速数学优化;d.指示顶点着色器函数输出几何着色器的数据。
GPUShader带有着色器程序的 GPU 资源,可以在 GPU 上运行,并能够使用纹理、顶点和其他资源执行渲染计算。
GPUShaderProgram实现了返回除Owner之外三个属性的get函数,此外,三个虚函数:
virtual ShaderStage GetStage() const = 0;
virtual void* GetBufferHandle() const = 0;
virtual uint32 GetBufferSize() const = 0;
GetStage()获取着色器程序阶段类型。
GetBufferHandle()获取缓冲区句柄(取决于平台)。
GetBufferSize()获取缓冲区大小(以字节为单位)。
这篇博客暂时分析到这里,下一篇博客进一步看GPUShader部分,然后再看继承自GPUShaderProgram的几个类 。