如何获取片段的当前颜色?

Mas*_*ler 30 opengl shader glsl fragment-shader

我试图在GLSL中围绕着色器,我已经找到了一些有用的资源和教程,但是我一直在为一些应该是根本和微不足道的东西碰壁:我的片段着色器如何检索颜色目前的片段?

你可以通过说明来设置最终颜色gl_FragColor = whatever,但显然这是一个仅输出值.如何获得输入的原始颜色,以便对其进行计算?这必须在某个地方变量,但如果有人知道它的名字,他们似乎没有在我到目前为止遇到的任何教程或文档中记录它,它正在推动我的问题.

Jer*_*fin 14

片段着色器接收gl_Colorgl_SecondaryColor作为顶点属性.这也得到4个不同的变量:gl_FrontColor,gl_FrontSecondaryColor,gl_BackColor,以及gl_BackSecondaryColor它是否能写入值.如果你想直接传递原始颜色,你可以这样做:

gl_FrontColor = gl_Color;
gl_FrontSecondaryColor = gl_SecondaryColor;
gl_BackColor = gl_Color;
gl_BackSecondaryColor = gl_SecondaryColor;
Run Code Online (Sandbox Code Playgroud)

在顶点着色器之后的管道中的固定功能然后将这些功能钳位到范围[0..1],并确定顶点是正面还是背面.然后它会像往常一样插入所选的(正面或背面)颜色.然后片段着色器将接收所选择的,夹紧,内插颜色gl_Colorgl_SecondaryColor.

例如,如果您绘制标准的"死亡三角形",如:

glBegin(GL_TRIANGLES);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex3f(-1.0f, 0.0f, -1.0f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(1.0f, 0.0f, -1.0f);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex3d(0.0, -1.0, -1.0);
glEnd();
Run Code Online (Sandbox Code Playgroud)

然后像这样的顶点着色器:

void main(void) {
    gl_Position = ftransform();
    gl_FrontColor = gl_Color;
}
Run Code Online (Sandbox Code Playgroud)

使用像这样的片段着色器:

void main() {
    gl_FragColor = gl_Color;
}
Run Code Online (Sandbox Code Playgroud)

将传输颜色,就像您使用固定功能管道一样.

  • 你正在做的大多数事情都是在120版之后弃用的.事实上,不仅是警告,还有错误.也不适用于OpenGL ES 2.0(也在4.x中消失?) (26认同)

Dan*_*vil 12

如果你想进行多次渲染渲染,即如果你已经渲染到帧缓冲区并且想要使用之前渲染的第二个渲染过程,那么答案是:

  1. 将第一个渲染渲染到纹理
  2. 将此纹理绑定到第二遍
  3. 访问着色器中的私有渲染像素

3.2的着色器代码:

uniform sampler2D mytex; // texture with the previous render pass

layout(pixel_center_integer) in vec4 gl_FragCoord;
// will give the screen position of the current fragment

void main()
{
  // convert fragment position to integers
  ivec2 screenpos = ivec2(gl_FragCoord.xy);
  // look up result from previous render pass in the texture
  vec4 color = texelFetch(mytex, screenpos, 0);
  // now use the value from the previous render pass ...
}
Run Code Online (Sandbox Code Playgroud)

处理渲染图像的另一方法将是的OpenCL用OpenGL - >的OpenCL互操作.这允许更多的CPU计算.


Bah*_*bar 7

如果你所谓的"片段的当前值"是片段着色器运行之前渲染目标中的像素颜色值,那么不,它不可用.

主要原因是,在您的片段着色器运行时,可能尚未知道.片段着色器并行运行,可能(取决于哪些硬件)影响相同的像素,并且从某种FIFO读取的单独块通常负责稍后将它们合并在一起.这种合并称为"混合",并且还不是可编程管道的一部分.它是固定功能,但它确实有许多不同的方法可以将片段着色器生成的内容与像素的前一个颜色值组合在一起.


Agn*_*kas 5

您需要在当前像素坐标处采样纹理,如下所示

vec4 Pixel_color =texture2D(tex, gl_TexCoord[0].xy);

注意,正如我所见,texture2D 在 GLSL 4.00 规范中已被弃用 - 只需寻找类似的纹理...获取函数。

有时最好提供自己的像素坐标而不是 gl_TexCoord[0].xy - 在这种情况下编写顶点着色器,如下所示:

改变 vec2 texCoord;

无效主(无效)
{
   gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0 );
   texCoord = 0.5 * gl_Position.xy + vec2(0.5);     
}

在片段着色器中使用 texCoord 变量而不是 gl_TexCoord[0].xy。

祝你好运。