第二十三课,抗锯齿(Anti Aliasing)
Anti Aliasing(ˈænti
,ˈeliəsɪŋ
)反走样
文章目录
- 超采样抗锯齿(Super Sample Anti-aliasing, SSAA)
- 多重采样抗锯齿(Multisample Anti-aliasing, MSAA)
- GLFW中的MSAA
- OpenGL离屏MSAA
- 缓存
- 使用纹理缓存
- 使用多重采样缓冲对象缓存
- 将多重采样帧缓存直接渲染到屏幕
- 将多重采样纹理传送为一个普通颜色附件
- 自定义抗锯齿算法
- QT+OpenGL中的MSAA
- 内置方法
- 离屏方法
超采样抗锯齿(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 nowQOpenGLFramebufferObjectFormat 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();}}}
第二十三课,抗锯齿(Anti Aliasing)相关推荐
- OpenGL 抗锯齿Anti Aliasing
OpenGL抗锯齿Anti Aliasing 抗锯齿Anti Aliasing简介 多重采样 OpenGL中的MSAA 离屏MSAA 多重采样纹理附件 多重采样渲染缓冲对象 渲染到多重采样帧缓冲 自定 ...
- NeHe OpenGL教程 第二十三课:球面映射
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- OpenGL教程翻译 第二十三课 阴影贴图(一)
第二十三课 阴影贴图(一) 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) 背景 阴影和光是紧密联系在一起的,因为如果你想要产生一个阴影就必须要光.有许多的 ...
- 宇宙精密调治的再思《基督教与科学》第二十三课
黄牧师 从圣经诗19:1-2,看宇宙.太阳系.地球.生物.人类的创造. 一.回顾宇宙.地球.生物.人的设计 宇宙.地球.太阳系.行星.地球环境.生命.人,一切都有极端精密的调治,很清楚可以观察到有看不 ...
- Vue2+Vue3的专题目录结构(第二十三课)
这个世界有些事情真的是无法改变的,我们唯一能做的,只是在自己与世界之间找到一个平衡点. 了解Vue框架的大致学习方向(第一课)_星辰镜的博客-CSDN博客 Vue框架的学习(Vue的基础指令操作一)第 ...
- 学习淘淘商城第二十三课(添加商品的实现)
上节课我们一起学习了富文本编辑器的使用,这节课我们一起学习下商品添加的实现. 在item-add.jsp当中,当点击提交按钮后,会触发submitForm方法,如下图所示. 在提交表单前需要校验输入的 ...
- 第二十三课.Kaggle交易预测
目录 简介 基于 lightgbm 的 Kaggle 交易预测 baseline 优化 简介 实验基于 Kaggle 竞赛数据,使用 lightgbm 预测银行客户在未来是否会进行交易,比赛地址(已结 ...
- 【线性代数公开课MIT Linear Algebra】 第二十三课 微分方程与exp(At)
本系列笔记为方便日后自己查阅而写,更多的是个人见解,也算一种学习的复习与总结,望善始善终吧~ 一阶常系数微分方程 Au=dudt 将一阶常系数微分方程转换为线性代数问题的关键在于常系数微分方程的解一定 ...
- 重学java基础第二十三课:java基础 注释
最新文章
- python代码示例下载-使用python3批量下载rbsp数据的示例代码
- Linux+Apache+Postgresql+PHP安装Drupal7.15
- linux查看通信延迟,低优先级进程延迟实时进程中的串行通信(Linux)
- Cisco系列网络设备测试命令大全
- React Native之(var和let区别 )(简单解构)(map对象遍历)(可变顺序参数和不可以变顺序参数函数)
- java内存分配模型优点_高并发实战(二)-并发基础 缓存 MESI 内存模型
- Codeforces Global Round 14, C. Phoenix and Towers
- python中列表中的字典的排序问题
- UGUI ScrollRect使用
- paip.mysql 性能测试by mysqlslap
- 2021MathorCup高校数学建模挑战赛——大数据竞赛的一些想法总结
- HTML5九宫格拼图小游戏
- html当当网上书店,完整版:当当网上书店
- weevely生成木马文件上传获取靶机中的flag文件
- 解决问题:cannot create symlink in “/etc/docker“: existing file in the way
- element 验证出现英文_vue.js+element 默认提示中英文操作
- Linux网络设备驱动结构概述
- 批量绘图 | EXCEL绘制基站扇区地图
- Python编写微信打飞机小游戏(三)
- Web前端学习笔记(十一)---聚光灯效果
热门文章
- Linux平台好用的十款屏幕录制工具
- 【嵌入式开发】ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )
- 解读微博Q1财报:寒冬里稳步向前
- vue后台实现点击图片放大
- 以太坊上的数字资产基金管理应用:Melonport 绿皮书
- 中国市场到底有多少国产开源操作系统?
- CVPR2020最新15篇论文开源代码
- 面试官的一些问题要如何回答?
- windows下c语言删除文件夹
- OpenGL学习——glut/ 场景漫游,对gluLookAt()函数的深入理解