23.opengl高级-抗锯齿

这两天有点疲惫,这一章节的代码没有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个子样本

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • opengl入门-坐标系统(1)

    坐标系变换流程 变换的好处: 1.1 方便计算 1.2 把很复杂的逻辑拆解成一次次独立的简单变换

    用户1068165
  • 22.opengl高级-实例化

    绘制有共同特征,或者按照一定规则变化的图形阵列,如果挨个按照普通流程来绘制:绑定VAO、绑定纹理、设置uniform-->调用glDrawArrays(GL_T...

    用户1068165
  • opengl入门-纹理

    用户1068165
  • Selenium自动化测试-3.元素定位(3)

    css定位是通过css选择器进行定位,我们需要了解css选择器的一些知识才能进行css定位,选择器基本语法如下:

    ITester软件测试小栈
  • medooze源码分析--启动服务器

    当我们打开index.js 后,看到的第一个重要的 API就是createEndpoint函数了。我们就以这个 API为开头,一步一步的分析一下medooze的...

    音视频_李超
  • 【原创】写给喜欢数据分析的初学者

    以上是一位资深的数据分析师写的自嘲的段子,却是很多分析师的真实写照。在耀眼的职业光环下,数据分析师自身的成长,几乎是与孤寂相伴,在高级打杂中,锻造而成。

    用户1756920
  • 学会这个,再也不怕Python环境安装 (CentOS 6 Python2.7 & Python3.7)

    为什么举例来说这个安装过程呢, 因为现在开发部署的主流linux就是CentOS,而大部分人目前所使用的版本是CentOS Linux release 7.x ...

    蒋老湿
  • Centos7安装Python2.7

    1、删除现有Python [root@test ~]# rpm -qa|grep python|xargs rpm -ev --allmatches --nod...

    py3study
  • 人脸检测--SSH: Single Stage Headless Face Detector

    SSH: Single Stage Headless Face Detector ICCV2017 https://github.com/mahyar...

    用户1148525
  • webpack学习(五)配置详解

    配置详解 //使用插件html-webpack-plugin打包合并html //使用插件extract-text-webpack-plugin打包独立的css...

    柴小智

扫码关注云+社区

领取腾讯云代金券