颜色的中的α分量控制着颜色的透明度,在webgl
实现透明效果需要用到α混合,因为webgl
已经内置了该功能因此开启即可
开启混合
- 开启混合功能 -
gl.enable(gl.BLEND)
- 指定混合函数 -
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
混合函数
在进行α混合时,实际上webgl
用到了两个颜色,即 源颜色和 目标颜色,前者是 待混合进去的颜色后者是 待被混合进去的颜色
gl.blendFunc(src_factor, dst_factor)
混合后的颜色计算如下:
<混合后的颜色> = <源颜色> * src_factor + <目标颜色> * dst_factor
参数:
src_factor
:指定源颜色在混合后颜色中的权重因子dst_factor
:指定目标颜色在混合颜色中的权重因子
有一种常用的混合方式 加法混合,加法混合会使被混合的区域更加明亮,通常被用来实现爆炸的关照效果,或者游戏中需要引起玩家注意的任务物品
<gl.bendFunc(GL_SRC_ALPHA, GL_ONE)>
物体透明
需要实现物体的透明效果,只需要开启混合然后关闭深度检测就可以了
// 开启混合
gl.enable(gl.BLEND);
// 设置混合函数
gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);
但是场景中的物体不一定全部都是透明的,并且物体与物体间的深度关系也需要处理,因此不能全部关闭深度检测;
webgl
可以通过某种机制,同时实现隐藏面消除和半透明效果
- 开启隐藏面消除功能 –
gl.enable(gl.DEPTH_TEST)
- 绘制所有不透明的物体(
α
为0
) - 锁定用于进行隐藏面消除的深度缓冲区的独写操作,使之只读
gl.depthMask(false)
- 绘制所有半透明的物体(
α
小于0
),注意它们应当按照深度排序,然后从后向前绘制 - 释放深度缓冲区,使之可读可写
gl.depthMask(true)
gl.depthMask()
方法用来锁定和释放深度缓冲区
隐藏面消除原理
深度缓冲区存储了每个像素的z
坐标值,(归一化为0.0
到1.0
之间),假设场景中有两个前后重叠的三角形A
和B
;
首先,在绘制三角形A
的时候,将他们的每个片元的z
值写入深度缓冲区,然后在绘制三角形B
的时候,将B
中与A
重叠的片元和深度缓冲区中的对应像素的z
值左比较;
如果深度缓冲区的z
值小,就说明三角形A
在前面,那么B
的千元就被舍弃discard
了,不会写入颜色缓冲区;
如果深度缓冲区中的z
值大,就说明三角形B
在前面,会把B
的片元写入颜色缓冲区,将之前的A
的颜色覆盖掉,这样当绘制完成时,颜色缓冲区中的所有像素都是最前面的片元;以上这些操作都是在片元层面上进行的;