WPF 3.5中抗锯齿效果不一致

9
我在使用FluidKit中的ElementFlow控件时遇到了奇怪的别名问题,这与WPF应用程序相关。我们正在工作中的一个应用程序中使用该控件来呈现内容,当ElementFlow的元素倾斜时,边缘会出现别名效果,如下图所示: Aliased edges 为避免出现别名效果,我们决定摆脱倾斜角度,因此我创建了一个快速测试应用程序,在其中将倾斜角度、项目间隙和弹出距离绑定到滑块上,以找出最佳外观。
然而,在使用相同设置的测试应用程序中,边缘被很好地抗锯齿: Anti-aliased edges 我假设在XAML层次结构的某个位置有某些设置控制了这一点,但我已经尝试在设计时和运行时(使用绑定和Snoop等工具)在各种元素和样式上设置SnapsToDevicePixels,但都没有成功。
ElementFlow的XAML如下:
<ListView.ItemsPanel>
    <ItemsPanelTemplate>
        <Fluid:ElementFlow
            x:Name="ContentElementFlow"
            SelectedIndex="{Binding SelectedIndex}"
            Focusable="True"
            TiltAngle="15.95"
            ItemGap="0.722"
            FrontItemGap="0.052"
            PopoutDistance="1.631"
            HasReflection="False"
            Background="Transparent"
            CurrentView="{StaticResource CoverFlowView}"
            ElementWidth="175"
            ElementHeight="250"
            >
            <Fluid:ElementFlow.Camera>
                <PerspectiveCamera
                    FieldOfView="60"
                    Position="0,0,6"
                    LookDirection="0,0,-6"
                    UpDirection="0,1,0"
                    />
            </Fluid:ElementFlow.Camera>
        </Fluid:ElementFlow>
    </ItemsPanelTemplate>
</ListView.ItemsPanel>

我也在两台不同的机器上尝试了这两个应用程序(一台运行XP Pro,一台运行XP Embedded,两者都有不同级别的专用图形),其中一个应用程序表现出锯齿,另一个应用程序则表现出反锯齿。

是否有人知道任何可以用来控制这种情况的设置或XAML属性?

4个回答

1

如果我没记错的话,在这种情况下,WPF 3.5存在一个关于别名的错误。我无论如何都找不到相关信息,但是从我记得的来看,这是由于WPF没有正确设置Direct X标志。

我记得发现,如果您将有问题的元素包装在某些类型的父元素中,似乎可以解决问题。例如,我认为将有问题的元素包装在空边框中可以解决问题?同样,我无论如何都找不到信息,但是如果我找到了,我会更新我的答案。

我想您看到的应用程序之间的差异与此有关。在显示别名的应用程序中,ItemTemplate中的项目是否被包装在某种父元素中(而测试应用程序则没有)?反之亦然吗?

很抱歉我不能提供更多帮助,仍在寻找信息,但我的谷歌能力今天似乎很弱。

更新:好的,我找到了我想到的东西。

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7382637b-b4bc-4a46-8bed-f36250a65385/

这与效果有关,所以也许不是你看到的同一件事情,但值得一试。


感谢这篇文章。我尝试在测试和实际应用程序中更改了一些布局容器,但无法解决别名问题,不过可能值得进一步深入研究。 - jeffora
鉴于视觉树的深度/复杂性是这些应用程序之间唯一的区别,我会假设这是正确答案,直到我有时间进一步测试为止。谢谢。 - jeffora
1
FluidKit ElementFlow是一个Viewport3D。以上所有内容都不适用于WPF 3D。 - bitbonk

1
需要考虑的一件事是ElementFlow控件的位置。如果它的排列矩形不在整个像素上,那可能会引起一切混乱。SnapToDevicePixels不能帮助排列矩形。
这通常发生在使用TextBlocks时,因为它们的高度/宽度通常不是整数。
在.NET 4中,有一个新的FrameworkElement.UseLayoutRounding可以解决这个问题。

1
这是WPF 3D的一个常见问题。FluidKit的ElementFlow使用了WPF 3D。控件中的项是实际的3D对象(Viewport3D,ContainerUIElement3D)。亚像素渲染问题、LayoutRounding和SnapToDevicePixels不适用于3D内容。当性能不足时,WPF会恢复到锯齿状的Viewport3D内容。因此,最可能的情况是您有问题的应用程序正在消耗过多的资源(CPU、GPU、内存)。我的经验是,在Windows XP下,这种情况发生得更加频繁,而在Vista/Windows 7下则较少。对于Windows XP,设置抗锯齿注册表键有一定帮助。除此之外,改善应用程序的性能以外,您没有太多可以做的了。

你有这方面的参考资料吗?该应用程序在嵌入式设备上运行Atom处理器和Radeon移动图形,以及在桌面机器上运行i7处理器和Radeon 4550图形卡上演示了这个问题,并且在使用时都没有显示出实质性的CPU负载。 - jeffora
我们在这里做了很多关于WPF 3D的工作,我们经常看到这种情况。抗锯齿神奇地停止工作了。我们认为这一定与资源使用有关,因为我们大多数情况下都可以通过减少应用程序启动期间的资源来解决它。 - bitbonk
嗯,有趣。不幸的是,我们目前没有资源来进一步调查此事。我已经为你的答案点赞,并在有机会时一定会重新审视这种情况。感谢提供信息。 - jeffora

0

来自微软的 Brendan Clark 说:

当您尝试在子像素位置绘制内容时,就会出现此类错误。如果您尝试在半个像素边界上绘制一条线,则 WPF 通常会对该线进行反锯齿处理,以使其在包含它的两个像素上混合(这会导致它变得不太清晰、更轻或“模糊”)。如果您强制使用锯齿渲染,则位于子像素边界上的线条有时会完全绘制在一个像素内;其他时候,四舍五入会使它们消失。

您尝试设置不同的 ElementHeight 值了吗?


谢谢您的建议,我之前尝试了类似的多种方法,但都没有成功。通过修改ElementHeight,我能让测试应用程序变得更平滑,但实际的应用程序还无法抗锯齿。 - jeffora

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接