OpenGL ES混合Blend

来源:互联网 发布:js new做了什么 编辑:程序博客网 时间:2024/05/29 04:08
OpenGL开发中经常需要在物体外层再绘制一层,但是又不能覆盖地面的那层事物,相当于透明效果。这种情况可以使用Blend(混合)技术来实现,使用方法如下:
//开启混合GLES20.glEnable(GLES20.GL_BLEND);  //设置混合因子cglBlendFunc(sfactor, dfactor);//TODO 绘制外层//关闭混合GLES20.glDisable(GLES20.GL_BLEND);
sfactor 及 dfactor 分别代表源和目标颜色在混合时所占比重的枚举常量,就是变换因子。
sfactor 可取值包括:
GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA_SATURATE ; 
dfactor 可取值包括:
GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA。

如果设源和目标的颜色数组分别为 S=(sR, sG, sB, sA) D=(dR, dG, dB, dA) ,那么上面各个因子的取值可以表示为下面形式:
GL_ZERO                   = (0, 0, 0, 0)GL_ONE                    = (1, 1, 1, 1)GL_SRC_COLOR              =(sR, sG, sB, sA)GL_DST_COLOR              =(dR, dG, dB, dA)GL_ONE_MINUS_SRC_COLOR    =(1-sR, 1-sG, 1-sB, 1-sA)GL_ONE_MINUS_DST_COLOR    =(1-dR, 1-dG, 1-dB, 1-dA)GL_SRC_ALPHA              =(sA, sA, sA, sA)GL_DST_ALPHA              =(dA, dA, dA, dA)GL_ONE_MINUS_SRC_ALPHA    =(1-sA, 1-sA, 1-sA, 1-sA)GL_ONE_MINUS_DST_ALPHA    =(1-dA, 1-dA, 1-dA, 1-dA)GL_SRC_ALPHA_SATURATE     =(i, i, i, 1 )   //i取值为min(sA, 1-dA)

混合的过程是:原色与原因子矩阵积+目标色与目标因子矩阵积
假设sfactor=(sfR, sfG, sfB, sfA), dfactor=(dfR, dfG, dfB, dfA),则计算公式为:
result=S*sfactor+D*dfactor

设最终结果色result=(rR, rG, rB, rA),则可得到最后结果为:
rR = sR * sfR + dR * dfR
rG = sG * sfG + dG * dfG
rB = sB * sfB + dB * dfB
rA = sA * sfA + dA * dfA


以上所有数组矩阵的分量取值范围都是0到1,采取的RGBA颜色是浮点形式,如果计算结果大于1则最终取值为1。

根据以上公式,
glBlendFunc(GL_ONE, GL_ONE); 即源与目标颜色的RGBA分别相加。
glBlendFunc(GL_ONE, GL_ZERO); 即只取源颜色,这也是默认值。
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 是比较典型的半透明效果,如果源色 alpha 为0,则取目标色,如果源色alpha为1,则取源色,否则视源色的alpha大小各取一部分。源色的alpha越大,则源色取的越多,最终结果源色的表现更强;源色的alpha越小,则目标色“透过”的越多。

此外在一般的渲染过程中,都会把有半透明效果的渲染放到后边,先把不透明的部分在深度测试启用的情况下渲染完, 再关闭深度测试写入(glDepthMask(false)),并渲染半透明的部分。这样就不会出现由于半透明且离镜头近的面被先渲染时污染深度缓冲了。



0 0
原创粉丝点击