混合
alpha值是rgba中的a值 alpha值是决定一个颜色的透明度的值,如果alpha值为1则这个颜色完全不透明,完全显示自己的颜色,如果alpha值为0.6则显示这个颜色的百分之60并且显示其后面的颜色值百分之40
前面先说如何绘制一个透明的纹理。
我们如果直接拿到一个透明的纹理贴在一个长方体上 我们看到的往往是一片白色,因为他贴上了图,哦OpenGL并不知道怎么处理alpha值,并且不知道什么时候该丢弃完全透明的片段 他后面长方体的颜色就会显示不出来,这个时候我们应该丢弃alpha值为0的片段
uniform sampler2D texture1;
vec4 texColor = texture(texture1, TexCoords);
if(texColor.a < 0.1)
discard;
绘制半透明的片段时:
C¯result=C¯source∗Fsource+C¯destination∗Fdestination
C¯source:源颜色向量。这是源自纹理的颜色向量。
C¯destination:目标颜色向量。这是当前储存在颜色缓冲中的颜色向量。
Fsource:源因子值。指定了alpha值对源颜色的影响。
Fdestination:目标因子值。指定了alpha值对目标颜色的影响。
目标因子可以看作玻璃后面的东西 源因子可以看作玻璃 如果玻璃的阿尔法值有0.8那么就以为着玻璃上的颜色只能显示0.8 而玻璃后面的物体能显露0.2的颜色
半透明的物体从远到进画; 不透明的物体从近到远画; 先画不透明物体, 再画透明物体 这个的主要原因是半透明的物体也会被加入深度测试的话,后面的物体就不会被显示出来,导致看起里就是前面的半透明物体遮挡了后面的物体看起来很突兀 具体排序代码看混合篇
如果想大致解决这个问题我们通过顺序绘制就可以部分解决,绘制透明半透明物体时先绘制最远的物体,最后绘制最近的物体 并且先绘制所有不透明的物体。对所有透明的物体排序。按顺序绘制所有透明的物体
排序物体方法是:从观察者视角获取物体的距离。这可以通过计算摄像机位置向量和物体的位置向量之间的距离所获得。这些数据用map存储
std::map<float, glm::vec3> sorted;
for (unsigned int i = 0; i < windows.size(); i++)
{
float distance = glm::length(camera.Position - windows[i]);
sorted[distance] = windows[i];
}
for(std::map<float,glm::vec3>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); ++it)
{
model = glm::mat4();
model = glm::translate(model, it->second);
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
但是这个方法没有考虑旋转,位移缩放的矩阵变换,还有待改进
当采样纹理的边缘的时候,OpenGL会对边缘的值和纹理下一个重复的值进行插值(因为我们将它的环绕方式设置为了GL_REPEAT。这通常是没问题的,但是由于我们使用了透明值,纹理图像的顶部将会与底部边缘的纯色值进行插值。这样的结果是一个半透明的有色边框,你可能会看见它环绕着你的纹理四边形。要想避免这个,每当你alpha纹理的时候,请将纹理的环绕方式设置为GL_CLAMP_TO_EDGE:
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
函数调用:
discard;片段着色器中命令,一旦被调用,它就会保证片段不会被进一步处理
glEnable(GL_BLEND);开启混合
glBlendFunc(GLenum sfactor, GLenum dfactor);是设置源因子和目标因子的函数
参数可以是:
GL_ZERO 因子等于0
GL_ONE 因子等于1
GL_SRC_COLOR 因子等于源颜色向量C¯source
GL_ONE_MINUS_SRC_COLOR 因子等于1−C¯source
GL_DST_COLOR 因子等于目标颜色向量C¯destination
GL_ONE_MINUS_DST_COLOR 因子等于1−C¯destination
GL_SRC_ALPHA 因子等于C¯source的alpha分量
GL_ONE_MINUS_SRC_ALPHA 因子等于1− C¯source的alpha分量
GL_DST_ALPHA 因子等于C¯destination的alpha分量
GL_ONE_MINUS_DST_ALPHA 因子等于1− C¯destination的alpha分量
GL_CONSTANT_COLOR 因子等于常数颜色向量C¯constant
GL_ONE_MINUS_CONSTANT_COLOR 因子等于1−C¯constant
GL_CONSTANT_ALPHA 因子等于C¯constant的alpha分量
GL_ONE_MINUS_CONSTANT_ALPHA 因子等于1− C¯constant的alpha分量
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);为RGB和alpha通道分别设置不同的选项 (目前还不会用)
但这样只能让最终的alpha分量被源颜色向量的alpha值所影响到
glBlendEquation(GLenum mode)允许我们设置运算符
GL_FUNC_ADD:默认选项,将两个分量相加:C¯result=Src+Dst。
GL_FUNC_SUBTRACT:将两个分量相减: C¯result=Src−Dst。
GL_FUNC_REVERSE_SUBTRACT:将两个分量相减,但顺序相反:C¯result=Dst−Src。