什么 3D 渲染 technic/algorithm 最有效地按边绘制光束?
What 3D rendering technic/algorithm is most effective to draw beams by edges?
我正在尝试用 C# 构建一个程序,该程序生成由梁组成的结构的 3D 模型,然后创建对象的一些视图(正面、侧面、顶部和等轴测图)。
因为我不需要画表面(边缘就足够了),我一直在计算要画的每条线,然后用
GraphicObject.DrawLine(myPen, x1, y1, x2, y2)
到目前为止效果很好,但是当我向结构中添加部件时,GraphicObject
的刷新需要太多时间。所以我开始检查线条可见性以减少要绘制的线条数量。
我已经搜索过维基百科和一些关于这个主题的 PDF,但我发现的都是以表面为导向的。所以我的问题是:是否有简化的算法来检查对象边缘的可见性,或者我应该采用不同的方法,比如考虑表面?
如有任何建议,我们将不胜感激,感谢您的帮助。
其他notes/questions:
我目前的做法:
计算局部轴(所有顶点)中的每个光束
- => 将它们移动到全局位置
- => 创建一个包含点对的列表(投影并缩放到视图)
- =>
GraphicObject.DrawLine
点对列表)
如果我按像素计算视图而不是使用 DrawLine
方法,整个过程会更快吗?
屏幕截图显示了它将要执行的结构类型(尚未完全完成):
- 结构视图
- 结构细节
有 2 种解决方案可以提高性能。
a) 将计算切换到显卡。
b) 使用 kd-tree 或其他类似的数据结构来快速删除不可见的边缘。
详情如下:
对于 a),你们中的很多计算都是将许多顶点(长度为 3 的向量)乘以某个矩阵。 CPU 很慢,因为它们一次只执行几个这样的操作。切换到 GPU,例如使用 CUDA,这将允许您以更好的内存访问基础架构并行执行更多操作。您还可以使用 OpenGL/DirectX/Vulkan 或任何其他方式来渲染线条本身,从而跳过必须从显卡取回结果以及 windows code/libraries 引入的任何其他问题。这将在几乎所有情况下都有助于提高性能。
对于 b),它仅在您不查看整个场景时才有帮助(在那种情况下您确实需要绘制所有内容)。在这种情况下,您可以将场景存储在 kd-tree 或其他一些数据结构中,并使用它来快速删除确定位于视图区域之外的内容。您通常需要用 pyramid/fustrum 与一些长方体相交,因此涉及更多数学运算。
作为一种折衷方案,在您希望看到所有内容的大型场景中应该有所帮助,您可以考虑调整细节级别。从您的示例中,读取的 bean 由 8 个左右的组件组成。如果你离得足够远,你将无法区分 8,所以只画一个。如果您有大量圆形边缘,这将非常有用,因为您可以简化其中的很多。
我正在尝试用 C# 构建一个程序,该程序生成由梁组成的结构的 3D 模型,然后创建对象的一些视图(正面、侧面、顶部和等轴测图)。
因为我不需要画表面(边缘就足够了),我一直在计算要画的每条线,然后用
GraphicObject.DrawLine(myPen, x1, y1, x2, y2)
到目前为止效果很好,但是当我向结构中添加部件时,GraphicObject
的刷新需要太多时间。所以我开始检查线条可见性以减少要绘制的线条数量。
我已经搜索过维基百科和一些关于这个主题的 PDF,但我发现的都是以表面为导向的。所以我的问题是:是否有简化的算法来检查对象边缘的可见性,或者我应该采用不同的方法,比如考虑表面?
如有任何建议,我们将不胜感激,感谢您的帮助。
其他notes/questions:
我目前的做法:
计算局部轴(所有顶点)中的每个光束
- => 将它们移动到全局位置
- => 创建一个包含点对的列表(投影并缩放到视图)
- =>
GraphicObject.DrawLine
点对列表)
如果我按像素计算视图而不是使用
DrawLine
方法,整个过程会更快吗?
屏幕截图显示了它将要执行的结构类型(尚未完全完成):
- 结构视图
- 结构细节
有 2 种解决方案可以提高性能。 a) 将计算切换到显卡。 b) 使用 kd-tree 或其他类似的数据结构来快速删除不可见的边缘。
详情如下: 对于 a),你们中的很多计算都是将许多顶点(长度为 3 的向量)乘以某个矩阵。 CPU 很慢,因为它们一次只执行几个这样的操作。切换到 GPU,例如使用 CUDA,这将允许您以更好的内存访问基础架构并行执行更多操作。您还可以使用 OpenGL/DirectX/Vulkan 或任何其他方式来渲染线条本身,从而跳过必须从显卡取回结果以及 windows code/libraries 引入的任何其他问题。这将在几乎所有情况下都有助于提高性能。
对于 b),它仅在您不查看整个场景时才有帮助(在那种情况下您确实需要绘制所有内容)。在这种情况下,您可以将场景存储在 kd-tree 或其他一些数据结构中,并使用它来快速删除确定位于视图区域之外的内容。您通常需要用 pyramid/fustrum 与一些长方体相交,因此涉及更多数学运算。
作为一种折衷方案,在您希望看到所有内容的大型场景中应该有所帮助,您可以考虑调整细节级别。从您的示例中,读取的 bean 由 8 个左右的组件组成。如果你离得足够远,你将无法区分 8,所以只画一个。如果您有大量圆形边缘,这将非常有用,因为您可以简化其中的很多。