Question

In OpenGL 2.1, we could create a post-processing effect by rendering to a FBO using a fullscreen quad. OpenGL 3.1 removes GL_QUADS, so we have to emulate this using two triangles instead.

Unfortunately, I am getting a strange issue when trying to apply this technique: a diagonal line appears in the hypotenuse of the two triangles!

This screenshot demonstrates the issue:

  Screenshot

I did not have a diagonal line in OpenGL 2.1 using GL_QUADS - it appeared in OpenGL 3.x core when I switched to GL_TRIANGLES. Unfortunately, most tutorials online suggest using two triangles and none of them show this issue.

// Fragment shader
#version 140
precision highp float;

uniform sampler2D ColorTexture;
uniform vec2 SampleDistance;

in vec4 TextureCoordinates0;
out vec4 FragData;

#define NORM (1.0 / (1.0 + 2.0 * (0.95894917 + 0.989575414)))
//const float w0 = 0.845633832 * NORM;
//const float w1 = 0.909997233 * NORM;
const float w2 = 0.95894917 * NORM;
const float w3 = 0.989575414 * NORM;
const float w4 = 1 * NORM;
const float w5 = 0.989575414 * NORM;
const float w6 = 0.95894917 * NORM;
//const float w7 = 0.909997233 * NORM;
//const float w8 = 0.845633832 * NORM;

void main(void)
{
    FragData = 
        texture(ColorTexture, TextureCoordinates0.st - 2.0 * SampleDistance) * w2 +
        texture(ColorTexture, TextureCoordinates0.st - SampleDistance) * w3+
        texture(ColorTexture, TextureCoordinates0.st) * w4 +
        texture(ColorTexture, TextureCoordinates0.st + SampleDistance) * w5 +
        texture(ColorTexture, TextureCoordinates0.st + 2.0 * SampleDistance) * w6
    ;
}

// Vertex shader
#version 140
precision highp float;

uniform mat4 ModelviewProjection; // loaded with orthographic projection (-1,-1):(1,1)
uniform mat4 TextureMatrix;       // loaded with identity matrix
in vec3 Position;
in vec2 TexCoord;

out vec4 TextureCoordinates0;

void main(void)
{
    gl_Position = ModelviewProjection * vec4(Position, 1.0);
    TextureCoordinates0 = (TextureMatrix * vec4(TexCoord, 0.0, 0.0));
}

What am I doing wrong? Is there a suggested way to perform a fullscreen post-processing effect in OpenGL 3.x/4.x core?

Was it helpful?

Solution

Reto Koradi is correct and I suspect that is what I meant when I wrote my original comment; I honestly do not remember this question.

You absolutely have to swap 2 of the vertex indices to draw a strip instead of a quad or you wind up with a smaller triangle cut out of part of the quad.

ASCII art showing difference between primitives generated in 0,1,2,3 order:

GL_QUADS   GL_TRIANGLE_STRIP   GL_TRIANGLE_FAN

  0-3             0 3               0-3
  | |             |X|               |\|
  1-2             1-2               1-2

                  0-2
                  |/|
                  1-3

As for why this may produce better results than two triangles using 6 different vertices, floating-point variance may be to blame. Indexed rendering in general will usually solve this, but using a primitive type like GL_TRIANGLE_STRIP requires 2 fewer indices to draw a quad as two triangles.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top