第二十三课,抗锯齿(Anti Aliasing)

2023-10-27

Anti Aliasingˈæntiˈeliəsɪŋ )反走样

超采样抗锯齿(Super Sample Anti-aliasing, SSAA)

使用更高分辨率的帧缓存生成图片,再通过多余的像素来做抗锯齿操作。

虽然它确实能够解决走样的问题,但是由于这样比平时要绘制更多的片段,它也会带来很大的性能开销。

在这项技术的基础上也诞生了更为现代的技术,叫做多重采样抗锯齿(Multisample Anti-aliasing, MSAA)

多重采样抗锯齿(Multisample Anti-aliasing, MSAA)

MSAA是“多重采样抗锯齿”,可以使画面更加平滑。

超级采样抗锯齿(Super Sampling Anti-Aliasing)的原理是把当前分辨率成倍提高,然后再把画缩放到当前的显示器上。这样的做法实际上就是在显示尺寸不变的情况提高分辨率,让单个像素变得极小,这样就能够大幅减轻画面的锯齿感了。不过是由于对整个显示画面的放大,因此它消耗的显示资源也是非常大的。不过MSAA是寻找出物体边缘部分的像素,然后对它们进行缩放处理。由于只是物体的外层像素进行缩放处理,忽略掉了不会产生锯齿的内部像素,所以显卡不会像处理SSAA(超级采样抗锯齿)那样需要庞大的计算量,因此MSAA比起SSAA来更有效。

GLFW中的MSAA

glfwCreateWindow调用之前提示窗口使用多重采样glfwWindowHint(GLFW_SAMPLES, 4);
启动glEnable(GL_MULTISAMPLE);开启多重采样(一般情况下默认开启)

OpenGL离屏MSAA

缓存

使用纹理缓存

在帧缓存绑定的纹理中使用glTexImage2DMultisample,纹理目标是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);

它的第二个参数设置的是纹理所拥有的样本个数。如果最后一个参数为GL_TRUE,图像将会对每个纹素使用相同的样本位置以及相同数量的子采样点个数。

使用glFramebufferTexture2D将多重采样纹理附加到帧缓冲上。

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
使用多重采样缓冲对象缓存

我们所要做的只是在指定(当前绑定的)渲染缓冲的内存存储时,将glRenderbufferStorage的调用改为glRenderbufferStorageMultisample就可以了。

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

将多重采样帧缓存直接渲染到屏幕

glBlitFramebuffer会将一个用4个屏幕空间坐标所定义的源区域复制到一个同样用4个屏幕空间坐标所定义的目标区域中。
将离屏帧缓存定义为读缓存,将屏幕定义为渲染缓存。

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

函数glBlitFramebuffer

glBlitFramebuffer(readbuffer(srcX0, srcY0, srcX1, srcY1),drawbuffer(dstX0, dstY0, dstX1, dstY1),mask,filter)
mask:指示要复制哪些缓冲区的标志的“或”位。允许的标志是GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT。
filter:指定在图像拉伸时应用的插值。必须为GL_NEAREST或GL_LINEAR。

将多重采样纹理传送为一个普通颜色附件

没有实际代码。

自定义抗锯齿算法

使用Uniform将多重采样纹理导入着色器

uniform sampler2DMS screenTextureMS;

使用texelFetch获取每个子样本的颜色值

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

QT+OpenGL中的MSAA

内置方法

在这里插入图片描述
使用抗锯齿

GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
    QSurfaceFormat formate;
    formate.setSamples(4);//采样数
    setFormat(formate);
}

在这里插入图片描述
使用后的问题:glReadPixels无法获取到物体的模板值。(怎么解决,尚且不知)。

离屏方法

引自:https://www.liangzl.com/get-article-detail-230476.html

想要实现离屏的MSAA,我们需要添加两个QOpenGLFrameBufferObject实例;其中一个用于多重采样, 一个多重采样的图像包含比普通图像更多的信息 ,所以此时我们的另外一个QOpenGLFrameBufferObject 实例就需要实现降采样;

