屏幕像素网格的每个像素的中心都有一个采样点。 当采样点被三角形片段包含时,它将被填充颜色,而三角形之外的像素不受影响抗锯齿,即使该像素部分位于三角形内部。 里面。
光栅化三角形具有锯齿状边缘
为了平滑边缘,我们使用多重采样技术。
1. 多重采样(MSAA)
多重采样的原理是不是使用像素中心的单个采样点,而是以特定的模式排列 4 个采样点。 当片段着色器运行时,颜色将基于屏蔽子样本存储在子样本中。 数量,最终像素颜色由像素内所有子样本的平均值决定。 采样点的数量是任意的,但是采样点越多意味着性能消耗越大。
MSAA基本上只是对图片中物体的边缘进行放大和混合抗锯齿操作,因为边缘是锯齿最明显的地方(注意不是所有边缘)。 提取边缘主要结合深度技术。 MSAA是一种硬件AA。 (摘自方克满先生的回答)
2.MSAA在
当开启MSAA时,必须使用一个可以在每个像素中存储多于1个颜色值的颜色缓冲区:多重采样缓冲区(因为多重采样需要我们为每个样本点存储一个颜色)。
设置 MSAA:
glfwWindowHint(GLFW_SAMPLES, 4);
打开 MSAA(默认打开):
glEnable(GL_MULTISAMPLE);
//glDisable(GL_MULTISAMPLE)//关闭
开启后即可实现MSAA:
MSAA 关闭(左)和 MSAA 开启(右)的比较
可以看到,开启MSAA后,锯齿现象得到了一定程度的缓解。
2. 屏外MSAA
提供离屏渲染的方法,但需要手动生成多采样缓冲区。 有两种方法可以生成多重采样缓冲区。 纹理附件和渲染缓冲区附件。
1.纹理配件
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB, width, height, GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
它的第二个参数设置纹理具有的样本数。 如果最后一个参数为 ,则图像将为每个纹素使用相同的采样位置和相同数量的子采样点。
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
2. 渲染缓冲区附件
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
多重采样帧缓冲区恢复通常是通过将一个帧缓冲区中的区域复制到另一个帧缓冲区并恢复多重采样缓冲区来完成的。
将图像 Blit 到默认帧缓冲区并将多重采样帧缓冲区发送到屏幕;
glBindFramebuffer(GL_READ_FRAMEBUFFER, multisampledFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3. 自定义抗锯齿算法
要将多重采样的纹理图像直接传递给着色器而不进行恢复以获得每个子样本的颜色值,需要将纹理采样器设置为:
uniform sampler2DMS screenTextureMS;
使用该函数获取每个子样本的颜色值:
vec4 colorSample = texelFetch(screenTextureMS, TexCoords, 3); // 第4个子样本
有关抗锯齿的更多信息,请参考作者的:
未经允许不得转载! 作者:admin,转载或复制请以超链接形式并注明出处天心神途传奇手游发布网。
原文地址:《【11】高级OpenGL_抗锯齿》发布于:2024-03-29
还没有评论,来说两句吧...