一方面,您正在使用 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
变量。
现在真正的问题是你似乎想要改变你采样的纹理的颜色。那是行不通的,充其量你将不得不使用两个片段数据输出。可以在一些非常受控的情况下写入您从中采样的相同纹理,但通常您会做的是纹理之间的乒乓球。换句话说,您将从一个纹理中获取,写入另一个纹理,并且引用原始纹理的所有后续渲染通道应该与您刚刚写入的那个交换。
有关多渲染目标绘图的更多信息,请参见“片段数据位置” 。