那么首先我们创建两个FBO,并分别设置其采样值

//MultiSampling set to 4 now
		QOpenGLFramebufferObjectFormat muliSampleFormat;
       	muliSampleFormat.setAttachment (QOpenGLFramebufferObject::CombinedDepthStencil);
        muliSampleFormat.setMipmap(true);
        muliSampleFormat.setSamples(4);
        muliSampleFormat.setTextureTarget(GL_TEXTURE_2D);
        muliSampleFormat.setInternalTextureFormat(GL_RGBA32F_ARB);

        //fbo=new QOpenGLFramebufferObject(this->width(),this->height(),QOpenGLFramebufferObject::Depth);
        fbo=new QOpenGLFramebufferObject(this->width(),this->height(),muliSampleFormat);

        QOpenGLFramebufferObjectFormat downSampledFormat;
        downSampledFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
        downSampledFormat.setMipmap(true);
        downSampledFormat.setTextureTarget(GL_TEXTURE_2D);
        downSampledFormat.setInternalTextureFormat(GL_RGBA32F_ARB);

        renderfbo=new QOpenGLFramebufferObject(this->width(),this->height(),downSampledFormat);

然后在执行渲染操作的时候,首先绑定多重采样FBO,将内容绘制到多重采样FBO中,然后解绑多重采样FBO。接着绑定降采样FBO,然后使用 QOpenGLFramebufferObject::blitFramebuffer方法,实现位块传送,此时解绑降采样FBo。然后从降采样的FBO中获取textureid,并进行渲染;

