我目前正在开发一个使用OpenGL-ES 3.0 for Android的项目。在我的项目中,我绘制了一个三维人体头部,其质心位于原点。我也有一个圆柱体,其中一个面的中心位于原点上。圆筒伸出的长度超过头部的长度。换句话说,我有一个圆柱体穿过头部。
现在,我只是使用默认深度测试(GL_LESS)来不绘制位于头部内部的圆柱部分。对我的项目来说最理想的是,如果我能够以某种方式仅绘制圆柱与圆头相交的圆。我尝试将深度测试更改为(GL_EQUAL),但它没有做到这一点。
我该怎么做?请记住,头部对象非常复杂,有大量的点和三角形。
答案 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中。没有这个,实际上没有办法丢弃顶点,至少我能想到的是。因此丢弃片段可能是最合理的选择。