【问题标题】:OpenGLES 3.0, Android: How to draw intersection of two objectsOpenGLES 3.0,Android:如何绘制两个对象的交集
【发布时间】:2016-01-19 19:04:14
【问题描述】:

我目前正在开发一个使用适用于 Android 的 OpenGL-ES 3.0 的项目。在我的项目中,我绘制了一个 3d 人头,其质心位于原点。我还有一个圆柱体,其中一个面的中心位于原点。圆柱体伸出的长度比头部的长度长。换句话说,我有一个气缸穿过头部。

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

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

【问题讨论】:

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


    【解决方案1】:

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

    一种方法是将原始坐标从顶点着色器传递到片段着色器。假设您当前有一个应用 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 中都没有。没有这个,真的没有办法丢弃顶点,至少我能想到的。所以丢弃碎片可能是最合理的选择。

    【讨论】:

    • 我不明白如何丢弃正确的片段。我相信我没有完全解释我想要什么。我有一个复杂的 3D 头部,其质心位于原点。我有一个圆柱体,其顶部圆形面之一的中心位于原点。圆柱体可以围绕原点旋转(头部也可以)。通过深度测试,我可以将圆柱体部分隐藏在头部内部,但可以看到圆柱体部分在头部外部。我宁愿只画一个圆柱体与头部相交的圆圈。所以我需要丢弃圆柱体碎片,而不是圆柱体外部的碎片。
    • 基本上,我想知道是否可以使用一种涉及深度测试的方法。
    猜你喜欢
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 2014-03-05
    相关资源
    最近更新 更多