« 点与直方图处理的小结全屏反锯齿 - 多重采样Ⅱ »

全屏反锯齿 - 多重采样Ⅰ

 图形绘制的时候总能看见那些不美观的锯齿。尤其是边缘锯齿给用户带来的突兀感,给了计算机图形学几乎一个属于“领域”的研究——反锯齿。视觉上的美观优化,以及改进后的运行效率,两手都要硬。——ZwqXin.com

本文来源于 ZwqXin (http://www.zwqxin.com/), 转载请注明
      原文地址:http://www.zwqxin.com/archives/opengl/antialiasing-multi-sample-1.html

锯齿是由于屏幕分辨率低所造成的赝项,想必大家也知道这指什么。CSDN里一位高人仁兄问道,在显卡设置里面有所谓的“反锯齿”选项,可以设置覆盖采样的参数,那么在OpenGL里是否也有相应的API能够做相应的设置呢?我刚开始是认为所谓显卡里的抗锯齿是shader里对屏幕做全屏PCF(百分比渐进过滤),而OPENGL的API里面也没见过有什么可以接收类似覆盖采样这样的参数的,顶多是glHint那类函数可以通过混合等缓解点线的锯齿现象罢了。可接下来有人回帖说了NEHE46课,我马上“觉醒”,对喔,NEHE里[搜集的优良OpenGL教程] 确实有课叫什么“全屏反锯齿”的,马上在电脑里找出来看——还真的有呢!

所谓采样参数,也可以说是“平滑处理级别”,一般就有1X,2X,4X,8X,16X这几个值。在[图像处理里的空间域滤波] 一文中,谈到了图像的平滑处理(模糊),其本质就是通过把一个像素作邻域处理(领域加合平均)得出新像素值而已,领域大小被称为模板参数,一般是个奇数,这样才能把待处理像素包围在中间。而这里的采样参数,乍一看就是2的N次方这样的数,但窃认为其实都是那么回事,只不过更适合于描述而已。

通常认为在实时图形学中,这种像素级别的操作应该交给强大的Shder。在shader里被称为dithered samples的,就是PCF系数。因为它的可编程性能,对显卡的要求就更可具弹性了,实际上任何X都可以,不限制于2的N次方。

为了说得清晰点,以橙书里关于对Shadow map做PCF那章的代码段为例(ZwqXin也弄过[Shadow Map阴影贴图技术之探Ⅲ] ):

  1. //Listing 13.7. Fragment shader for generating shadows, using four dithered samples
  2.  
  3. uniform sampler2DShadow ShadowMap;
  4. uniform float Epsilon;
  5. uniform bool  SelfShadowed;
  6. uniform float SelfShadowedVal;
  7. uniform float NonSelfShadowedVal;
  8.  
  9. varying vec3 ShadowCoord;
  10.  
  11. float Illumination;
  12.  
  13. float lookup(float x, float y)
  14. {
  15.     float depth = shadow2D(ShadowMap,
  16.                        ShadowCoord + vec2(x, y) * Epsilon).x;
  17.     return depth != 1.0 ? Illumination : 1.0;
  18. }
  19.  
  20. void main()
  21. {
  22.     // lighten up the self-shadows
  23.     Illumination = SelfShadowed ? SelfShadowedVal : NonSelfShadowedVal;
  24.  
  25.     // use modulo to vary the sample pattern
  26.     vec2 o = mod(floor(gl_FragCoord.xy), 2.0);
  27.  
  28.     float sum = 0.0;
  29.  
  30.     sum += lookup(vec2(-1.5, 1.5) + o);
  31.     sum += lookup(vec2( 0.5, 1.5) + o);
  32.     sum += lookup(vec2(-1.5, -0.5) + o);
  33.     sum += lookup(vec2( 0.5, -0.5) + o);
  34.  
  35.     gl_FragColor = vec4(sum * 0.25 * gl_Color.rgb, gl_Color.a);
  36. }

这里你可以认为是为了消缓shadow map形成的锯齿而做的“全屏反锯齿”,或者说“全屏模糊化”“全屏平滑化”(针对阴影帖图覆盖之场景)。参数是4X。看最下面几行,它做了一些检索纹理(阴影图)的动作。sum是个颜色计数器,它把当前处理像素所在纹素的周边四个纹素的值相加,并在输出时除以4以归一化回[0,1]区间——这是典型的模板滤波操作。当然还有一点小动作(取非整值并根据纹理索引的奇偶再偏移0个或1个纹素),不多提,但总体思路就是这样——这就是PCF的雏形。一张纹理的颜色过渡只有在边缘处巨变,而人眼对边缘的部分总是比较敏感,边缘处产生的模糊正能消除这种突兀感。

好吧,如果这算4X,那么5X,6X如此下去都可以。但是4X和5X你能想到两者有啥区别么?无非后者多搅和了一个纹素而已,如果这个被搅和的纹素不用中心纹素,你还得决定是在哪个方向多加一个呢!6X就更不用说了.......所以说,下一个“级别”应该是关于中心纹素得包围圈向外延伸一个纹素,每方向上加多一个,也就是8X了.......如此类推,你能发现比较匀称和谐的“采样参数”都是2的N次方。

另一方面,总不能无限地32X,64X下去吧,要知道,每多一个“级别”,对每个像素就得做多一倍的加法,运算效率下来了,这还不算,更主要的是,整张纹理都被错位叠加N次了,纹理被覆物最后真被模糊得血肉模糊,不成人形(喂,本来就不成嘛)了——因为平滑模糊,就相当于去处细节!

概念讲到这里,回到开头那里。显卡里的PCF?我看了看自己的显卡的控制面板(NV9),里面解释到:

平滑处理可设置为有利于提高系统性能或改进图象质量。

  • 如果要显示三维动画效果和强调场景的流畅变换,最好使用性能设置。

  • 如果要以显示非常精细和逼真的三维物体为主要目的时,最好使用质量设置。

  • 在“管理 3D 设置”页面上(高级视图),您可以设置具体的平滑处理级别。

    值越高,对应的平滑处理的级别就越高。例如,16x 的质量要高于 2x。  

    在 GeForce 8 系列 GPU 中,NVIDIA 推出了一种新形式的平滑处理,称为“覆盖采样”,该功能对 8x、16x 和 16xQ 平滑处理设置产生影响。如需更多信息,请参照 NVIDIA.com 网站上关于 Lumenex 引擎技术的简介。

  • 如果您不能肯定如何配置平滑处理,请使用“应用程序控制的”选项。您的显示将根据应用程序的规定自行调整。

有粗略的设置方法(质量-效率权衡):

全屏反锯齿-多重采样Ⅰ

也有可能做个精确一点的设置:

全屏反锯齿-多重采样Ⅰ

的确是可以设置的。那么,既然显卡提供了这样的功能,那么有对应的集成API也很正常吧。但是,看完NEHE46课后,我知道OPenGL里能实现这种设置的方法是使用一个叫"multi sample"的扩展。而且也不能一步到位,需要设置不少东西。我不能肯定它与PCF有没有什么特别的联系,于是我想自己按照NEHE 46来实现一下。

请留意下篇文章:全屏反锯齿 - 多重采样Ⅱ

本文来源于 ZwqXin (http://www.zwqxin.com/), 转载请注明
      原文地址:http://www.zwqxin.com/archives/opengl/antialiasing-multi-sample-1.html

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

IE下本页面显示有问题?

→点击地址栏右侧【兼容视图】←

日历

Search

网站分类

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Walle Build 100427

Copyright 2008-2013 ZwqXin. All Rights Reserved. Theme edited from ipati.