0

I am currently working on a project using OpenGL-ES 3.0 for Android. In my project, I have drawn a 3d human head, whose centroid lies at the origin. I also have a cylinder, with the center of one of its faces lying on the origin. The cylinder extends out longer than the length of the head. In other words, I have a cylinder running through the head.

Right now, I am just using the default depth test (GL_LESS) to NOT draw the section of the cylinder that lies inside of the head. What would be ideal for my project is if I could somehow only draw the circle where the cylinder intersects with the head. I tried changing my depth test to (GL_EQUAL) but it did not do the trick.

How can I do this? Keep in mind that the head object is very complex, with a large amount of points and triangles.

brohan322
  • 358
  • 1
  • 12

1 Answers1

0

The most practical solution that comes to mind is to discard the fragments outside the cylinder in the fragment shader.

One approach for this is that you pass the original coordinates from the vertex shader into the fragment shader. Say you currently have a typical vertex shader that applies a MVP transformation:

uniform mat4 MvpMat;
in vec4 InPos;
...
gl_Position = MvpMat * InPos;

You can extend this to:

uniform mat4 MvpMat;
in vec4 InPos;
out vec4 OrigPos;
...
    gl_Position = MvpMat * InPos;
    OrigPos = InPos;

Then in the fragment shader (for a cylinder with the given radius along the z-axis):

uniform float CylRad;
in vec4 OrigPos;
...
    if (dot(OrigPos.xy, OrigPos.xy) > CylRad * CylRad) {
        discard;
    }

There are countless variations of how exactly you can handle this. For example, instead of passing the original coordinates into the fragments shader, you could transform the cylinder geometry, and then perform the test using the transformed vertex/fragment coordinates. You'll have to figure out what looks the cleanest based on your exact use, but this should illustrate the basic idea.

Discarding fragments can have a negative performance impact. But unless you're already pushing the performance envelope, this approach might work just fine. And I doubt that there's a solution that will not have a performance cost.

It would be nice to operate on the vertex level. Full OpenGL has clip planes, which could potentially be used creatively for this case, but the clip plane feature is not in any version of OpenGL ES. Without this, there is really no way of discarding vertices, at least that I can think of. So discarding fragments might be the most reasonable option.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • I don't understand how to discard the right fragments. I believe I didn't fully explain what I wanted. I have the complex 3D head whose centroid is on the origin. I have a cylinder and the center of one of its top circular faces lies on the origin. The cylinder can rotate around the origin (and so can the head). With depth tests I can hide the portion of the cylinder inside the head, but see the portion of the cylinder outside of the head. I would prefer to just a circle where the cylinder intersects with the head. So I need to discard the cylinder fragments, not frags outside of the cylinder. – brohan322 Jan 20 '16 at 18:30
  • Basically, I was wondering if there was an approach I could use involving depth testing. – brohan322 Jan 20 '16 at 18:32