Mathematica 7 中具有抗锯齿功能的 3D 旋转速度较慢

发布于 2024-11-30 18:43:32 字数 1392 浏览 2 评论 0原文

关闭抗锯齿后,Mathematica 7 中的 3D 表面旋转非常快速且平滑。然而,打开抗锯齿功能,即使处于中等水平,也会大大降低渲染帧速率,使旋转变得非常不稳定。与其他 3D 应用程序相比,这种情况在 Mathematica 中发生的程度要高得多。

  1. 为什么 Mathematica 中的抗锯齿速度异常慢?

  2. 大幅增强 3D 图形感觉的一种方法是在旋转过程中关闭 AA,但在旋转停止后立即将其打开。这可以在 Mathematica 7 中完成吗?


要求提供示例。我将使用迈克代码的变体。请使用 Edit > 尝试以下操作首选项>外观>图形首先设置为无抗锯齿,然后设置为最高质量。还可以尝试介于两者之间的设置。对我来说,除了无抗锯齿之外的任何设置都不流畅。我可以在视觉上区分三种不同级别的 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 的代码进行修改的,并且它具有非常理想的效果。我将尽力弄清楚它是什么。


有用的选项是 RotationAction -> “剪辑”,SphericalRegion ->确实,偶然出现在 Alexey 的代码中。这些或其效果(ViewAngle)以与旋转相同的方式“粘”在图形上,因此我能够在没有这些选项的情况下键入新代码而不是旧代码,然后运行它,然后仍然获得平滑的旋转(这解释了我上面所看到的)。请参阅下面的答案以进行一些详细说明。

虽然已经找到了可行的解决方法,但我仍然对 AA 开启时不稳定旋转的解释感兴趣。我不认为图形的“拟合”是一种解释,而仅仅是一种相关性,因为拟合仍然需要在 AA 关闭的情况下进行,但旋转是平滑的。

3D surface rotation in Mathematica 7 with anti-aliasing turned off is very fast and smooth. However, turning on anti-aliasing, even at a moderate level, drastically reduces the rendered frame rate, making rotation very choppy. This happens to a much greater degree in Mathematica than it does in other 3D applications.

  1. Why is anti-aliasing disproportionately slower in Mathematica?

  2. A way to greatly enhance the feel of 3D graphics would be to turn off AA during rotation, but turn it on as soon as rotation is stopped. Can this be done in Mathematica 7?


An example was requested. I will use a variation of Mike's code. Please try the following with Edit > Preferences > Appearance > Graphics first set to No antialiasing and then Highest quality. Also try the settings in between. For me, any setting besides No antialiasing is not smooth. I can visually distinguish three different levels of AA, so it is not a matter of my GPU forcing all or none, yet all of them are slow.

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
]

UPDATE and OBSERVATION

While playing around with Alexey and Mike's code, something strange and good happened. I suddenly have smooth antialiased rotation! I don't know what precipitated the change, and I have not closed Mathematica for fear that it will go away, but this proves what I suspected, that it CAN be fast.

More strange, I have the slow and fast behavior happening in parallel in the same notebook. One graphic is rotating smoothly, and another produced with the same code is choppy. I theorize that some cell option was modified by running Alexey and Mike's code, and it is having a very desirable effect. I am going to do my best to figure out what it is.


The helpful options were RotationAction -> "Clip", SphericalRegion -> True that appeared in Alexey's code incidentally. These, or their effect (ViewAngle), "stick" with a graphic in the same way that rotation does, therefore I was able to type new code without these options over the old, and run it, and still get the smooth rotation (which explains what I saw above). See answers below for some elaboration.

While a viable workaround has been discovered, I am still interested in an explanation for the choppy rotation with AA on. I do not believe that the "fitting" of the graphic is an explanation, but merely a correlation, as the fitting still needs to take place with AA off, and yet the rotation is smooth.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

掀纱窥君容 2024-12-07 18:43:32

在 Wizard 先生指出更改 ViewAngle 可以提高性能之后,我有一种预感,知道是什么原因造成的。

通常,当您在 Mathematica 中旋转图形时,您会注意到包含图形的框会随着图像的旋转而自行调整大小。为什么?大多数设置都设置为默认值自动,因此他们尝试摆弄以使图形很好地适应屏幕。具体来说,Plot3D(以及许多其他 3D Plot 函数)有一个名为 RotationAction 的命名参数。根据 Mathematica 文档

交互式旋转时,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]

这尽可能接近默认剪切体积,没有任何快速旋转或剪切图形的奇怪问题。

After Mr. Wizard pointed out that changing the ViewAngle improved performance, I had a hunch as to what was causing it.

Normally, when you rotate graphics in Mathematica, you'll notice the box that contains the graphics resizes itself as the image is rotated around. Why? Most of the settings are set to the default of Automatic, so they try to fiddle around to make the graphics fit nicely within the screen. Specifically, Plot3D (and many other 3D Plot functions) have a named parameter called RotationAction. According to the Mathematica documentation:

3D graphics by default resize and move to fit when they are interactively rotated

