OpenGLES 3.0,Android:如何绘制两个对象的交集

时间:2016-01-19 19:04:14

标签: android opengl-es depth-buffer stencil-buffer

我目前正在开发一个使用OpenGL-ES 3.0 for Android的项目。在我的项目中,我绘制了一个三维人体头部,其质心位于原点。我也有一个圆柱体,其中一个面的中心位于原点上。圆筒伸出的长度超过头部的长度。换句话说,我有一个圆柱体穿过头部。

现在,我只是使用默认深度测试(GL_LESS)来不绘制位于头部内部的圆柱部分。对我的项目来说最理想的是,如果我能够以某种方式仅绘制圆柱与圆头相交的圆。我尝试将深度测试更改为(GL_EQUAL),但它没有做到这一点。

我该怎么做?请记住,头部对象非常复杂,有大量的点和三角形。

1 个答案:

答案 0 :(得分:0)

我想到的最实用的解决方案是在片段着色器中丢弃柱面外的碎片。

一种方法是将原始坐标从顶点着色器传递到片段着色器。假设您目前有一个应用MVP转换的典型顶点着色器:

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

您可以将其扩展为:

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

然后在片段着色器中(对于沿z轴具有给定半径的圆柱体):

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

有多少变化可以解决这个问题。例如,您可以转换圆柱体几何体,然后使用变换后的顶点/片段坐标执行测试,而不是将原始坐标传递到片段着色器中。你必须根据你的确切用途找出看起来最干净的东西,但这应该说明基本的想法。

丢弃片段可能会对性能产生负面影响。但除非你已经在推动性能范围,否则这种方法可能会正常工作。我怀疑有一个解决方案不会有性能成本。

在顶点级操作会很不错。完整的OpenGL具有剪辑平面,可能会创造性地用于此情况,但剪辑平面功能不在任何版本的OpenGL ES中。没有这个,实际上没有办法丢弃顶点,至少我能想到的是。因此丢弃片段可能是最合理的选择。