内容简介:在前面的博客文章中有提到除了透过矩形区域,还可以实现透过任意形状区域来观察物体,这就是要用到 OpenGL 的 Alpha 透明度测试。关于 Alpha 透明度测试,在 用
在前面的博客文章中有提到 OpenGL 裁剪测试及注意点 ,并且裁剪测试只能裁剪一个矩形区域,相当于就是把整个内容都绘制上去了,但是透过一个小矩形区域来看绘制的物体。
除了透过矩形区域,还可以实现透过任意形状区域来观察物体,这就是要用到 OpenGL 的 Alpha 透明度测试。
关于 Alpha 透明度测试,在 用 OpenGL 对视频帧内容进行替换 也用实践用到过。
在 OpenGL 中,每个颜色都有四个色彩通道 --- RGBA,其中 A 就是 Alpha 透明度通道,可以利用它的值进行检测。
Alpha 测试的基本原理为,当绘制一个片元时,首先检测其 Alpha 值,若 Alpha 值满足要求,就通过测试,绘制此片元,否则丢弃此片元,不进行绘制。
比如如下的场景:
如果是裁剪测试,只能屏幕上透过一个矩形区域来观察实际场景。
而换成 Alpha 测试,就可以实现透过任意形状的观察,效果如下:
图上的内容实际由三部分组成,树、地形、中间带透明度的边框。
正因为绘制的边框带透明度,才不会全部遮住后面的内容。
具体绘制代码如下:
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT or GLES20.GL_COLOR_BUFFER_BIT) // 打开深度检测 GLES20.glEnable(GLES20.GL_DEPTH_TEST) // 设置相机和观察矩阵,绘制地形和树 MatrixState.setProjectFrustum(-ratio!!, ratio!!, -1f, 1f, 1f, 100f) MatrixState.setCamera(cx, 0f, cz, 0f, 0f, 0f, 0f, 1.0f, 0f) MatrixState.pushMatrix() MatrixState.translate(0f, -2f, 0f) // 绘制地形 desert!!.drawSelf(desertId) MatrixState.popMatrix() // 开启混合,因为树要和地形有混合的地方 GLES20.glEnable(GLES20.GL_BLEND) // 设置混合因子 GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA) MatrixState.pushMatrix() MatrixState.translate(0f, -2f, 0f) // 绘制树 tg!!.drawSelf(treeId) MatrixState.popMatrix() // 关闭混合 GLES20.glDisable(GLES20.GL_BLEND) // 清除深度缓冲 GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT) // 设置相机和投影矩阵来绘制带透明度的边框 MatrixState.pushMatrix() MatrixState.setProjectOrtho(-1f, 1f, -1f, 1f, 1f, 100f) MatrixState.setCamera(0f, 0f, 3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f) rect!!.drawSelf(maskTextureId) MatrixState.popMatrix() 复制代码
这里面绘制带透明度的边框时清除了一次深度缓冲,因为带透明度边框不属于主场景,不应该和主场景中的物体以同一标准进行深度检测,否则可能会产生不正确的视觉效果。
具体实现
Alpha 测试的重点在于片段着色器的处理,在这里可以对每一个片段进行处理,根据 Alpha 来决定是否抛弃它。
precision mediump float; varying vec2 vTextureCoord; //接收从顶点着色器过来的参数 uniform sampler2D sTexture;//纹理内容数据 void main() { //给此片元从纹理中采样出颜色值 vec4 bcolor = texture2D(sTexture, vTextureCoord); if(bcolor.a<0.6) { discard; } else { gl_FragColor=bcolor; }} 复制代码
根据具体的图片透明度,这里,如果透明度小于 0.6 ,就抛弃这个片元,否则的话就赋值给原本采样的颜色。
其中,在 GLSL 着色器语言中, discard
代表放弃该片元。
而 texture2D 方法代表纹理采样,它的结果类型是一个向量,向量在着色器代码中的地位非常重要,可以方便地存储以及操作 颜色 、 位置 、 纹理坐标 等不仅包含一个组成部分的量。
对于一个向量,有时需要单独访问向量中的某个分量,基本语法为 <向量名>.<分量名>
,从不同的角度来看,它的每个分量代表的含义是不同的:
- 将向量看作颜色时,可以使用 r、g、b、a 四个分量名,分别代表红、绿、蓝、透明度 4 个色彩通道。
vec4 aColor; aColor.r = 0.6; aColor.g = 0.8; 复制代码
若向量是 4 维的,可以使用的分量名为 r、g、b、a;若向量是 3 维的,可以使用的分量名为 r、g、b;若是 2 维的,可以使用的 r、g 两个分量名。
- 将向量看作位置时,可以使用 x、y、z、w 四个分量名,分别代表 x 轴、y 轴、z 轴分量及 w 值。
vec4 aPosition; aPosition.x = 34.2 aPosition.z = 12.2 复制代码
若向量是 4 维的,可以使用的分量名为 x、y、z、w;若向量是 3 维的,可以使用的分量名为 x、y、z;若是 2 维的,可以使用的 x、y 两个分量名。
- 将向量看作纹理坐标时,可以使用 s、t、p、q 四个分量名,分别代表纹理坐标的不同分量。
vec4 aTexCoor; aTexCoor.s = 0.45; aTexCoor.t = 0.22; 复制代码
若向量是 4 维的,可以使用的分量名为 s、t、p、q;若向量是 3 维的,可以使用的分量名为 s、t、p;若是 2 维的,可以使用的 s、t 两个分量名。
除了使用 .
的形式来访问分量名,还可以将向量看作一个数组,用下标来进行访问:
aColor[0] = 0.4; aPostion[2] = 0.34; aTexCoorp[1] = 0.12; 复制代码
理解了 discard 的作用和向量各分量的含义,就很容易明白 Alpha 测试的原理了。
实际上,Alpha 测试并不是渲染管线上要进行的操作流程,而是我们自己想出的根据 Alpha 透明度值对片元进行处理罢了。
具体的实现可以参考我的 Github 项目,求一波 Star 。
OpenGL 相关文章:
最后
俗话说:
独学而无友,则孤陋而寡闻
学习的路上是需要交流和分享的,这里有个二维码,如果你对 OpenGL ES 感兴趣欢迎一起来交流讨论。
要是二维码过期了,加微信 ezglume 好友,备注 OpenGL ,拉你入群~
这里还有个二维码,欢迎扫码关注,及时阅读最新文章内容~~
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- BUF早餐铺 | Twitter 公布今年上半年透明度报告;伊朗相关黑客利用网络钓鱼攻击活动人士和美国官员...
- PyQT设置控件透明度
- swift – 如何为SKShapeNode的不透明度设置动画?
- AI透明度引发关注 科技巨头推工具解释算法决策过程
- win2d 通过 CanvasActiveLayer 画出透明度和裁剪
- 透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 WPF 和 HLSL 的实现)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Host Your Web Site In The Cloud
Jeff Barr / SitePoint / 2010-9-28 / USD 39.95
Host Your Web Site On The Cloud is the OFFICIAL step-by-step guide to this revolutionary approach to hosting and managing your websites and applications, authored by Amazon's very own Jeffrey Barr. "H......一起来看看 《Host Your Web Site In The Cloud》 这本书的介绍吧!