美文网首页
23.opengl高级-抗锯齿

23.opengl高级-抗锯齿

作者: 天叔 | 来源:发表于2020-07-14 00:48 被阅读0次

这两天有点疲惫,这一章节的代码没有run起来看效果,重点理解锯齿现象和抗锯齿的实现

一、锯齿生成原理

锯齿原理-参考知乎fengliancanxue

参考上图,几何图形是连续的坐标连接实现的,实际屏幕上的像素是离散化的点,分辨率越低的屏幕离散越剧烈,在图形的边缘必然会产生锯齿。

抗锯齿有两种常见的方案:1)超采样抗锯齿(Super Sample Anti-aliasing, SSAA);2)多重采样抗锯齿(Multisample Anti-aliasing, MSAA),MSAA借鉴了SSAA背后的理论。

SSAA背后的理论说明,比如400 x 400的图片,采样成100 x 100,那就是缩放成原图的1/4,那么就可以用平均值的方式从相邻的4个像素采样生成100 x100中的一个新像素。SSAA用高分辨率图来降低锯齿效果较好,但是牺牲了内存性能。

MSAA的方式是在内存中将一个采样点拓展成4个子采样点,4个子采样点不一定都在三角形中,计算包含在三角形内的子采样点的比例,再乘以原采样颜色,即得到该边缘点应该渲染的颜色。再简单点,包含在三角形中的子采样点越少,该像素的实际像素越淡

4个子采样点 边缘像素的处理

暂时先理解这么多,到用时再回头来深入研究

二、Opengl中的MSAA

2.1 默认窗口的话,2行代码实现
glfwWindowHint(GLFW_SAMPLES, 4);
glEnable(GL_MULTISAMPLE);
无抗锯齿 锯齿放大 抗锯齿
2.2 离屏MSAA

使用glTexImage2DMultisample来替代glTexImage2D,它的纹理目标是GL_TEXTURE_2D_MULTISAPLE。

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_TEXTURE_2D_MULTISAMPLE。

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);

和纹理类似,创建一个多重采样渲染缓冲对象并不难。我们所要做的只是在指定(当前绑定的)渲染缓冲的内存存储时,将glRenderbufferStorage的调用改为glRenderbufferStorageMultisample就可以了。

glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);

因为多重采样缓冲有一点特别,我们不能直接将它们的缓冲图像用于其他运算,比如在着色器中对它们进行采样。

一个多重采样的图像包含比普通图像更多的信息,我们所要做的是缩小或者还原(Resolve)图像。多重采样帧缓冲的还原通常是通过glBlitFramebuffer来完成,它能够将一个帧缓冲中的某个区域复制到另一个帧缓冲中,并且将多重采样缓冲还原。

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);

你可以看到,如果将多重采样与离屏渲染结合起来,我们需要自己负责一些额外的细节。但所有的这些细节都是值得额外的努力的,因为多重采样能够显著提升场景的视觉质量。当然,要注意,如果使用的采样点非常多,启用多重采样会显著降低程序的性能。在本节写作时,通常采用的是4采样点的MSAA。

三、自定义抗锯齿算法

将一个多重采样的纹理图像不进行还原直接传入着色器也是可行的。GLSL提供了这样的选项,让我们能够对纹理图像的每个子样本进行采样,所以我们可以创建我们自己的抗锯齿算法。在大型的图形应用中通常都会这么做。

要想获取每个子样本的颜色值,你需要将纹理uniform采样器设置为sampler2DMS,而不是平常使用的sampler2D:

uniform sampler2DMS screenTextureMS;

使用texelFetch函数就能够获取每个子样本的颜色值了:

vec4 colorSample = texelFetch(screenTextureMS, TexCoords, 3);  // 第4个子样本

可以自己设计权重,计算输出颜色值
我们不会深入探究自定义抗锯齿技术的细节,这里仅仅是给你一点启发。

相关文章

  • 23.opengl高级-抗锯齿

    这两天有点疲惫,这一章节的代码没有run起来看效果,重点理解锯齿现象和抗锯齿的实现 一、锯齿生成原理 参考上图,几...

  • OpenGL学习笔记四

    抗锯齿 抗锯齿混合的2大功能:颜色组合、抗锯齿 多重采样 多重采样,抗锯齿混合综合使用 OpenGL 数学库; M...

  • 2020-02-22 Paint图片绘制抗锯齿设置

    1.普通抗锯齿 2.图片抗锯齿

  • Anti-aliasing

    中文译作抗锯齿,当然抗锯齿不止可以用后处理来实现,一般显卡里也自带了硬件抗锯齿。抗锯齿是用于防止锯齿的一系列算法,...

  • unity 模型显示锯齿问题

    没有开抗锯齿的时候 开了抗锯齿的时候 抗锯齿选项 这里Allow MSAA选项忘了,尴尬了,这里记录下在ios和a...

  • 从0开始的OpenGL学习(二十七)-抗锯齿

    本文主要解决两个问题: 1、什么是抗锯齿?2、如何在OpenGL中使用抗锯齿? 引言 抗锯齿,英文名是anti-a...

  • OpenGL四-基础变化

    一、抗锯齿 混合的2大功能:颜⾊组合、抗锯⻮ 混合处理-抗锯齿 使⽤混合实现抗锯⻮效果Demo:10-抗锯齿 二、...

  • OpenGL ES 3.0 快速近似抗锯齿(Fast Appro

    OpenGL ES 3.0抗锯齿系列文档: 多重采样抗锯齿Multiple Sample Anti-aliasin...

  • OpenGL(二)

    抗锯齿 混合的2 功能:颜 组合、抗锯 混合处理-抗锯齿 //开启混合处 glEnable(GL_BLEND); ...

  • OpenGL(四)-两种方式实现抗锯齿效果

    方式一 : 利用混合(GLBlend)实现抗锯齿 核心代码如下: 方式二 : 利用多重采样实现抗锯齿 效果图: 关...

网友评论

      本文标题:23.opengl高级-抗锯齿

      本文链接:https://www.haomeiwen.com/subject/obmthktx.html