【问题标题】:How can I replace a colour in texture from within my shader code?如何从我的着色器代码中替换纹理中的颜色?
【发布时间】:2012-05-31 10:49:03
【问题描述】:

我正在编写一个简单的图像查看器,用于在 Android 上的 OpenGL ES 2.0 中的几个三角形上显示图像。这些图像中有一种特定的颜色,必须以某种方式替换为黑色。问题是如果 GL_LINEAR 用于我的最小和最大化过滤器,需要替换的颜色的轮廓仍然可见。如果我将 GL_NEAREST 用于我的过滤器,着色器可以轻松替换颜色,但是它不会将图像渲染得那么平滑,并且在放大和缩小时当然看起来像素化。

我想知道是否有更好的方法来执行此类任务。我的一些想法是:

  • 构建另一个仅在纹理像素上运行一次并在我的片段着色器期间实际使用纹理之前替换颜色的着色器?
  • 重写我的着色器,使其即使在使用 GL_LINEAR 时也能正常工作。

谁能告诉我这通常是如何完成的?我宁愿在着色器中执行此操作的原因是,我可以确保遮罩像素颜色始终保持黑色。

我对 OpenGL ES 2.0 还很陌生,但我正在尝试了解它是如何工作的。请记住这一点,并帮助我学习。提前致谢。

【问题讨论】:

  • 您当前是否使用 Alpha 通道,并且可以选择编辑源图像?与颜色键控相比,使用 Alpha 通道执行此操作可能更合适。否则我想不出更好的方法,我认为你已经很好地概述了限制。
  • 在 Dalvik 中编辑源图像非常耗时,我宁愿没有这样的开销。目前代码对 alpha 通道没有任何作用,但我们显示的图像实际上是 16 位灰度,我将其编码为 RGB_565 并在着色器中解码这些位。这有点难看,但似乎有效。我们得到的最好结果似乎是在服务器上预处理我们的图像,而不是尝试在客户端上进行颜色键控。我们可能不得不求助于这个解决方案。
  • 我想我还可以补充一点,蒙版像素不会在图像中移动。他们都在同一个地方。我想我也可以尝试创建一个 alpha 纹理,并使用它来设置输出像素的 alpha?还是在这种情况下我也会看到这个大纲问题?

标签: android opengl-es-2.0


【解决方案1】:

在那种情况下(面具总是在同一个地方),我认为你有更多的选择。

我会创建一个单通道图像,其中蒙版区域为 1,未蒙版区域为 0。

然后在shader中,对原始纹理和遮罩纹理进行采样,如果遮罩值大于某个阈值,则可以用自己的遮罩颜色替换。

这在一定程度上缓解了使用 GL_LINEAR 的问题,因为您可以调整拒绝像素的值。

例如,如果您在蒙版和未蒙版像素之间进行采样,则蒙版值将为 0.5,颜色将为 (0.5*color_key + 0.5*unmasked_color)。如果您发现这种不可接受的颜色渗色,您可以将 alpha 拒绝设置为 0.1、0.001 等,以遮盖其中甚至有轻微遮罩痕迹的任何像素。这会稍微扩大您的蒙版区域,但会让您在结果中的任何地方都看不到颜色键的痕迹。

【讨论】:

  • 另外,请确保蒙版和纹理具有相同的分辨率,否则可能无法正常工作。
  • 我明白你在说什么。我今天做了一个实验来了解正在发生的采样,以及你所说的线性插值在纹理采样时返回 0.5。这可能会奏效。我会尝试看看我是否可以实现这样的东西。谢谢。
  • 我刚刚通过添加蒙版纹理对此进行了测试实现,并按照您的建议在着色器中使用它。它工作得很好。再次感谢@Tim。
猜你喜欢
  • 2021-11-13
  • 1970-01-01
  • 2016-03-06
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
相关资源
最近更新 更多