I'm trying to render a quad with a coloured border. I'm using texture coordinates to detect whether the fragment should be considered part of border or not. If it is part of border, then render it with green colour or else with black colour.

Here are my vertices / normals / tex coordinates.

    float vertices[] = {
        // posistions          // normals           // texture coords
      -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,
       0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  0.0f,
       0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,
       0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,
      -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  1.0f,
      -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,

Here's my fragment shader

#version 330 core

in vec3 frag_pos;
in vec3 frag_nor;
in vec2 frag_tex;

out vec4 frag_color;

void main()
    vec2 origin = vec2(0.01, 0.01);

    float width =  1.0 - origin.x * 2.0;
    float height = 1.0 - origin.y * 2.0;

    if( (frag_tex.x >= origin.x && frag_tex.x < origin.x + width) &&
        (frag_tex.y >= origin.y && frag_tex.y < origin.y + height) )
        frag_color = vec4(0.0);
        frag_color = vec4(0.0, 1.0, 0.0, 0.0);

And this is how I'm rendering

glDrawArrays(GL_TRIANGLES, 0, 6);

enter image description here

In right, I'm drawing the same quad with another pass-through fragment shader in wireframe mode.

As you can see the left quad is flickering while moving the camera. Any ideas how to fix this.


1 Answer 1


I think your problem is that your border checking is too exact. You should use an epsilon value, which looks like, rather than saying x = 0, abs(x) < EPSILON. In your case, that would look like

  abs(frag_tex.x - origin.x) >= EPSILON && 
  abs(frag_tex.x - origin.x - width) < EPSILON) && 
  abs(frag_tex.y - origin.y) >= EPSILON && 
  abs(frag_tex.y - origin.y - height) < EPSILON

(Unless I've made a typo. I would advise retyping this in an IDE to avoid a potentially missing parenthesis or something).

Then, at the top of the shader, just add the line float EPSILON = 0.1;. Now EPSILON controls how thick the borders are! If they're too big, just make EPSILON smaller.

  • 1
    \$\begingroup\$ You can also use screenspace derivatives to dynamically adjust your threshold to the size/orientation of the object on screen. \$\endgroup\$
    – DMGregory
    Feb 23, 2019 at 22:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .