阅读 317

OpenGL入门第六课-- 裁剪和混合

裁剪

     前面两节分别说到了深度测试和正背面剔除,这两种技能都是OpenGL中常用的提高渲染性能的方式;裁剪也是一种提高渲染性的方式. OpenGL允许只刷新屏幕上发⽣变化的部分,可以在要进行渲染的窗⼝去指定⼀个裁剪框.在这个裁剪框里去渲染你需要的画面。

     其基本原理是在渲染时限制绘制区域,通过此技术可以再屏幕(帧缓冲)指定⼀个矩形区域。然后启⽤剪裁测试,不在此矩形区域内的片元讲被丢弃,只有在此矩形区域内的片元才有可能进⼊帧缓冲。因此实际达到的效果就是在屏幕上开辟了⼀个⼩窗口,可以再其中进⾏指定内容的绘制。

裁剪测试

      裁剪测试发生在片元着色器,此时已经光栅化将3D图形转换成了2D图形。裁剪测试确定(Xw,Yw)是否位于当前OpenGL上下文所确定的那一部分裁剪矩形范围内.如果该⽚段位于裁剪区域之外,则被抛弃。 

      这里需要了解和区别一下窗口、视口和裁剪区域这三个概率。

窗口、视口和裁剪区域

  • 窗口:就是显示用的界面
  • 视口:就是窗口中用来显示图形的一块矩形区域,它可以和窗口等大,也可以⽐窗口大或者⼩小。只有绘制在视口区域中的图形才能被显示,如果图形有一部分超出了视口区域,那么那⼀一部分是看不到的。通过glViewport()函数设置。
  • 裁剪区域(平⾏投影):就是视⼝矩形区域的最⼩最⼤x坐标(left,right)和最小最大y坐标 (bottom,top),⽽不是窗⼝的最小最大x坐标和y坐标。通过glOrtho()函数设置,这个函数还需指定最近最远z坐标,形成⼀个立体的裁剪区域。

相关API

  • 开启裁剪测试:和OpenGL大多数的功能一样,我们可以启用GL_SCISSOR_TEST来开启裁剪测试:glEnable(GL_SCISSOR_TEST)。
  • 关闭裁剪测试:glDisable(GL_SCISSOR_TEST)
  •  指定裁剪窗⼝:glScissor(Glint x,Glint y,GLSize width,GLSize height);x,y指定裁剪框左下⻆位置,weight、height指定裁剪尺寸

 混合

      OpenGL中,混合(Blending)通常是实现物体透明度(Transparency)的一种技术。透明就是说一个物体(或者其中的一部分)不是纯色(Solid Color)的,它的颜色是物体本身的颜色和它背后其它物体的颜色的不同强度结合。一个有色玻璃窗是一个透明的物体,玻璃有它自己的颜色,但它最终的颜色还包含了玻璃之后所有物体的颜色。这也是混合这一名字的出处,我们混合(Blend)(不同物体的)多种颜色为一种颜色。所以透明度能让我们看穿物体。

颜色组合

     要想渲染有多个透明度级别的图像,我们需要启用混合(Blending) ;glEnable(GL_BLEND)。启用了混合之后,我们需要告诉OpenGL它该如何混合它。当混合功能被启动时,源颜色和目标颜色的组合方式是通过混合方程式控制的:Cf = (Cs * S) + (Cd * D)。其中Cf表示最终计算得到的颜⾊ ;Cs表示源颜色;Cd表示目标颜色;S表示源混合因子指定了alpha值对源颜色的影响;D表示目标混合因子指定了alpha值对目标颜色的影响

      片元着色器运行完成后,并且所有的测试都通过之后,这个混合方程(Blend Equation)才会应用到片元颜色输出与当前颜色缓冲中的值(当前片段之前储存的之前片段的颜色)上。源颜色和目标颜色将会由OpenGL自动设定,但源因子和目标因子的值可以由我们来决定。先来看一个简单的例子:

                        

     假设有两个方形,现在希望将这个半透明的绿色方形绘制在红色方形之上。红色的方形将会是目标颜色(所以它应该先在颜色缓冲中),我们将要在这个红色方形之上绘制这个绿色方形。那么问题来了。因子值设置怎么设置?如果至少想让绿色方形乘以它的alpha值,那么将要将源混合因子S设置为源颜色向量的alpha值,也就是0.6。接下来就应该清楚了,目标方形的贡献应该为剩下的alpha值。如果绿色方形对最终颜色贡献了60%,那么红色方块应该对最终颜色贡献了40%,即1.0-0.6.  带入方程式可得:Cf = [0  1  0  0.6]  *  0.6 + [1   0  0   1] * 0.4。结果就是重叠方形的片段包含了一个60%绿色,40%红色的一种脏兮兮的颜色.

                                             

         最终的颜色将会被储存到颜色缓冲中,替代之前的颜色。那么在OpenGL中该如果设置混合因子呢。

设置混合因子

       设置混合因⼦子,需要⽤用到glBlendFun函数。

glBlendFunc(GLenum sfactor, GLenum dfactor) 

两个参数分别表示源因子与目标因子。OpenGL为我们定义了很多个选项,下面列出大部分最常用的选项:    

      表中R、G、B、A 分别代表 红、绿、蓝、alpha;下标S、D,分别代表源、目标;C 代表常量颜色(默认⿊色) 。注意其中C常量颜色可以通过glBlendColor函数来另外设置。

      比如上面的例子我们使用源颜色向量的alpha作为源因子,使用1-alpha作为目标因子。对应一下的glBlendFun。

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);复制代码

       也可以使用glBlendFuncSeparate为RGB和alpha通道分别设置不同的选项。比如:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);复制代码

     这个函数和我们之前设置的那样设置了RGB分量,但这样只能让最终的alpha分量被源颜色向量的alpha值所影响到。

       OpenGL甚至给了我们更多的灵活性,允许我们改变方程中源和目标部分的运算符。当前源和目标是相加的,但如果愿意的话,我们也可以让它们相减。glBlendEquation(GLenum mode)允许我们设置运算符,它提供了三个选项:

  • GL_FUNC_ADD:默认选项,将两个分量相加
  • GL_FUNC_SUBTRACT:将两个分量相减
  • GL_FUNC_REVERSE_SUBTRACT:将两个分量相减,但顺序相反

     通常我们都可以省略调用glBlendEquation,因为 GL_FUNC_ADD对大部分的操作来说都是我们希望的混合方程,但如果你真的想打破主流,其它的方程也可能符合你的要求。


关注下面的标签,发现更多相似文章
评论