使用 alpha 值渲染纹理(贴花)?
Render a texture (decal) with an alpha value?
我尝试绘制贴花和背景两种纹理,但只有贴花的 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);
我可以正常画画,但有以下问题。
-贴花的alpha部分不能透明。
这个问题可以在片段着色器中解决吗?
那么,我该如何重写代码呢?
纹理是DDS,其中一个是DXT1类型(背景。因为这个纹理不需要alpha),另一个是DXT3类型(贴花)。也是这个原因吗?(都需要是DXT3类型?)
此外,我是否应该寻找另一种贴花的方法?
DecalTex
应该是 vec4
,而不是 vec3
。否则阿尔法
不会存储值。
您还必须将末尾的行更改为:color =
vec4(BGTex, 1.0) + DecalTex * DecalTex.a
目前它设置了 alpha 组件
到 0.
DecalTex
有一个 alpha 通道。 Alpha 通道为 "weight",表示 DecalTex
的强度。如果alpha通道为1,则必须使用DecalTex
的颜色,如果alpha通道为0,则必须使用BGTex
的颜色。
根据 DecalTex
的 Alpha 通道,使用 mix
混合 BGTex
和 DecalTex
的颜色。当然 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 应用于片段着色器输出和帧缓冲区中的当前值。
您根本不需要任何混合,因为片段着色器中的纹理是 "blended" 并且结果放在帧缓冲区中。由于片段着色器输出的alpha通道>=1.0,所以输出完全是"opaque"。
我尝试绘制贴花和背景两种纹理,但只有贴花的 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);
我可以正常画画,但有以下问题。 -贴花的alpha部分不能透明。
这个问题可以在片段着色器中解决吗? 那么,我该如何重写代码呢?
纹理是DDS,其中一个是DXT1类型(背景。因为这个纹理不需要alpha),另一个是DXT3类型(贴花)。也是这个原因吗?(都需要是DXT3类型?)
此外,我是否应该寻找另一种贴花的方法?
DecalTex
应该是vec4
,而不是vec3
。否则阿尔法 不会存储值。您还必须将末尾的行更改为:
color = vec4(BGTex, 1.0) + DecalTex * DecalTex.a
目前它设置了 alpha 组件 到 0.
DecalTex
有一个 alpha 通道。 Alpha 通道为 "weight",表示 DecalTex
的强度。如果alpha通道为1,则必须使用DecalTex
的颜色,如果alpha通道为0,则必须使用BGTex
的颜色。
根据 DecalTex
的 Alpha 通道,使用 mix
混合 BGTex
和 DecalTex
的颜色。当然 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 应用于片段着色器输出和帧缓冲区中的当前值。
您根本不需要任何混合,因为片段着色器中的纹理是 "blended" 并且结果放在帧缓冲区中。由于片段着色器输出的alpha通道>=1.0,所以输出完全是"opaque"。