user2673108
user2673108

Reputation: 309

Changing color of fragment

I have written a fragment shader which i would like to change the color of the fragment. for example I would like if the color it receives is black then it should change it to a blue.

This is the shader that I am using:

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);
}

And here is the log that I am getting from it:

WARNING: -1:65535: 'GL_ARB_explicit_attrib_location' : extension is not available in current GLSL version

WARNING: 0:1: 'texelFetch' : function is not available in current GLSL version

I am aware of the warning- but shouldn't it compile anyways? The shader is not doing what i would like it to do, can someone explain why?

Upvotes: 0

Views: 549

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43319

For one thing, you are using functions that are not available in your GLSL implementation. The result of calling these will be undefined.

However, the kicker here is that gl_FragColor has absolutely NOTHING to do with the value of color in this shader. So even if your texelFetch (...) logic actually did work correctly, changing the value of color does nothing to the final output. A smart compiler will see this as a no-op and effectively strip your shader down to this:


uniform sampler2D texture1;

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


If that were not enough, texelFetch (...) is completely unnecessary in this shader. If you want to lookup the texel that corresponds to the current fragment in your shader and the texture has the same dimensions as the viewport you are drawing into you can actually use texture2D (texture1, gl_FragCoord.xy); This is because the default behaviour in GLSL is to have gl_FragCoord supply the coordinate of the fragment's center (x+0.5, y+0.5) - this is also the center of the corresponding texel in your texture (if it is the same resolution), so you can do a traditional texture lookup without worrying that texture filtering will alter your sampled result.

texelFetch (...) lets you fetch an explicit texel in a texture without using normalized coordinates, it is sort of like a "grownup" rectangle texture :) It is generally useful if you are using a multisample texture and want a specific sample, or if you want to bypass texture filtering (which includes mipmap level selection). In this case, it is not needed at all.

This is probably what you really want (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);
}

In older GLSL versions, you will have to use glBindFragDataLocation (...) and set the data locations manually or use gl_FragData[n] instead of out variables.

Now the real problem here is that you seem to be wanting to change the color of the texture you are sampling from. That will not work, at best you will have to use two fragment data outputs. Writing into the same texture you are sampling from can be done under some very controlled circumstances, but generally what you would do is ping-pong between textures. In other words, you would fetch from one texture, write to another texture and all subsequent render passes that reference to the original texture should be swapped with the one you just wrote to.

See "Fragment Data Location" for more information on Multiple Render Target drawing.

Upvotes: 1

Related Questions