OpenGL中曲面上的水平曲线

时间:2018-06-12 07:21:01

标签: python opengl graphics 3d pyopengl

我在三角形网格上定义了一个函数f,即对于每个顶点,我有一个相关的数字。例如,f可以是网格上的测地距离,即,对于网格中的每个点,从特定的固定点a计算的f(x)= d(a,x)。 显然,只需将f的值标准化并将它们映射到网格节点上的颜色,就可以很容易地在曲面上“绘制”此函数。

但是如果我想在表面上绘制等值线(也称为contour lines或isoclines)会怎样?

我该怎么做?通过简单地将网格着色如上所述,这似乎不太容易实现。特别是因为网格可能具有顶点很少的稀疏区域(即大面)。这表明(可能)我应该将isoclines直接计算为网格上的3D曲线并使用例如GL-线。但计算等倾曲线不是那么明显,因为天真的方法是固定一组目标值,然后我将检查每个三角形是否通过插值在三角形的某个点到达目标。看起来不太理想。任何人都可以向我指出解决这个问题的任何资源吗?

供参考,我使用的是python OpenGL。

2 个答案:

答案 0 :(得分:1)

如果值为float并且您知道它的范围您可以尝试着色,如上所述,片段着色器位于其顶部,只会在渲染值附近呈现片段。

最简单的方法是使用单个渲染过程在片段中使用类似的东西:

float x;
x = (value/10.0)+0.5; // 10 is distance of value you want the lines to render
x = x-floor(x);   // x = value mod distance
if (abs(x-0.5)>0.001) discard; // do not render fragments too far from your line

代码只是决定你是否非常接近每个距离= 10的值并抛弃任何不是的片段。然而,线/曲线的厚度可以根据值密度和三角形尺寸分布而变化。您必须正确设置常量(distance=10,threshold=0.001)才能使其正常工作。

这个GLSL animated mesh surface highlight使用非常类似的技术而不是丢弃,因为那里的东西是连续的。

更准确的选择是在2遍渲染中使用相同的原理。在第一遍中将值作为颜色渲染到某些纹理的位置。然后在每个片段的第二个扫描周围的纹理,找到可渲染值的最近位置,并根据它与渲染或不渲染的距离。无论如何,这都提供了精确的线条厚度。但为此,该值必须包含特定的可渲染值。这个How to implement 2D raycasting light effect in GLSL可能会有所帮助,因为它还会扫描所有方向的纹理(但出于不同的目的)。

如果以上都不适合您,那么我脑海中只有其他选项是几何方法,您可以根据与网格的交点(如横截面与平面)从网格创建折线。

答案 1 :(得分:1)

假设您想要绘制其Z坐标是ci的倍数的轮廓(等值线)(对于“轮廓间隔”)。例如,对于ci=5,有效值为25,30,35等。
三角形可以没有,一个或几个轮廓穿过它。我不打扰线。我使用点,我检查片段着色器中的每个片段。

第一个目标是在片段着色器中返回片段的世界坐标。
片段着色器接收gl_FragCoord,其屏幕坐标为{x,y,z}。或者在顶点着色器中,您可以使用z传递变化。阅读this q&a以了解如何进行此转换。

现在世界坐标中有一个z,是时候判断它是否属于轮廓了:

float maxErr = 0.0001;
float dif = abs(z - (ci * floor(z/ci)));
if ( dif > maxErr )
    color = triangleColor;
else
    color = contourColor;

因为片段与像素不同,所以可能会得到一个非宽度常数线。