原来一直以为,只有当前颜色alpha<0时,使用src alpha才会将图半透明的画到已有的内容上,今天试验gles的point sprite时发现,我使用一张24bit的粒子纹理图,不带alpha通道,中心亮边缘渐黑
使用的混合函数为glBlendFunc( GL_SRC_ALPHA, GL_ONE );也有类似alpha通道的效果。
复习一下blend的公式:
源颜色是(Rs,Gs,Bs,As),源混合因子是(Sr,Sg,Sb,Sa),目的颜色是(Rd,Gd,Bd,Ad),目的混合因子是(Dr,Dg,Db,Da),而默认的混合计算是加法
那么最终混合后的片段颜色是 (RsSr+RdDr, GsSg+GdDg, BsSb+BdDb, AsSa+AdDa)
GL_SRC_ALPHA代表的RGBA混合因子是(As,As,As,As),因为我这张纹理是24bitRGB的,没有alpha通道,所以As=1
GL_ONE的代表RGBA混合因子是(1,1,1,1)
带入上面的公式就是:
(Rs+Rd, Gs+Gd, Bs+Bd, Gs+Gd, As+Ad)
也就是直接将源颜色加到已有的颜色上,因为我的粒子纹理图是中心亮边缘渐变黑色的,而黑色就是0,所以黑的地方最终的颜色就是已有的颜色,亮一点的地方就是将灰色加到已有颜色上会让颜色更饱和,所以渐变黑色就形成了类似alpha通道的效果。
然后我又将纹理环境模式设置成GL_MODULATE,并且在画粒子时指定一个颜色,这样彩色的颜色被乘到纹理颜色上,最终纹理的效果是彩色的,再加到背景上就变成彩色粒子,这个效果和直接在图上设定alpha通道和颜色还是有区别的,不过这种效果更适合粒子系统。
下 图是蓝色背景上画彩色粒子,由于使用这种混合方式,可以透过粒子看到部分蓝色背景,如果使用glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );那么就看不到背景了,因为粒子纹理上是没有alpha通道的(alpha===1)。
(ps:irrlicht的transparent add color材质渲染器就是用这种方式混合的)