头部跟踪应用程序的 WPF 3D 性能
我正在致力于创建一个全屏 3D 应用程序(基于 Johnny Lee 的 Wii 头部跟踪应用)具有一些增强现实功能,而且 WPF 似乎太慢,无法以合理的帧速率渲染我正在使用的简单模型。我认为问题在于,由于应用程序的性质(它使用网络摄像头来跟踪您的脸部,并使用该数据来移动相机),我需要在几乎每一帧上更改相机的视图和投影周围并改变其视角)。
我花了很多时间试图缩小问题范围,这肯定与图形有关,而不是我正在使用的头部跟踪 API 的速度。另外,我在 XNA 中重新创建了该应用程序,它似乎在那里运行良好(28 FPS,而 WPF 中为 9)。最后,当我移除“墙”或使窗口变得更小(例如,800 x 600)时,WPF的性能大大提高,这让我认为瓶颈是图形计算。
因此,我需要找到一个新的图形后端来使用,或者找到一种方法来使 WPF 对于这个应用程序来说更快。我主要关注 DirectX 和 XNA,也可能关注 OpenGL。关于这些 API 中哪一个最适合用于 .NET 中的此应用程序,有什么建议吗?或者,知道我在 WPF 中做错了什么导致速度变慢吗?
I’m working on creating a full-screen 3-D app (based on Johnny Lee's Wii head tracking app) with some augmented reality features, and it seems that WPF is too slow to render even the simple models I’m using at a reasonable frame rate. I think the problem is that I need to change both the view and projection of the camera on just about every frame, because of the nature of the app (it uses a web cam to track your face, and uses that data to move the camera around and change its perspective).
I've spent a lot of time trying to narrow down the problem, and it's definitely related to the graphics, and not the speed of the head-tracking API that I'm using. Also, I recreated the app in XNA, and it seems to work fine there (28 FPS versus 9 in WPF). Finally, when I remove the "walls" or make the window much smaller (say, 800 x 600), WPF's performance greatly improves, which makes me think that the bottleneck is the graphics calculations.
As a result, I need to either find a new graphics back-end to work with, or find a way to make WPF much faster for this app. I’m mostly looking at DirectX and XNA, and possibly OpenGL. Any recommendations on which of these APIs would be best to use for this app in .NET? Or alternatively, any idea what I'm doing wrong in WPF that's slowing things down?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我对 WPF 中的 3D 进行的研究还不够多,无法说出可能导致缓慢的原因,但我确实注意到它的模型数据结构不是很有效。虽然这可能不是原因,但它可能是整个管道普遍缓慢的症状。
我确实想到的一件事是,WPF 在软件中渲染场景,而不是使用显卡上的硬件加速。事实上,使用较小的窗口可以获得更好的性能(尽管你没有说好多少)。
如果从模型中删除任何纹理,是否也会获得更好的性能?
我认为您选择 Direct3D 还是 OpenGL 并不重要 - 几乎所有现代显卡都同样支持它们。如果您坚持使用 .NET,XNA 是显而易见的选择,因为它已集成到 Visual Studio(甚至是 Express 版本)中。
I've not done enough with 3D in WPF to be able to say what could be causing the slowness, but I did notice that it's model datastructure isn't very efficient. While this might not be the cause it could be symptomatic of general slowness to the whole pipeline.
One thing that does spring to mind is that WPF is rendering the scene in software rather than using the hardware acceleration on the graphics card. The fact that you get better performance (though you don't say how much better) with a smaller window.
If you remove any textures from your model do you get better performance too?
I don't think it really matters whether you go for Direct3D or OpenGL - virtually all modern cards support them equally well. XNA is the obvious choice if you're sticking with .NET as it's integrated into Visual Studio - even the Express edition.
我会查看 SlimDX,它是比 XNA 或 WPF 更薄的 DirectX 包装器
更改每一帧上的投影的问题是XNA/WPF 等 API 的设计并未考虑到这一点,因此经过优化,在初始化阶段设置一次投影,然后不再设置。
I would check out SlimDX, a much thinner DirectX wrapper than XNA or WPF
The problem with changing the projection on every frame is that API's like XNA/WPF werent designed with this in mind, so were optimized to have projection set once in the initialization phase, then not again.
我建议在这里进行混合选择:使用 WPF 发挥其擅长的功能(Windows UI、合成等)并使用 XNA 渲染 3D。有示例演示了 XNA 与 WinForms 的结合。应该可以使用相同的“技巧”将 XNA 渲染到 WPF 中的表面上。
更新:直接在 WPF 中使用 XNA 可能会出现问题。 此线程表示将 XNA 与 WinForms 一起使用,然后在 WPF 中托管 WinForms 控件是这些问题的解决方法。不过我自己还没有测试过这个(还)。
I would suggest a hybrid choice here: use WPF for what its good at (Windows UI, composition, etc) and use XNA to render the 3D. There are samples out there that demonstrates combining XNA with WinForms. It should be possible to do the same "trick" to render XNA onto surfaces in WPF.
Update: there are supposedly issues with using XNA directly with WPF. This thread indicates that using XNA with WinForms and then hosting the WinForms control in WPF is a workaround to these issues. I've not tested this myself though (yet).