渲染具有alpha值的纹理(贴花)?

时间:2019-06-26 16:24:27

标签: c++ opengl glsl shader blending

我试图绘制贴花和背景的两种纹理,但是只有贴花的Alpha部分变为白色。

我只是尝试了以下方法。

  • 绘制2个纹理(背景和贴花)
  • 添加glBlendFunc以应用贴图alpha值
#version 330 core

in vec2 UV;

out vec3 color;

uniform sampler2D background;

in      vec3      decalCoord;
uniform sampler2D decal;

void main(){

    vec3 BGTex     = texture( background, UV ).rgb;
    vec3 DecalTex  = texture(decal, decalCoord.xy).rgba;

    color = 
    vec4(BGTex,1.0) +   // Background texture is DDS DXT1 (I wonder if DXT1 is the cause?)
    vec4(DecalTex,0.0); // Decal texture is DDS DXT3 for alpha

}
// Set below...
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);

enter image description here

我能够正常绘制,但是存在以下问题。 -贴花的Alpha部分无法设为透明。

这是可以在fragmenthader中解决的问题吗? 在那种情况下,我应该如何重写代码?

纹理是DDS,其中一种是DXT1类型(背景。因为该纹理不需要alpha),而另一种是DXT3类型(贴花)。这也是原因吗?(都需要是DXT3类型吗?)

另外,我是否应该寻找另一种贴花的方法?

2 个答案:

答案 0 :(得分:2)

  1. DecalTex应该是vec4,而不是vec3。否则alpha 值将不会存储。

  2. 您还必须将最后一行更改为:color = vec4(BGTex, 1.0) + DecalTex * DecalTex.a当前,它设置了alpha分量 到0。

答案 1 :(得分:2)

DecalTex有一个Alpha通道。 Alpha通道为“权重”,表示DecalTex的强度。如果Alpha通道为1,则必须使用DecalTex的颜色,如果Alpha通道为0,则必须使用BGTex的颜色。
使用mix来混合BGTexDecalTex的颜色,具体取决于DecalTex的alpha通道。当然,DecalTex的类型必须为vec4

vec3 BGTex     = texture( background, UV ).rgb;
vec4 DecalTex  = texture(decal, decalCoord.xy).rgba;

color = vec4(mix(BGTex.rgb, DecalTex.rgb, DecalTex.a), 1.0);

请注意,mix线性插值在两个值之间:

mix(x, y, a) = x * (1−a) + y * a

这类似于由混合函数和方程式执行的操作:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);

但是Blending应用于片段着色器的输出以及帧缓冲区中的当前值。
您根本不需要任何混合,因为纹理在片段着色器中被“混合”,并且结果被放入帧缓冲区。由于片段着色器输出的Alpha通道> = 1.0,因此输出完全“不透明”。