4
\$\begingroup\$

How would I "highlight" faces/edges/corners? I would prefer an explanation OpenGL if possible.

Here's an example:

enter image description here

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Depending on your skill level, solid wireframes may be an option.

(Image borrowed from the linked NVIDIA paper) enter image description here

NVIDIA's example images show highlighting edges of triangles, but that's something you can work around.

You can use a geometry shader to generate barycentric coordinates, and then check them in your fragment shader to determine distance of a fragment from an edge.

If the distance falls below some threshold, set your fragment color to the desired "wire" color, and return. Otherwise, shade as normal.

Another option is to render your model filled, then render it again as wireframe with depth test disabled. However, unlike solid wireframes, this requires a second pass, and just feels inelegant. Also, rendering in wireframe mode is significantly slower than rendering filled primitives.

Or, you could just render with a texture that has a nice border, but that'll look like crap unless you tweak your texture coordinates in the pixel / fragment shader.

Here's a snippet from one of my geometry shaders that does the brunt of the work:

void EmitTriangle(vec3 v0, vec3 v1, vec3 v2)
{
    // float a[5] = float[](3.4, 4.2, 5.0, 5.2, 1.1);
    vec3 verts[] = vec3[]( v0, v1, v2 );

    for (int i = 0; i < 3; ++i)
    {
        vec4 p = vec4(verts[i], 1);

        gl_Position = Projection * View * World * p;
        gOut.ObjectPosition = p;
        gOut.WorldPosition = World * p;
        gOut.Color = vec4(1, 0, 1, 1);
        gOut.BaryPosition = vec3(i == 0, i == 1, i == 2);
        //gOut.BaryPosition.rgb = vec3(1.0f);



        EmitVertex();
    }

    EndPrimitive();
}

and a snippet associated fragment shader:

const float wireDistance = 0.05f;

/// check interpolated BaryPosition to determine distance to edge.
bool showWire = (gOut.BaryPosition.x < wireDistance
                || gOut.BaryPosition.y < wireDistance
                || gOut.BaryPosition.z < wireDistance)
                ;

if (showWire) { // return the desired wire color }

You can probably replace the '||' triplet with any(gOut.BaryPosition < wireDistance), but I don't have time to try it and remember the shader compiler being a bit persnickety about that one.

\$\endgroup\$
1
  • \$\begingroup\$ thank you very much, i understand how all of this works now! \$\endgroup\$
    – Type 10
    Commented Sep 24, 2016 at 7:37

You must log in to answer this question.

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