0

我写了一个片段着色器,我想改变片段的颜色。例如,我想如果它收到的颜色是黑色,那么它应该将其更改为蓝色。

这是我正在使用的着色器:

uniform sampler2D mytex;

layout (pixel_center_integer) in vec4 gl_FragCoord;

uniform sampler2D texture1;

void main ()
{
    ivec2 screenpos = ivec2      (gl_FragCoord.xy);
    vec4  color     = texelFetch (mytex, screenpos, 0);

    if (color == vec4 (0.0,0.0,0.0,1.0)) {
        color = (0.0,0.0,0.0,0.0);
    }

    gl_FragColor = texture2D (texture1, gl_TexCoord[0].st);
}

这是我从中得到的日志:

警告:-1:65535:'GL_ARB_explicit_attrib_location':扩展在当前 GLSL 版本中不可用

警告:0:1:“texelFetch”:当前 GLSL 版本中没有该功能

我知道警告 - 但它不应该编译吗?着色器没有做我想做的事情,有人可以解释为什么吗?

4

1 回答 1

1

一方面,您正在使用 GLSL 实现中不可用的功能。调用这些的结果将是未定义的。

然而,这里的关键是与这个着色器中gl_FragColor的值完全无关。color因此,即使您的texelFetch (...)逻辑确实可以正常工作,更改 的值color也不会影响最终输出。智能编译器会将其视为无操作,并有效地将您的着色器剥离为:


uniform sampler2D texture1;

void main ()
{
  gl_FragColor = texture2D (texture1, gl_TexCoord[0].st);
}


如果这还不够,texelFetch (...)则在此着色器中完全没有必要。如果您想在着色器中查找与当前片段对应的纹素,并且纹理与您正在绘制的视口具有相同的尺寸,您可以实际使用texture2D (texture1, gl_FragCoord.xy);这是因为 GLSL 中的默认行为是gl_FragCoord提供坐标片段的中心 (x+0.5, y+0.5) - 这也是纹理中相应纹素的中心(如果分辨率相同),因此您可以进行传统的纹理查找,而不必担心纹理过滤会改变您的采样结果。

texelFetch (...)允许您在不使用归一化坐标的情况下获取纹理中的显式纹素,它有点像“长大”的矩形纹理 :) 如果您使用多样本纹理并想要特定样本,或者如果您想绕过它,它通常很有用纹理过滤(包括 mipmap 级别选择)。在这种情况下,根本不需要它。

这可能是您真正想要的(OpenGL 3.2):


#version 150

uniform sampler2D mytex;
uniform sampler2D texture1;

layout (location=0) out vec4 frag_color;
layout (location=1) out vec4 mytex_color;

void main ()
{
  mytex_color = texture2D (mytex, gl_FragCoord.xy);

  // This is not black->blue like you explained in your question...
  //   ... This is generally opaque->transparent, assuming 4th component = alpha
  if (mytex_color == vec4 (0.0,0.0,0.0,1.0)) {
    mytex_color = vec4 (0.0);
  }

  frag_color = texture2D (texture1, gl_TexCoord[0].st);
}

在较旧的 GLSL 版本中,您将不得不glBindFragDataLocation (...)手动使用和设置数据位置或使用gl_FragData[n]而不是out变量。

现在真正的问题是你似乎想要改变你采样的纹理的颜色。那是行不通的,充其量你将不得不使用两个片段数据输出。可以在一些非常受控的情况下写入您从中采样的相同纹理,但通常您会做的是纹理之间的乒乓球。换句话说,您将从一个纹理中获取,写入另一个纹理,并且引用原始纹理的所有后续渲染通道应该与您刚刚写入的那个交换。

有关多渲染目标绘图的更多信息,请参见“片段数据位置” 。

于 2013-08-14T19:10:37.830 回答