在OpenGL中更改纹理不透明度

问题描述 投票:12回答:8

希望这是个简单的问题。我有一个OpenGL纹理,想改变它的不透明度,我该怎么做?纹理已经有一个alpha通道,混合效果也很好,但我希望能够降低整个纹理的不透明度,使其淡入背景。我已经用 glBlendFunc但运气不佳--似乎我需要一些类似于 GL_SRC_ALPHA_MINUS_CONSTANT,这是不可用的。我在iPhone上工作,使用OpenGL ES。

iphone opengl-es
8个回答
17
投票

我对OpenGL ES不了解,但在标准OpenGL中,您可以在使用纹理之前通过声明纹理的颜色来设置不透明度。

//          R,   G,   B,   A
glColor4f(1.0, 1.0, 1.0, 0.5);

这个例子可以给你50%的alpha,而不影响纹理的颜色。通过调整其他数值,您也可以改变纹理的颜色。


8
投票

使用纹理组合器。将纹理阶段设置为做 GL_MODULATE 纹理和常数颜色之间的操作。然后改变你的代码中的恒定颜色(glTexEnv, GL_TEXTURE_ENV_COLOR).

这在性能上应该是 "免费 "的。在大多数(如果不是所有)图形芯片上,组合器操作需要相同数量的GPU周期(通常是1),所以仅仅使用一个纹理与进行调制操作(或任何其他操作)是完全相同的成本。


2
投票

谢谢大家的想法。我同时玩了glColor4f和glTexEnv,最后强迫自己仔细阅读了glTexEnv的manpage。手册上说,在GL_MODULATE纹理模式下,生成的颜色是通过将输入的片段乘以纹理颜色(C=Cf×Ct)来计算的,alpha也是如此。我试过glColor4f(1, 1, 1, opacity),但没有成功,但将所需的不透明度传递到调用的所有四个参数中就成功了。(不过还是不知道为什么。)


2
投票

基本上你有两个选择:用GL_MODULATE为你的纹理使用glTexEnv,用glColor4*指定颜色,并为alpha通道使用非不透明级别。请注意,glTexEnv应该只发出一次,当你第一次加载你的纹理时。但如果你在顶点属性中指定颜色,这种情况将不起作用。这些颜色将即覆盖你可能设置的任何glColor4*颜色。在这种情况下,你可能会想使用2个选项中的一个:使用纹理组合器(高级主题,在固定管道中不适合使用),或者 "手动 "改变每个单独顶点的顶点颜色属性(对于较大的网格来说可能不可取)。


1
投票

最直接的方法是在飞行中改变纹理的alpha值。由于您在某些时候告诉OpenGL关于纹理的信息,您将在内存中拥有该位图。所以只需将纹理重新绑定到同一个纹理id上即可。如果你的内存中没有它(由于空间限制,因为你是在ES上),你可以再次将纹理检索到一个缓冲区,使用 glGetTexImage(). 这是干净的解决方案。

不过,保存重取操作的成本有点高,所以你可能需要另一种解决方案。考虑到这一点,你也许可以在显示纹理的几何体后面的几何体上工作,或者干脆在持有纹理的几何体的材质颜色上工作。你可能会想要对后面的几何体进行一些加法混合。使用下面的glBlendFunc

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA),

你也许可以 "轻松 "地,更重要的是,以较低的成本达到所需的效果。


1
投票

最有可能的是,你正在使用cg来将你的图像转化为纹理。当您使用cg时,alpha是预先乘以的,因此您必须使用color4f func的rgba的alpha。


1
投票

如果你使用的是现代OpenGL...

你可以在fragment shader中这样做。

void main()
{
     color = vec4(1.0f, 1.0f, 1.0f, OPACITY) * texture(u_Texture, TexCoord);
}

这允许你在不影响混合的情况下对纹理应用一个不透明度值。


0
投票

我怀疑你的背景是黑色的,因此通过减少每一种颜色的数量,你有效地将颜色淡化为黑色。

© www.soinside.com 2019 - 2024. All rights reserved.