【问题标题】:openGL Translating pixel brightness to colormap texture produces incorrect resultopenGL 将像素亮度转换为颜色图纹理会产生不正确的结果
【发布时间】:2017-03-23 18:36:00
【问题描述】:

查看 RGB 和颜色图之间的 gif 切换:


问题在于两张图片不同。

我正在绘制 RGB 白色 (1.0,1.0,1.0) 的点。 Alpha 通道控制像素亮度,从而创建点模糊。这就是你看到的更亮的图像。然后我有一个黑白 (0.0,0.0,0.0,1.0) (1.0,1.0,1.0,1.0) 的 2 像素纹理,在片段着色器中我做了:

#version 330

precision highp float;

uniform sampler2D originalColor;
uniform sampler1D colorMap;
in vec2 uv;
out vec4 color;

void main()
{
  vec4 oldColor = texture(originalColor, uv);
  color = texture(colorMap, oldColor.a);
}

非常简单,将 originalColor 纹理的 alpha 值从 0 变为 1 的片段,并将其转换为 colorMap 纹理为黑色到白色的新颜色。 两张图片应该没有区别!或者……至少,这是我的目标。

这是我对颜色图纹理的设置

  glActiveTexture(GL_TEXTURE0);
  glGenTextures(1, &colormap_texture_id); // get texture id
  glBindTexture(GL_TEXTURE_1D, colormap_texture_id);
  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // required: stop texture wrapping
  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // required: scale texture with linear sampling
  glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, colormapColors.size(), 0, GL_RGBA, GL_FLOAT, colormapColors.data()); // setup memory   

渲染循环:

  GLuint textures[] = { textureIDs[currentTexture], colormap_texture_id };
  glBindTextures(0, 2, textures);

  colormapShader->use();
  colormapShader->setUniform("originalColor", 0);
  colormapShader->setUniform("colorMap", 1);
  renderFullScreenQuad(colormapShader, "position", "texCoord");

我使用 1D 纹理作为颜色图,因为这似乎是可能在 GPU 内存中存储 1000 到 2000 个颜色图值索引的唯一方法。如果有更好的方法,请告诉我。我认为问题在于在两个像素之间进行插值的数学不适合我的目的。

我应该怎么做才能获得预期的结果?

为了确保没有恶作剧,我尝试遵循着色器代码:

color = texture(colorMap, oldColor.a); //incorrect results
color = texture(colorMap, (oldColor.r + oldColor.g + oldColor.b)/3); //incorrect
color = texture(colorMap, (oldColor.r + oldColor.g + oldColor.b + oldColor.a)/4); //incorrect
color = vec4(oldColor.a); //incorrect
color = oldColor; // CORRECT... obviously...

【问题讨论】:

  • 您的图片链接给了我一个“未找到”页面
  • 颜色图是否连续(例如渐变)?如果不是,GL_LINEAR 没有意义。
  • 颜色图是 2 个像素,不确定它有多“连续”。图片链接已修复

标签: opengl textures color-mapping


【解决方案1】:

我认为更准确地说,您需要进行更改:

color = texture(colorMap, oldColor.a);

color = texture(colorMap, oldColor.a * 0.5 + 0.25);

或者更一般的

color = texture(colorMap, oldColor.a * (1.0 - (1.0 / texWidth)) + (0.5 / texWidth));

通常,您不会注意到错误,这只是因为 texWidth 太小以至于差异很大。

这是因为纹理只会在您通过第一个 texel 的中心(在 2 texel 宽的纹理中为 0.25)后才开始从黑色到白色的线性过滤。一旦通过最后一个纹素的中心(0.75),插值就完成了。

如果您有一个像您提到的那样的 1024 纹理,那么您计划结束时插值从 0.000488 开始,我怀疑您会注意到错误。

【讨论】:

  • 是的!谢谢!看起来我还是有整体亮度不一样的问题,但至少现在只是亮度问题,不是插值问题。任意增加像素亮度可以解决这个问题。将不得不进一步调查。
  • f*** hmm...实际上问题仍然没有通过改变亮度来解决,问题肯定存在于其他地方。我对它可能是什么有一个想法,我会在可能的时候回到这个问题上。 (虽然这个答案让我更接近预期的结果)
  • 除非您小心,否则您的 Alpha 通道可能不包含您认为它包含的内容。如果您使用标准 alpha 混合渲染具有 0.5 alpha 的纹素,则帧缓冲区将不包含 0.5,它将包含 0.25。可能最简单的解决方法就是使用 color = texture(colorMap, oldColor.r * 0.5 + 0.25);。否则你需要小心地改变你的 alpha 混合函数,以便它能够正确累积,这可以做到但有点繁琐。
  • 是的,你是对的!我刚刚修好了!我回到堆栈让您知道,然后阅读您准确描述问题的评论。我基本上只是将olColor.a * etc. 切换到oldColor.r * etc. 本质上是因为我在绘制白色,我可以使用任何通道,只是不能使用 alpha 通道,因为就像你说的那样,alpha 通道没有像我想的那样被存储。它正在根据 alpha 调整 RGB。
猜你喜欢
  • 2021-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多