使用相同的着色器处理 GL_RGBA 和 GL_ALPHA 纹理?
Posted
技术标签:
【中文标题】使用相同的着色器处理 GL_RGBA 和 GL_ALPHA 纹理?【英文标题】:Handling GL_RGBA and GL_ALPHA textures with the same shader? 【发布时间】:2012-10-28 15:35:49 【问题描述】:所以我的应用程序主要使用 rgba 纹理进行渲染,但在少数情况下,我会使用 alpha 蒙版来渲染文本。
我希望我的片段着色器的输出是给定坐标处纹理采样器的值乘以我传入的颜色均匀度。问题是我找不到一个简单的解决方案来处理这两种情况.
所以对于 rgba 纹理,这给出了想要的结果:
gl_FragColor = texture2D(diffuseTexture, varTexcoord.st, 0.0) * color;
但是对于 alpha 纹理,输出总是黑色的。我假设纹理采样器将 alpha 纹理的每个像素视为:rgba(0, 0, 0, alpha),并且我希望它被视为 rgba(1, 1, 1, alpha)。我可以通过以下方式在 alpha 纹理上获得所需的结果:
gl_FragColor = texture2D(diffuseTexture, varTexcoord.st, 0.0).w * color;
但显然这会破坏 rgba 纹理。
我是 GLSL 的新手,我想知道是否有处理这两种情况的好方法,或者我是否必须拥有 2 个不同的着色器,或者将我所有的 aplha 纹理转换为 rgba。
编辑:
我想我最终会在加载资源时将我的 alpha 纹理重新打包为 GL_LUMINANCE_ALPHA 纹理。
【问题讨论】:
您的假设是正确的,GL_ALPHA 映射到 RGBA 为 R=0, G=0, B=0, A=A 您使用的是桌面 OpenGL 还是 OpenGL ES? .w 语义不正确。 【参考方案1】:您有两种不同的方式来处理数据。所以你有两个不同的着色器。切换它们。着色器反映将要发生的事情。
如果您对 glTexEnv、照明等的每个设置使用旧的、已弃用的固定功能管道,则会在原地创建特定的着色器。
切换着色器就像调用 glUseProgramm 一样简单
【讨论】:
真的,这是处理数据的一种方式。数据在功能上是相同的;唯一的区别是某些数据的格式不完全正确。这就是 desktop OpenGL 具有 texture swizzling 的原因,因此您可以在不涉及着色器的情况下处理此类较小的格式问题。 @NicolBolas:在那种简单的情况下是的,但是如果有两个着色器以非常不同的方式处理通道呢? 那么他就不会要求单着色器解决方案了。他的特定问题是他想要一个单着色器解决方案,因为着色器代码是相同的。数学的唯一问题是来自 alpha 纹理的 RGB 分量。他不是在寻找将着色器代码填充到纹理提取或其他东西中的通用解决方案。他正在寻找一种解决方案来解决这种获取 0 而不是 1 的特定情况。 Swizzle Masks 的存在就是为了解决这个确切的问题,这个问题发生的频率可能比你想象的要多。 @NicolBolas:哦,我知道他们很多。我自己在很多程序中都使用 swizzle mask。然而我经常观察到人们对他们的问题做出假设,强迫自己进入一个相当奇怪的心理模型,而更容易和更好的解决方案就在他们面前。请记住,OpenGL 实现可以通过原位着色器重新编译来实现 swizzle 掩码。因此,应用 swizzle 蒙版可能对性能产生与切换着色器相同的影响。 "因此,应用 swizzle 蒙版可能对性能产生与切换着色器相同的影响。" 不太可能。用户更改程序状态也意味着更改存储在程序中的 uniform 状态,因为您正在切换程序。修改着色器的驱动程序不必这样做。它可以上传一组稍微不同的着色器数据,仅此而已。因此,即使它确实进行了原位修改,它也不需要做用户必须做的事情来完成工作。以上是关于使用相同的着色器处理 GL_RGBA 和 GL_ALPHA 纹理?的主要内容,如果未能解决你的问题,请参考以下文章
在 glTexImage2D() 中指定 GL_RGBA32F 时输出奇怪