这是我在《游戏架构-核心技术与面试精粹》看的,记录一下~
啥玩意是渲染?
游戏图像的绘制被称为渲染
啥玩意是渲染管线?
表示绘制到游戏视图的过程中,一个模型文件的数据经过了哪些转换步骤
通常指的是GPU流水线,不包含CPU部分
CPU主要是准备好顶点、贴图、法线、灯光方向、颜色等东西之后,告诉GPU
GPU接收到数据后,就要对其处理最终显示到屏幕上
因为屏幕是2D画面,模型是3D资源,必然有一部操作,就是将3D转化为2D。
这个操作之前被称为顶点阶段(几何阶段),主要是处理3D模型数据
之后被称为片元阶段(光栅化阶段),处理2D像素数据
1.顶点着色器(Vertex Shader)
如下所示:
#pragma vertex vert
struct v2f
{
float4 pos : SV_POSITION;
fixed4 color : COLOR;
};
v2f vert (appdata_base v)
{
//vertex operation
}
每个顶点都会调用一次这个函数,并转化为这个函数的输出,这些输出被称为图元(Primitive)
一般可以在这里改变顶点或者法线相关信息
2.曲面细分(Tessellation Shader)
是OpenGL 4.0新加入的特性,很多设备还不支持
主要的作用是可以优化曲面,eg:使曲面更平滑
3.几何着色器(Gemoetry Shader)
几何着色器的输入输出都是图元(Primitive),不是顶点
可以将简单的图元扩展成更为复杂的形式
4.变化回执(Transform Feedback)
是在OpenGL 3.0之后加入的特性
可以将图元存放到 Transform Feedback Buffer中,并可以决定是否按照先前的流程光栅化
主要特性:在下一帧渲染时,可以得到上一帧图元的数据,对于定量变化的情况,可以节省掉流水线之前的步骤
(常被用于粒子系统 or 角色的头发)
5.裁剪(Clipping)
图元会根据视域的平截头体(Frustums)做可见性判断
区域外的定点会被舍弃,与这个定点连线的三角形的边会与平截体求交点,这些交点就变成裁剪后的新顶点
6.屏幕映射(Screen Transform)
图元的坐标从齐次裁剪空间变换到屏幕空间
7.图元装配(Primitive Assembly)
顶点会被转化成基础图元,供后续步骤使用
三角形的朝向剔除(Face Culling)是在这个阶段完成的
8.光栅化(Rasterization)
三角形会经历两个步骤:
1.三角形会被转化成片段
2.会遍历三角形,获取顶点属性进行插值,在每个像素点上产生一个插值
如果开启了多重采样抗锯齿(Multisample Antialiasing,MSAA),此处就会对每个像素进行多次采样,产生多个偏远,最后在混合,以达到抗锯齿的效果
9.提前深度测试(Early Depth Test)
检查片元的深度,如果不需要显示则丢弃它
可以在片元着色器运行之前去掉不合理的值,减少运算的消耗
但是与后续的透明测试有冲突,如果在后续的透明度测试中失败,这步深度测试也不应该将其通过
有些GPU会判断是否有此类冲突,如果有就跳过(有一定消耗)
10.片元着色器(Fragment Shader)
可以自定义光照计算、读取贴图颜色、设置透明度等
输入是光栅化后得到的片元数据,输出值也为片元数据
Unity中会把函数返回值写为运算后的颜色
fixed4 frag (v2f i) : SV_TARGET
{
//do framgent operation
}
11.逐片元操作(Pre-Sample Operation)
这个阶段:主要是先测试后混合
测试共经历了4个测试:
他们的作用都是确定一个像素是否应该显示
1.裁切测试(Scissor Test)
通过区域判断的,与基于顶点的 Clipping 阶段不同
2.透明测试(Alpha Test)
透明度达不到,就不绘制
AlphaTest Greater 0.5
3.模板测试(Stencil Test)
通过缓冲区来进行像素比较,与ColorBuffer或DepthBUffer,StencilBuffer是一个8位图像,每个像素保存一个无符号整型
Stencil
{
Ref 2
Comp equal
Pass Keep
ZFail decrWrap
}
//也就是,通过按位与的操作比较两侧结果
if((RefValue & readMask) comparisonFunction (StencilBUfferValue * readMask))
{
pass;
}
else
{
discard;
}
4.深度测试(Depth Test)
通过深度缓冲区的比较,判断是否应该绘制像素
需要先制定深度写入规则,然后再指定比较规则
分别对应Unity的 ZWrtie 和 ZTest
(深度写入不透明物体默认打开,透明物体默认关闭,测试方法默认是小于等于)
混合阶段主要有2个阶段:
1.混合(Blending)
通过测试的颜色与ColorBuffer中颜色的叠加方式
混合有多种叠加方式,一般会使用RGBA的值作为计算因子,采用插值的方式进行线性计算
Blend SrcAlpha OneMinusSrcAlpha
2.写入遮罩(Write Mask)
主要是颜色遮罩(Color Mask),在最终绘制时,对颜色进行过滤
ColorMask RG
so,
经过上面所有的步骤后,最终这个像素会被绘制到颜色缓冲区,并被显示到屏幕上