OpenGL中曲面上的层次曲线

mkh04yzy  于 2023-08-04  发布在  其他
关注(0)|答案(3)|浏览(90)

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

但是如果我想在曲面上绘制等值线(也称为contour lines或isoclines),该怎么办?

我该怎么做?这似乎不容易通过简单地着色网格如上所述。特别是由于网格可以具有带有很少顶点的稀疏区域(即,网格的顶点数可以是0)。大的脸)。这表明(也许)我应该直接计算等倾线作为网格上的3D曲线,并使用例如但是计算等倾曲线并不那么明显,因为简单的方法是固定一组目标值,然后我将不得不检查每个三角形是否通过插值在三角形上的某些点到达目标,这似乎并不理想。有人能给我指出解决这个问题的任何资源吗?
作为参考,我使用python OpenGL。

vtwuwzda

vtwuwzda1#

如果值是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可能会有所帮助,因为它也可以在所有方向上扫描纹理(但目的不同)。
如果以上都不适合你,那么我想到的唯一其他选择是几何方法,你可以根据与网格的值相交(如平面横截面)从网格中创建折线。

64jmpszr

64jmpszr2#

假设你想要绘制Z坐标是ci倍数的等高线(等值线)(表示“等高线间隔”)。例如,对于ci=5,有效值是25、30、35等。
一个三角形可以没有一条、一条或多条等高线与之相交。我不在乎台词。我使用点,我检查片段着色器中的每个片段。
第一个目标是在片段着色器中获取片段的世界坐标。
片段着色器接收屏幕坐标为{x,y,z}gl_FragCoord。或者在顶点着色器中,你可以用z传递一个 varying。阅读this q&a来了解如何进行这种转换。
现在你在世界坐标系中有一个z,是时候判断它是否属于一个轮廓了:

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

字符串
因为片段与像素不同,所以您可能会得到宽度不恒定的线。

vnjpjtjt

vnjpjtjt3#

显然,在曲面上“绘制”这个函数是很容易的,只需将f的值归一化并将其Map到网格节点上的颜色即可。这似乎不容易通过简单地着色网格如上所述。
实际上,绘制可见线作为相同颜色区域之间的边界同样容易。一个只是创建一个OpenGL纹理与所需的调色板的颜色,并要求OpenGL采样它没有插值(GL_NEAREST模式):

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

字符串
并且指定每个顶点中的uv纹理坐标中的一个与该顶点处的值成比例。
下面是一个只有4个不同元素的纹理:


的数据
另一种方法是构造由线段组成的等值线,并将其绘制成等值线。给定某个等值线值,每个网格三角形可以不向结果多段线贡献线段或向结果多段线贡献单个线段。后一种情况发生在三个三角形顶点中的顶点值低于和高于所选择的等值线值时。在这种情况下,连接具有低于和高于值的顶点的两条边与等值线相交(并且剩余的第三条边不相交)。这可以被看作是移动立方体算法的变体。
球体上的等值线相同:



在这篇简短的video中,两种方法一起呈现。在那里的链接,可以找到一个开源的C++库。我认为在python中移植算法是相当简单的。

相关问题