void MyGLWidget::paintGL()
{
    if(fbo!=nullptr)
    {
        bool result = fbo->bind();
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
        //在此进行物体的渲染



        if(result)
        {
            fbo->release();
            renderfbo->bind();
            QOpenGLFramebufferObject::blitFramebuffer(renderfbo,fbo,GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT,GL_NEAREST);
            renderfbo->release();
            GLuint textureid=renderfbo->texture();

            m_program->bind();
            {
                glActiveTexture(GL_TEXTURE0);
                glBindTexture(GL_TEXTURE_2D, textureid);
                glUniform1i(m_program->uniformLocation("screenTexture"), 0);
                m_vao->bind();
                glDrawArrays(GL_TRIANGLES, 0, 6);
                m_vao->release();

            }
            m_program->release();
        }

    }
   
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第二十三课,抗锯齿(Anti Aliasing) 的相关文章

  • OpenGL C++ 鼠标光线拾取 glm:unproject

    我目前正在开发 C 游戏引擎 我想在应用程序中构建鼠标交互 我之前通过光线拾取完成了此操作 但当时我使用了固定的鼠标位置 现在我想不使用它 我读到您可以使用 glm unProject 函数来执行此操作 但我的函数不起作用 该函数给出的坐标
  • 如何通过着色器管道传递顶点颜色?

    我试图通过顶点 几何和片段着色器传递顶点颜色 glBegin GL POINTS glVertex3f 2 0f 0 0f 0 0 glColor3f 0 0 1 0 0 0 glVertex3f 2 0f 0 0f 0 0 glColor
  • 3D 图形矩阵 4x4 中最后一行的 magic 4 的用途是什么?

    当我阅读有关WebGL的书时 我看到了下一个矩阵描述 有关于书中最后一行的信息 WebGL 初学者指南 初学者指南 Diego Cantor Brandon Jones 神秘的第四排 第四排没有任何特殊之处 意义 元素 m4 m8 m12
  • glGenerateMipmap 是否在 sRGB 纹理的线性空间中执行平均?

    OpenGL 3 3 规范似乎没有要求 mipmap 生成在线性空间中完成 我能找到的只有以下内容 派生的 mipmap 数组的内部格式都与 levelbase 数组和派生数组的维度如下 第 3 8 14 节中描述的要求 的内容 派生数组是
  • 将 CVPixelBuffer 渲染到 NSView (macOS)

    我有一个CVPixelBuffer我正在尝试在屏幕上有效地绘制 转变为低效率的方式NSImage可以工作 但速度非常慢 丢掉了大约 40 的帧数 因此 我尝试使用将其渲染在屏幕上CIContext s drawImage inRect fr
  • 将glm四元数转换为旋转矩阵并与opengl一起使用

    所以我将对象的方向存储在 glm fquat 中 我想用它来旋转我的模型 我怎么做 我试过这个 glPushMatrix glTranslatef position x position y position z glMultMatrixf
  • Opengl 非同步/非阻塞地图

    我刚刚找到以下内容OpenGL 规范ARB map buffer range http www opengl org registry specs ARB map buffer range txt 我想知道是否可以使用此扩展进行非阻塞地图调
  • 对 VBO 中的特定三角形使用不同的纹理

    我有 9 个由三角形组成的四边形 如下所示 我在用着VBO存储有关它们的数据 它们的位置和纹理坐标 我的问题是 是否可以仅使用一个来使四边形 5 具有与其余四边形不同的纹理VBO and shader 绿色代表纹理 1 黄色代表纹理 2 到
  • (定义一个宏)方便OpenGL命令调试?

    有时插入条件打印和检查需要很长时间glGetError 使用二分搜索的形式来缩小范围 其中第一个函数调用是 OpenGL 首先报告错误 我认为如果有一种方法可以构建一个宏 我可以包装所有可能失败的 GL 调用 并有条件地调用 那就太酷了gl
  • 三角形未在 OSX 上的 OpenGL 2.1 中绘制

    我正在学习有关使用 OpenGL 在 Java 中创建游戏引擎的教程 我正在尝试在屏幕上渲染一个三角形 一切运行良好 我可以更改背景颜色 但三角形不会显示 我还尝试运行作为教程系列的一部分提供的代码 但它仍然不起作用 教程链接 http b
  • glutPostRedisplay 不在循环内工作

    我试图让一个人在 y 轴上跳跃 所以我使用 2 秒的循环 第一秒它应该向下移动并弯曲膝盖 第二秒它应该向上移动 然后在起始位置完成 现在我刚刚开始让这个人在第一秒内跪下并弯曲膝盖 我还没有编写动画的其余部分 问题是 glutPostRedi
  • 如何将点光源转换为卵形/椭圆形?

    我希望通过具有不同 x 和 y 值的 vec2 半径将当前的圆形光变成椭圆形 有没有办法根据我当前在片段着色器中的代码来做到这一点 uniform struct Light vec4 colour vec3 position vec2 ra
  • OpenGL 着色器不与着色器程序链接

    我正在尝试使用 GLFW GLEW 添加着色器 我收到一个错误 指出着色器已加载 但它们没有有效的对象代码 这是我用于加载着色器的代码 class SHADER public void LoadShaders const char vert
  • lnk1104:无法打开“LIBC.lib”链接

    使用 GLee 将着色器写入我的 OpenGL 项目并编译后 我收到了错误LNK1104 cannot open file LIBC lib 我尝试按照其他人的建议添加它并忽略它 但没有解决问题 有没有其他方法可以解决我错过的这个问题 以下
  • 阻止 OpenGL.framework 在 Cocoa 应用程序中加载

    我的应用程序链接到这些框架 Cocoa Framework AppKit Framework CoreData Framework Foundation Framework 请注意 OpenGL Framework 是NOT已链接 但是 设
  • glBlitFramebuffer 渲染缓冲区和渲染全屏纹理哪个更快?

    哪个更快更高效 使用 OpenGL 纹理作为 CUDA 表面并在四边形上渲染 新样式 使用渲染缓冲区作为 CUDA 表面并使用 glBlitFramebuffer 进行渲染 None
  • glut 库中缺少 glutInitContextVersion()

    我正在练习一些 opengl 代码 但是当我想通过以下方式强制 opengl 上下文使用特定版本的 opengl 时glutInitContextVersion 它编译过程失败并给出以下消息 使用未声明的标识符 glutInitContex
  • SDL 鼠标位置调整大小后裁剪

    我在 SDL 中的鼠标位置上遇到了一些奇怪的行为 如果我将窗口大小调整得更大 则任一鼠标事件的 x y 位置似乎都限制为原始窗口的宽度和高度 如果我缺少一些函数调用来告诉 SDL 鼠标区域的大小已增加 应用程序的相关部分 void Resi
  • 使用 C# 截取任何外部应用程序的屏幕截图

    我们有一个 C WPF 应用程序 我们想要在其中截取我们启动的任意应用程序的屏幕截图 即 我们可以引用我们启动的进程 应用程序可能已最小化或位于其他窗口后面 但我们仍然只需要单个应用程序的图像 而不是重叠像素 我知道使用 BitBlt 或的
  • 为什么OpenGL使用float而不是double? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi

随机推荐

  • 南科大于仕琪团队招聘研究助理教授,博士后

    南方科技大学于仕琪副教授团队招聘研究助理教授 博士后 博士生和硕士生 团队特色 专注步态识别方向十余年 在步态识别方向具有较高的影响力 研究助理教授 研究方向 步态识别 行人视频合成 图像和视频中的人体建模 视频中人的行为分析及相关 要求
  • 分布式系统架构——CAP理论

    1 什么是CAP 在分布式系统中 任何存储系统 有状态服务 都会涉及到CAP定理 Consistency 一致性 简称C 在同一时刻所有节点是具有同样的数据副本 每个节点的数据要保证实时同步 Availability 可用性 简称A 对于一
  • Ubuntu14.04 :By not providing "FindEigen3.cmake" in CMAKE_MODULE_PATH

    Ubuntu14 04 By not providing FindEigen3 cmake in CMAKE MODULE PATH 今天下载了hector slam的源码想要跑一下 结果编译不能通过 并且一直出现如下错误 烦得一逼 研究了
  • 兼容性测试真实案例-餐饮APP

    兼容性测试真实案例 某餐饮APP 项目背景 APP是以电商加直播为载体 供应链为核心 辅以短视频和直播内容分销带货 以及积分商城体系 本项目主要对APP的商品列表及商品采购流程及涉及页面 针对不同品牌 操作系统 分辨率的机型 验证APP是否
  • jenkins和jdk安装教程(安装支持jdk8的最新版本)

    1 安装版本查看 Jenkins稳定版 2 进入清华镜像 下载对应版本的rpm包 清华镜像 3 已rpm安装过Jenkins 现在先卸载 1 卸载 rpm e jenkins 2 检查是否卸载成功 rpm ql jenkins 3 彻底删除
  • (大集合)AI工具和用法汇总—集合的集合

    AI 工具和用法汇总 汇集整理 by Staok 瞰百 源于相关资料在我这慢慢越积累越多 到了不得不梳理的程度 文中有许多内容作者还没有亲自尝试 所以很多内容只是罗列 但信息大源都已给出 授人以渔 欢迎 PR 补充细节内容 比如 好的教程
  • HTML+CSS简单复习

    目录 什么是HTML CSS VSCode编辑器 HTML基本结构和属性 HTML初始代码 HTML注释 标题与段落 文本修饰标签 图片标签 路径的引入 链接标签 锚点 特殊字符 列表标签 表格标签 表单标签 div和span CSS基础语
  • 【机器学习笔记4】逻辑回归模型

    目录 什么是逻辑回归 Sigmoid函数 决策边界 逻辑回归的损失函数 为什么平方误差模型不可行 对数损失函数 单个样例损失 整体损失函数 梯度下降算法 补充 F1 score评价指标 F1 Score简介 相关概念 F Score 示例及
  • 第一次实践一个多文件的代码

    收获 1 ifndef防止头文件重复包含 为了避免同一个头文件被包含 include 多次 C C 中有两种宏实现方式 一种是 ifndef方式 另一种是 pragma once方式 ifndef 标识符A 每一个头文件都要有自己独特的标识
  • 小程序通过webview实现本地任意文件上传

    微信小程序做文件上传的时候 只能选择相册的图片或者视频 没办法选择手机内存卡里的文件 比如 word pdf文件等等 下面可以通过 webview 的方式 借用 h5 的方式即可实现上面的功能 添加业务域名 webview里面打开的地址 首
  • 【pytorch】pytorch-yolov3拍照并保存,进行检测后遍历所有图片并显示图片

    参看摄像头参数 v4l2 ctl d dev video0 all 安装numpy sudo apt get install python numpy 下载onnx pip install onnx 效果图 拍照部分 url http 19
  • HashMap实现原理及源码分析

    哈希表 hash table 也叫散列表 是一种非常重要的数据结构 应用场景及其丰富 许多缓存技术 比如memcached 的核心其实就是在内存中维护一张大的哈希表 而HashMap的实现原理也常常出现在各类的面试题中 重要性可见一斑 本文
  • Dubbo实战(三)多注册中心配置

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net FX SKY article details 51935533 本文将展示如何在Dubbo中进行多注册中心配置 开发环境 JDK 1 7 Maven
  • 如何实现前后端交互

    大概流程 首先我们要实现前端的页面 我们要有一个页面来让我们肉眼可以看见 JS的语法我们要掌握 1因为我们要通过JS来绑定事件 比如我们点击按钮就能发送数据给服务器 或者从服务器获取资源 2我们通过ajax请求来实现向服务器发送请求 3通过
  • mfc140u.dll丢失怎么解决?,哪种方法更简单?

    如果您在运行 Windows 操作系统时遇到了 mfc140u dll 丢失 或 找不到 mfc140u dll 等错误提示 那么这意味着您的计算机遗失了该文件 mfc140u dll 文件是 Microsoft Visual C 的一部分
  • jmeter如何进行一个简单的测试(超级详细,有图有文字,闭着眼都能成功)

    大家好 我是雄雄 内容先知 前言 软件获取 开始测试 1 新建线程组 2 创建一个请求 3 添加HTTP信息头 4 开始测试 5 查看请求情况 前言 上头问题要服务器的配置 基于我们现在做的项目 需要安排别人去采购服务器 给出的消息是 20
  • pytest.mark.parametrize及mock使用

    目录 pytest mark parametrize mock patch pytest mark parametrize 现在有 zjk py 模块 想测试其中 add 函数的功能 传入 x y 把 x 平方后的结果与 y 相加返回 zj
  • 在线旅游OTA行业调研报告-携程美团同程飞猪booking对比分析

    1 行业现状 根据前瞻研究院数据显示 2019年 我国在线旅游交易规模首次突破万亿规模 达到10866 5亿元 同比增长11 4 随着市场不断扩大 行业竞争也愈发激烈 市场上形成了以携程系 阿里系 美团系三大实力角逐的格局 在线酒店预订市场
  • Root cause: BlockMissingException【查看修复HDFS中丢失的块】ORG.APACHE.HADOOP.HDFS.BLOCKMISSINGEXCEPTION: COULD

    首先得好看有多少损坏的文件 其中需要使用Hadoop的fsck命令 以下是官方解释 用法 hadoop fsck 路径 以上将会展示该路径下所有受损的文件 最后用 delete 可以清除掉所有受损的文件
  • 第二十三课,抗锯齿(Anti Aliasing)

    Anti Aliasing nti eli s 反走样 文章目录 超采样抗锯齿 Super Sample Anti aliasing SSAA 多重采样抗锯齿 Multisample Anti aliasing MSAA GLFW中的MSA