文章目录
抗锯齿
为什么会有锯齿?
- 在渲染图形时,当渲染管线将图元的各顶点转化为片段时,由于顶点到片段的映射方式简短粗暴,使图元的边缘看起来格外辣眼,我们把这种现象叫做锯齿或者走样
怎么抗锯齿?
- 从产生锯齿的原因可知,如果从顶点到片段的映射方式高级一些,对图元边缘处的片段颜色弱化一些,让边缘看起来圆润一些,就实现了抗锯齿或者说是反走样
- 常用的“高级一些”的映射方式是多重采样
多重采样(Multisample Anti-aliasing, MSAA)
- 上面说的”简单粗暴“的映射方式是指:每个片段用中心点的位置来判断这个片段是否被图元所覆盖,这个中心点美其名曰采样点
- 多重采样,顾名思义就是用多个采样点来计算一个片段被图元覆盖的程度,然后再根据覆盖程度将片段的颜色弱化,最终使图形的边缘看起来更圆润,从而达到抗锯齿的效果
- 需要注意的是:每个像素只运行一次片段着色器
- 原理是:片段着色器中使用的顶点数据会插值到像素的中心,所得到的结果颜色会存储在每个被覆盖到的子采样点中,没有被覆盖到的子采样点存储无色,最终将所有子采样点中的颜色加权平均得到这个像素的颜色
- 当然多重采样不仅可以应用到颜色上,还可以应用到深度和模板上
实现多重采样
- 实现多重采样有两种方式,一种是使用OpenGL中自带的多重采样缓冲,另一种是通过离屏渲染实现多重采样
OpenGL中的多重采样
- 首先要创建多重采样缓冲
- 能在每个像素中存储大于1个颜色值的颜色缓冲叫做多重采样缓冲
- 一般的窗口系统都提供了创建多重采样缓冲的功能
- 开启多重采样——glEnable(GL_MULTISAMPLE)
- 在大多数OpenGL的驱动上,多重采样都是默认开启的
离屏渲染实现多重采样
创建多重采样缓冲
- 用纹理附件的方式创建
- 使用glTexImage2DMultisample来创建纹理,他的纹理目标是GL_TEXTURE_2D_MULTISAMPLE,其中还需要设置纹理所拥有的样本个数,如果最后一个参数设置为GL_TRUE表示图像将会对每个纹素使用相同的样本位置以及相同数量的子采样点个数
- 使用glFramebufferTexture2D将多重采样纹理附加到帧缓冲上,这个的纹理类型要用GL_TEXTURE_2D_MULTISAMPLE
- 用渲染缓冲对象的方式创建
- 使用glRenderbufferStorageMultisample指定渲染缓冲对象的内存,其中也要设置样本的数量
使用多重采样缓冲
-
接下来使用多重采样缓冲也分两种方式,一种是使用OpenGL定义的接口自动还原多重采样的结果,另一种是自定义多重采样的还原结果
-
还原多重采样的结果
-
多重采样缓冲有一个特别的地方,我们不能直接将他的图像用在着色器中进行采样
-
一个多重采样的图像包含比普通图像更多的信息,我们需要将他缩小或者还原
-
使用glBlitFramebuffer来还原多重采样缓冲中的图像,他能将一个源帧缓冲中的某个区域复制到另一个目标帧缓冲中,并且将图像还原
-
可以使用GL_READ_FRAMEBUFFER绑定源帧缓冲,GL_DRAW_FRAMEBUFFER绑定目标帧缓冲
-
不还原多重采样的结果
-
如果一个多重采样的图像不进行还原直接传入着色器,那么我们必须对图像的每个子样本进行采样,这时我们可以创建我们自己的抗锯齿算法
-
纹理的采样器类型要设置为sampler2DMS
-
使用texelFetch(…)获取每个子样本的颜色值