rgl:如何避免透明 3D 椭球体中的莫尔效应?

rgl: How to avoid moire effect in transparent 3D ellipsoids?

在我的 heplots 包中,我绘制了假设和误差 3D 椭球来表示多元线性检验。 我发现当 H 椭球实际上只是 2D 时,我会得到令人不快的莫尔效应,如下所示。 请注意,Error ellipsoid 没有此缺陷。

在此 MWE 中对 heplot3d 的调用指定没有线框,但使用表面的透明阴影。

library(rgl)
library(heplots)
data(penguins, package="palmerpenguins")

peng <- penguins
peng.mod0 <-lm(cbind(bill_length, bill_depth, flipper_length, body_mass) ~ species, data=peng)
heplot3d(peng.mod0, shade=TRUE, shade.alpha=0.2, wire=FALSE, size="effect")

有什么办法可以修改这个函数中的代码来避免这个问题吗?是什么原因造成的?这与表面的法线有什么关系吗?

这里的问题是椭圆体的前表面和后表面是在同一平面上绘制的。 rgl 绘制透明物体的方式依赖于将物体从后向前排序,但它只能近似地做到这一点:例如两个相交三角形的不同部分需要不同的排序。 在您的示例中,rgl 尝试对扁平椭圆体的正面和背面进行排序,但数值错误意味着它有点随机化绘图顺序,而且看起来真的很难看。

避免这种情况的最简单方法是在绘制椭圆体的调用中使用 back = "cull"。这样后面就完全不画了,好看多了。

两个椭球相交的地方还是会出现问题;修复它更难。您需要将红色椭圆体分成蓝色椭圆体每一侧的部分,然后分别绘制。可能还需要将红色内部的蓝色部分与外部的部分分开绘制。这些事情现在可以使用 clipMesh3d 功能,但很难做到正确。

编辑添加:

这里更好的解决办法是在绘制透明椭圆体时设置depth_mask = FALSE。 (这是另一个material 属性,它默认为TRUE。)解释如下:

  • “深度遮罩”决定绘制对象是否会阻止后面绘制的对象可见。不透明的对象应该总是用 depth_mask = TRUE 绘制,因为它们应该总是隐藏它们后面的东西。

  • 更难决定对透明对象使用哪种设置。因为它们是在绘制之前排序的,所以深度掩码应该无关紧要,但因为排序只是近似的,所以有时它会有所帮助。在您的情况下,您正在绘制两个完全相同深度的形状,直至舍入误差。对于 depth_mask = TRUE,有时不会绘制第二个,因为舍入误差使它看起来更远。如果你设置 depth_mask = FALSE,两者都会被绘制,并且椭圆看起来更好。并非所有形状都如此,但在这种情况下它有效。

  • 我所做的一些计算建议在 alpha > 0.5 时使用 depth_mask = TRUE,对于较小的 alpha 值使用 depth_mask = FALSE