使用 alpha 值渲染纹理(贴花)?
Posted
技术标签:
【中文标题】使用 alpha 值渲染纹理(贴花)?【英文标题】:Render a texture (decal) with an alpha value? 【发布时间】:2019-06-26 16:24:27 【问题描述】:我尝试绘制贴花和背景两种纹理,但只有贴花的 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类型的?)
另外,我应该寻找另一种贴花的方法吗?
【问题讨论】:
rgba
不适合 vec3。
【参考方案1】:
DecalTex
应该是 vec4
,而不是 vec3
。否则阿尔法
值不会被存储。
您还必须将末尾的行更改为:color =
vec4(BGTex, 1.0) + DecalTex * DecalTex.a
目前它设置了 alpha 组件
到 0。
【讨论】:
感谢您的回答。这段代码非常直观且易于理解。【参考方案2】:DecalTex
有一个 Alpha 通道。 alpha 通道是“权重”,表示DecalTex
的强度。如果alpha通道为1,则必须使用DecalTex
的颜色,如果alpha通道为0,则必须使用BGTex
的颜色。
使用mix
混合BGTex
和DecalTex
的颜色取决于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,因此输出完全“不透明”。
【讨论】:
感谢您的详细解释。这也清楚了为什么不需要 glBlendFunc 和 glBlendEquation。以上是关于使用 alpha 值渲染纹理(贴花)?的主要内容,如果未能解决你的问题,请参考以下文章
使用相同的着色器处理 GL_RGBA 和 GL_ALPHA 纹理?
FreeType - 纹理图集 - 为什么我的文字渲染为四边形?