在Mathematica 7中使用抗锯齿进行慢速3D旋转

时间:2011-08-21 08:21:32

标签: 3d wolfram-mathematica antialiasing

关闭抗锯齿的 Mathematica 7中的3D表面旋转非常快速和平滑。但是,即使在中等水平下打开消除锯齿,也会大幅降低渲染帧速率,使旋转非常不连贯。这种情况在 Mathematica 中发生的程度远远大于其他3D应用程序。

  1. 为什么 Mathematica 中的抗锯齿速度不成比例地慢?

  2. 一种极大地增强3D图形感觉的方法是在旋转期间关闭AA,但是一旦旋转停止就将其打开。可以在 Mathematica 7中完成吗?


  3. 要求提供一个例子。我将使用迈克代码的变体。请首先将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关闭的情况下进行,但旋转是平滑的。

5 个答案:

答案 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"]