`render` 函数可以用来加速渲染吗?

3D打印 3d 设计 CAD opencad
2021-04-29 19:57:14

我正在 OpenScad 中设计一个中等复杂的作品。

它在预览模式下渲染得足够快(1 秒)。但是当我做一个完整的渲染以便我可以导出到 STL 时,它需要很长时间(在 10 分钟内)

我读到有时该功能render对加快整体渲染很有用。

  • 这是正确的,还是我误解了?
    • 如果我误解了,这个render函数有什么用?
  • 这是如何运作的?
  • 什么情况下可以申请?
1个回答

首先免责声明:我远不是该主题的专家,我只是一个普通的 Joe,碰巧使用 OpenSCAD 并对其进行了一些实验。我相信下面的答案是正确的,但如果在评论中引起我注意的错误或误解,我将不胜感激。:)

我读到有时函数 render 对加速整体渲染很有用。这是正确的,还是我误解了?

我不知道是否可以使用render(),加快“整体呈现”,但我宁愿相信,预期的目的render()是简化模型的内存中表示,因此预览窗口的响应,而不是加速其最终渲染。

这是如何运作的?

为了理解这是如何工作的,我们必须了解构造实体几何 (CSG) 的工作原理。

CSG 的整个前提是在原始实体形状之间使用布尔运算,可以表示复杂的形状。

然而,虽然人类操作员可能会将差和交等减法运算视为使模型体积更小从而可能更易于处理的东西,但计算机将每一个运算视为增加零件的几何形状和复杂性,如下图恰当地说明:

视觉与内存模型

在 CAD 查看器中操作模型时,OpenSCAD 处于预览模式,并且每次调整视口时都需要处理所有“不可见几何体”。很容易达到 OpenSCAD 查看器变得紧张或无响应的程度。

render()函数的作用是告诉 OpenSCAD 计算由render()调用中包含的布尔运算产生的网格,并在查看器中处理模型时使用该单个网格而不是底层的布尔组合基元。 网格通常用于OpenSCAD (F6)渲染模式而不是预览模式,但在这里它们的优势不是更好的视觉质量,而是 OpenSCAD 需要处理的几何体少得多的事实。

什么情况下可以申请?

您可以随时应用它,真的,但这是一个权衡:在render()内部使用该功能的模型将需要更长的时间来显示其初始预览(因为生成网格是一项昂贵的操作)但它的行为非常在查看器中很好。相反,没有杠杆作用的大型模型render()在查看器中处理时会很紧张,但它会在很短的时间内呈现到屏幕上。必须注意的是,OpenSCAD 大量使用缓存,因此第一个预览将花费最长的时间,而连续的预览可能要快得多。

小测试

作为参考,此答案底部的代码(生成上图)的行为如下:

  • 使用render(): 15s 进行预览,多 1m29s 进行正确渲染(总计:1m44s)。
  • 没有render(): 0s 用于预览,1m45s 用于正确渲染(TOTAL: 1m45s)。

我不知道总数彼此相似的事实是我的模型特有的巧合还是一般的经验法则(该render()功能在预览期间有效地创建了最终渲染的一部分),但您可以随意使用代码如果你发现一个模式,请发表评论。

在下面的代码中,如果您想查看普通代码和render()函数之间的响应差异,您可能需要将网格大小增加到 20x20

还要记住在测试之间关闭并重新打开 OpenSCAD,以刷新缓存。


$fn = 30;

module shape() {
    render() difference() {
        sphere();
        cylinder(r=0.3, h=3, center=true);
        rotate([90, 0, 0]) cylinder(r=0.3, h=3, center=true);
        rotate([0, 90, 0]) cylinder(r=0.3, h=3, center=true);
        rotate([45, 0, 0]) cylinder(r=0.3, h=3, center=true);
        rotate([-45, 0, 0]) cylinder(r=0.3, h=3, center=true);
        rotate([0, 45, 0]) cylinder(r=0.3, h=3, center=true);
        rotate([0, -45, 0]) cylinder(r=0.3, h=3, center=true);
        rotate([90, 0, 45]) cylinder(r=0.3, h=3, center=true);
        rotate([90, 0, -45]) cylinder(r=0.3, h=3, center=true);
    }
}

module line(x, y) {
    translate([x * 2, y, 0]) shape();
    if (x > 0) line(x - 1, y);
}    

module grid(x, y) {
    line(x, y * 2);
    if (y > 0) grid(x, y - 1);
}

grid(3, 3);