This parameter defaults to RotationAction->"Fit", which tries to always make sure the entire 3D graphics fits on screen. Instead, you can force the graphics to clip using RotationAction->"Clip". This causes the bounding box to remain the same. Instead of resizing, it merely chops off whatever goes off screen. Performance is improved dramatically as Mathematica doesn't have to continuously reshape the image to make everything fit on screen.

Example code:

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

Some further notes

Upon further analysis, RotationAction->"Clip" has some issues with rotation initially. On the very first rotation of the graphics, it rotates extremely fast. I don't know why this is so, only Wolfram Research could possibly answer that. After the initial rotation though, it rotates at the normal speed as any other graphics though.

The smoothest way of accomplishing nice rotation for me was given by:

 Plot3D[..., RotationAction -> "Clip", ViewAngle -> 0.4]

This is as close to the default clipping volume as possible, without any strange issues with fast rotations or cut off graphics.

王权女流氓 2024-12-07 18:43:32

也许其他人可以用Mouseover想出一些巧妙的办法。这是通过当鼠标位于或不在显示的对象上时显示不同的表达式来实现的;尝试一下:

Mouseover[
 Style[
  Graphics[Circle[]],
  Antialiasing \[Rule] True
  ],
 Style[
  Graphics[Circle[]],
  Antialiasing \[Rule] False
  ]
 ]

不幸的是,我不知道如何打开和关闭抗锯齿功能,也不知道如何制作类似 Plot[f,range,Option->Mouseover[1,2]].

问题似乎是,当光标位于/不在其上方时,Mouseover 不会评估不同的内容,而是显示不同的内容事情——至少看起来是这样。

也许更了解动态构造的人可以弄清楚如何使用让 Mouseover 发挥作用的基础设施来解决您的问题。

Perhaps someone else can think of something clever with Mouseover. This works by displaying a different expression when the mouse is over the displayed object or not; try this to see:

Mouseover[
 Style[
  Graphics[Circle[]],
  Antialiasing \[Rule] True
  ],
 Style[
  Graphics[Circle[]],
  Antialiasing \[Rule] False
  ]
 ]

Unfortunately I have no idea how one would switch antialiasing on and off, nor do I know how to make something like Plot[f,range,Option->Mouseover[1,2]].

The problem seems to be that Mouseover doesn't evaluate to different things when the cursor is/is not over it, but rather it displays different things--or so it looks.

Maybe someone who understands dynamic constructs better can work out how to use the infrastructure that lets Mouseover do its thing to solve your problem.

苦笑流年记忆 2024-12-07 18:43:32

在 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]]

Building off of Alexey's answer, I changed the code slightly so it doesn't modify the front end settings:

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]

It accomplishes the same, but it avoids modifying $FrontEnd.

Here is a function which automatically tacks on the necessary logic for providing dynamically changing antialiasing:

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]]

Usage is what you what expect:

DynamicAA[Plot3D[{x^2 + y^2, -x^2 -y^2}, {x, -2, +2}, {y, -2, +2}, ImageSize->700]]
放飞的风筝 2024-12-07 18:43:32

基于 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]

它是如何工作的:当您旋转绘图时,它会关闭当前前端会话的抗锯齿功能,并在您释放鼠标时将其打开。唯一的问题是,当释放鼠标并打开抗锯齿功能时,前端不会再次渲染图形以使其抗锯齿。解决方案是单击绘图而不旋转它 - 它会变得抗锯齿!

Based on acl's idea:

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]

You can see what happens with the option with:

Dynamic["HardwareAntialiasingQuality" /. 
  Last@Last@Options[$FrontEnd, RenderingOptions], 
 UpdateInterval -> .1]

How it works: it switches off antialiasing for the currend FrontEnd session when you rotate the plot and switches it on when you release the mouse. The only problem is that when the mouse is released and antialiasing is switched on, the FrontEnd does not render the graphics again to make it antialiased. The solution is to click the plot without rotating it - and it becomes antialiased!

往昔成烟 2024-12-07 18:43:32

对于我的配置,我似乎发现了一个神奇的选项,可以在启用完全抗锯齿功能的情况下实现平滑的 3D 旋转。这适用于我尝试过的每种 3D 绘图类型,因此除非这也神奇地停止工作,否则我有我的解决方案。我很想知道这对其他系统是否有同样的效果。

该选项是ViewAngle。任何数值似乎都有效; 自动 不会。

评估第一个图形下方的代码旋转效果不佳,而第二个图形旋转平滑。

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]

我对 Mike 的 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"]

I appear to have discovered—for my configuration—a magic option that allows for smooth 3D rotation with full antialiasing on. This works for every 3D plot type I have tried therefore unless this also magically stops working I have my solution. I am very interested to know if this has the same effect on other systems.

The option is ViewAngle. Any numeric value appears to work; Automatic does not.

Evaluating the code below the first graphic rotates poorly and the second graphic rotates smoothly.

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]

I have a problem with Mike's RotationAction -> "Clip" method, in that I get unexpected and sometimes extreme cropping when rotate the graphic. However, adding SphericalRegion -> True restores the behavior that I get with ViewAngle, and the angle is chosen automatically:

Plot3D[{x^2 + y^2, -(x^2 + y^2)}, {x, -2, +2}, {y, -2, +2}, 
 ImageSize -> 700, SphericalRegion -> True, RotationAction -> "Clip"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文