1. 流程
OpenGL中,混合(Blending)通常是实现物体透明度(Transparency)的一种技术。透明就是说一个物体(或者其中的一部分)不是纯色(Solid Color)的,它的颜色是物体本身的颜色和它背后其它物体的颜色的不同强度结合。这在我们之前的教程中其实有过类似的功能,就是在片段着色器中对两个纹理的颜色进行mix,使得最终呈现出来的颜色是两个纹理不同程度的混合:

而这次我们可以用一种更通用的方法,那就是alpha测试
1.1 Alpha测试
在我们读取图片的时候,有的图片数据除了RGB通道之外,还包含了Alpha通道,我们生成该纹理的时候可以设置为GL_RGBA来读取:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
有了这个Alpha参数,我们可以怎么用呢?
同样看到之前混合纹理时用的片段着色器:
FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), visibility);
我们使用了一个mix函数,使得两个纹理根据一个0-1之间的值visibility来分别设定它们的可见度,而这个visibility其实就可以看作我们读取的Alpha值,为0时原图片完全透明(着色时不使用它的颜色),为1时原图片完全不透明(着色时完全使用它的颜色)
现在我们想要实现一种效果,我们要在游戏场景中渲染一块草地,只用一个贴图,如下图:

直接将它渲染在场景中可能会是这样:

这是因为空白部分的纯色纹理也被渲染出来了,现在我们只要这个图片中草的片段被渲染出来怎么办?
这时候就要用到之前读取的图片alpha值了,在读取的时候,空白部分的alpha值被设定为0,我们可以在片段着色器里这样设置:
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D texture1;
void main()
{
vec4 texColor = texture(texture1, TexCoords);
if(texColor.a < 0.1)
discard;
FragColor = texColor;
}
没错,GLSL提供了一个discard功能,在我们读取纹理值,发现它的alpha值小于0.1时,我们就调用discard丢弃这个片段而不着色,这样就能够只渲染草片段的纹理了:

这只是一种简单的应用,实际应用时,我们还更可能碰到一种情况,就是在渲染半透明物体时可能需要将物体本身的纹理与背景的颜色混合,而使用mix函数肯定无法完成这种较为复杂的操作,这时候就不得不提到OpenGL的另一个功能了
1.2 混合测试
在OpenGL中,也提供了一种类似于mix的方法,那就是混合(Blend)

OpenGL透明度与混合技术详解:Alpha测试与混合

本文介绍了如何在OpenGL中使用Alpha测试和混合技术实现物体透明度,包括Alpha测试的基本原理、混合测试的设置、半透明效果的渲染,以及深度测试、模板测试等配合,以实现复杂透明效果和场景渲染。
最低0.47元/天 解锁文章
582

被折叠的 条评论
为什么被折叠?



