关闭抗锯齿的 Mathematica 7中的3D表面旋转非常快速和平滑。但是,即使在中等水平下打开消除锯齿,也会大幅降低渲染帧速率,使旋转非常不连贯。这种情况在 Mathematica 中发生的程度远远大于其他3D应用程序。
为什么 Mathematica 中的抗锯齿速度不成比例地慢?
一种极大地增强3D图形感觉的方法是在旋转期间关闭AA,但是一旦旋转停止就将其打开。可以在 Mathematica 7中完成吗?
要求提供一个例子。我将使用迈克代码的变体。请首先将Edit > Preferences > Appearance > Graphics
设置为No antialiasing
,然后Highest quality
,然后尝试以下操作。还可以尝试两者之间的设置。对我来说,No antialiasing
以外的任何设置都不顺畅。我可以在视觉上区分三个不同级别的AA,所以这不是我的GPU强迫所有或没有,但所有这些都很慢。
Animate[Plot3D[{x^2 + y^2, -x^2 - y^2}, {x, -2, 2}, {y, -2, 2},
ImageSize -> 700,
ViewPoint ->
Dynamic[{Sin[theta] Cos[phi], Sin[theta] Sin[phi], Cos[theta]}]],
{theta, 0, Pi}, {phi, 0, 2 Pi},
RefreshRate -> 120
]
在玩Alexey和Mike的代码时,发生了一些奇怪和好事。我突然有光滑的抗锯齿旋转!我不知道是什么导致了这种变化,我还没有关闭 Mathematica 因为害怕它会消失,但这证明了我所怀疑的,它可以很快。
更奇怪的是,我在同一个笔记本中并行并行的行为缓慢而快速。一个图形平滑旋转,另一个图形生成相同的代码是不连贯的。我推测通过运行Alexey和Mike的代码修改了一些单元格选项,它具有非常理想的效果。我会尽力弄清楚它是什么。
有用的选项是偶然出现在Alexey代码中的RotationAction -> "Clip", SphericalRegion -> True
。这些,或它们的效果(ViewAngle
),“粘贴”图形的方式与旋转相同,因此我能够在没有这些选项的情况下键入新代码,并运行它,并仍然得到平滑旋转(这解释了我上面看到的)。请参阅下面的答案进行详细说明。
虽然已经发现了一个可行的解决方法,但我仍然对使用AA进行不稳定旋转的解释感兴趣。我不认为图形的“拟合”是一种解释,而只是一种相关性,因为拟合仍需要在AA关闭的情况下进行,但旋转是平滑的。
答案 0 :(得分:7)
在Wizard先生指出改变ViewAngle提高性能之后,我对这是什么导致了预感。
通常情况下,当您在Mathematica中旋转图形时,您会注意到包含图形的框会在图像旋转时自行调整大小。为什么?大多数设置都设置为默认值Automatic
,所以他们试图摆弄,使图形在屏幕内很好地适应。具体而言,Plot3D
(以及许多其他3D Plot
函数)具有名为RotationAction
的命名参数。根据{{3}}:
默认情况下,3D图形会在交互式旋转时调整大小并移动以适合
此参数默认为RotationAction->"Fit"
,它会尝试始终确保整个3D图形适合屏幕。相反,您可以使用RotationAction->"Clip"
强制图形剪辑。这会使边界框保持不变。它不是调整大小,而是仅仅关闭屏幕上的任何内容。由于Mathematica无需不断重塑图像以使所有内容都适合屏幕,因此性能得到了显着提升。
示例代码:
Plot3D[{x^2 + y^2, -(x^2 + y^2)}, {x, -2, +2}, {y, -2, +2},
ImageSize -> 700, RotationAction -> "Fit"]
Plot3D[{x^2 + y^2, -(x^2 + y^2)}, {x, -2, +2}, {y, -2, +2},
ImageSize -> 700, RotationAction -> "Clip"]
经过进一步分析,RotationAction->"Clip"
最初有一些轮换问题。在图形的第一次旋转时,它旋转得非常快。我不知道为什么会这样,只有Wolfram Research可能会回答这个问题。在初始旋转之后,它会以正常速度旋转,就像任何其他图形一样。
通过以下方式给出了实现良好轮换的最顺畅的方法:
Plot3D[..., RotationAction -> "Clip", ViewAngle -> 0.4]
尽可能接近默认的剪裁体积,没有任何奇怪的快速旋转或切断图形的问题。
答案 1 :(得分:3)
基于Alexey的回答,我稍微更改了代码,因此不会修改前端设置:
aa = True;
EventHandler[
Style[
Plot3D[{x^2 + y^2, -(x^2 + y^2)}, {x, -2, +2}, {y, -2, +2},
ImageSize -> 700, RotationAction -> "Clip",
SphericalRegion -> True],
Antialiasing -> Dynamic[aa, TrackedSymbols :> {aa}]],
{"MouseUp" :> (aa = True), "MouseDown" :> (aa = False)},
PassEventsDown -> True]
它完成了相同的操作,但它避免修改$ FrontEnd。
这是一个自动处理提供动态变化抗锯齿的必要逻辑的函数:
Clear[DynamicAA]; (* Perhaps I should also add the HoldFirst attribute too, not sure *)
DynamicAA[graphics_] := Module[{aa},
aa = True;
EventHandler[
Style[graphics,
Antialiasing -> Dynamic[aa, TrackedSymbols :> {aa}]], {"MouseUp" :> (aa = True),
"MouseDown" :> (aa = False)}, PassEventsDown -> True]]
用法是你所期望的:
DynamicAA[Plot3D[{x^2 + y^2, -x^2 -y^2}, {x, -2, +2}, {y, -2, +2}, ImageSize->700]]
答案 2 :(得分:3)
也许其他人可以用Mouseover
来思考一些聪明的事情。这可以通过在鼠标悬停在显示的对象上时显示不同的表达式来实现;试试看:
Mouseover[
Style[
Graphics[Circle[]],
Antialiasing \[Rule] True
],
Style[
Graphics[Circle[]],
Antialiasing \[Rule] False
]
]
不幸的是,我不知道如何打开和关闭抗锯齿,也不知道如何制作像Plot[f,range,Option->Mouseover[1,2]]
这样的东西。
问题似乎是Mouseover
当光标未覆盖时, 事情 - 或者看起来如此。
也许能够更好地理解动态结构的人可以找出如何使用让Mouseover
能够解决问题的基础设施。
答案 3 :(得分:3)
基于acl的想法:
EventHandler[
Plot3D[{x^2 + y^2, -x^2 - y^2}, {x, -2, 2}, {y, -2, 2},
ImageSize -> 700, RotationAction -> "Clip",
SphericalRegion ->
True], {"MouseUp" :> (SetOptions[$FrontEndSession,
RenderingOptions -> {"HardwareAntialiasingQuality" -> 1.}]),
"MouseClicked" :> (SetOptions[$FrontEndSession,
RenderingOptions -> {"HardwareAntialiasingQuality" -> 1.}]),
"MouseDown" :> (SetOptions[$FrontEndSession,
RenderingOptions -> {"HardwareAntialiasingQuality" -> 0.}])},
PassEventsDown -> True]
您可以通过以下选项查看选项会发生什么:
Dynamic["HardwareAntialiasingQuality" /.
Last@Last@Options[$FrontEnd, RenderingOptions],
UpdateInterval -> .1]
工作原理:当您旋转绘图时,它会关闭当前FrontEnd会话的抗锯齿功能,并在释放鼠标时将其打开。唯一的问题是当释放鼠标并打开抗锯齿时,FrontEnd不会再次渲染图形以使其抗锯齿。解决方案是单击绘图而不旋转它 - 它变得抗锯齿!
答案 4 :(得分:2)
对于我的配置,我似乎已经发现了一个看似神奇的选项,它允许在完全抗锯齿的情况下进行平滑的3D旋转。这适用于我尝试的每种3D绘图类型,因此,除非这也神奇地停止工作,我有我的解决方案。我很想知道这对其他系统是否有同样的影响。
魔术选项是ViewAngle
。任何数值似乎都有效; Automatic
没有。
评估下面的代码,第一个图形旋转效果不佳,第二个图形平滑旋转。
Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}, ImageSize -> 900]
Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}, ImageSize -> 900, ViewAngle -> 0.43]
我对迈克的RotationAction -> "Clip"
方法有疑问,因为旋转图形时会出现意外情况,有时会出现极端裁剪现象。但是,添加SphericalRegion -> True
会恢复我使用ViewAngle
获得的行为,并自动选择角度:
Plot3D[{x^2 + y^2, -(x^2 + y^2)}, {x, -2, +2}, {y, -2, +2},
ImageSize -> 700, SphericalRegion -> True, RotationAction -> "Clip"]