【问题标题】:OpenGL pre-multiplying alpha in GLSL gives unexpected result for DDS texturesGLSL 中的 OpenGL 预乘 alpha 为 DDS 纹理提供了意想不到的结果
【发布时间】:2012-10-30 10:43:22
【问题描述】:

我有以下情况。我在 OpenGL 渲染器上工作(OpenGL 4.2 所以没有固定的东西)。由于与我在着色器中所做的各种图像效果相关的原因,我不使用硬件混合。我有两种类型的输入纹理:

1) 带有 Alpha 通道的 PNG 24。 2)带alpha通道的DDS (DXT5)。

在片段着色器中,我在输出之前预乘了 alpha:

片段着色器:

     outputColor=texture(colorMap,interpolateAtSample(uvsOut , gl_SampleID));
      /////// PREMULTIPLY ALPHA //////////
     outputColor.a *= alpha;
     outputColor.rgb *= outputColor.a;

基于PNG的纹理工作正常:

但 DDS 看起来像这样:

你可以看到光晕+黑边。 我认为的第一件事是阿尔法乘法的问题。但后来我改变了 DDS 的纹理过滤从 GL_LINEAR 到 GL_NEAREST,它去除了光晕和黑边。 虽然这个“hack”基本上解决了这个问题,但我仍然想了解为什么 GL_LINEAR 会导致 DDS 压缩纹理出现此类问题。

差点忘了:如果我删除了预乘,它可以解决 DDS 的问题,但会为基于 PNG 的纹理创建一个问题。

更新: 在 MSAA 解析之后还有另一个通道,即混合通道。正如我所提到的,在这种情况下我不进行任何混合,但混合着色器中的输出代码如下所示:

         ///Prevent background bleeding:
         blendTex.rgb/=blendTex.a;
         //base texture is the texture under the current one.
         //This particular technique does "NORMAL" blend-just returns blendTex.
         vec4 blendedRes=blendTechnique( baseTex , blendTex) ;
         outputColor= vec4( blendedRes.rgb * blendTex.a, blendTex.a);

【问题讨论】:

  • "由于与我在着色器中执行的各种图像效果相关的原因,我不使用硬件混合。" 这将使诊断您的问题变得相当困难. 你用的是什么混合?你有一些代码吗?
  • 我没有对这个特定的例子进行混合,但只进行 alpha 预乘。文章顶部的代码块就是这样做的。另一件事我没有提到 - 我通过 MSAA在这之前。可以相关吗?
  • "我没有对这个特定的例子进行混合,但只进行 alpha 预乘。" 这不太可能,因为我可以通过四边形的模糊边区域看到部分内容。所以你正在混合某种形式。你用的是什么混合?也许你忘了关掉它?
  • 我更新了问题。我确实有一个混合通道作为第二通道。

标签: opengl glsl


【解决方案1】:

我找到了问题的根源。我的代码实际上 100% 正确。问题出在我用于测试的特定 DDS 纹理中。它已损坏。当我尝试不同的 DDS (DXT5) 时,它都可以正常工作GL_NEAREST 和 GL_LINEAR 过滤。要记住的重要细节是 DDS 默认情况下不能预乘,所以如果需要,请在 GPU 上进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多