【问题标题】:Inconsistent anti-aliasing in WPF 3.5WPF 3.5 中不一致的抗锯齿
【发布时间】:2011-03-27 13:49:51
【问题描述】:

我在使用 FluidKit's ElementFlow 控件的 WPF 应用程序中遇到奇怪的别名行为。我们在应用程序中使用控件来呈现内容,当 ElementFlow 的元素倾斜时,边缘别名如下图所示:

为了避免混叠,我们决定摆脱倾斜角度,所以我创建了一个快速测试应用程序,我将倾斜角度、项目间隙和弹出距离绑定到滑块,以便找出看起来最好的.

但是,在使用相同设置的测试应用中,边缘的抗锯齿效果很好:

我假设在 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 属性?

【问题讨论】:

    标签: .net wpf antialiasing


    【解决方案1】:

    如果我没记错的话,WPF 3.5 中有一个关于这种情况下的别名的错误,我终生无法找到相关信息,但据我所知,这是一个未设置的 Direct X 标志WPF 正确。

    我记得我发现如果你将有问题的元素包装在某些类型的父元素中,它似乎可以解决问题。例如,我认为将违规元素包装在空边框中可以解决问题吗?同样,我终生无法再次找到该信息,但如果我找到它,我将更新我的答案。

    我认为您在应用程序之间看到的差异与此有关。在显示别名的应用程序中,ItemTemplate 中的项目是否包含在某种父元素中(作为测试应用程序,它们不是)?还是反过来?

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

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

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

    这与效果有关,所以也许这与您看到的不一样,但值得一试。

    【讨论】:

    • 感谢您的文章。我尝试在测试和真实应用程序中更改一些布局容器,但无法更改别名问题,但可能值得更深入地研究。
    • 鉴于视觉树的深度/复杂性是应用程序之间的唯一区别,我将假设这是正确的答案,直到我有时间以一种或另一种方式进一步测试。谢谢
    • FluidKit ElementFlow 是一个 Viewport3D。以上所有内容均不适用于 WPF 3D。
    【解决方案2】:

    要考虑的一件事是 ElementFlow 控件的位置。如果它的排列矩形不在整个像素上,那可能会抛弃一切。 SnapToDevicePixels 对排列矩形没有帮助。

    这通常在您使用 TextBlock 时发生,因为它们的高度/宽度通常不是整数。

    在 .NET 4 中,有一个新的 FrameworkElement.UseLayoutRounding 可以解决此问题。

    【讨论】:

      【解决方案3】:

      这是 WPF 3D 的常见问题。 FluidKit 的 ElementFlow 使用 WPF 3D。控件中的项目是实际的 3D 对象(Viewport3D、ContainerUIElement3D)。子像素渲染问题、LayoutRounding 和 SnapToDevicePixels 不适用于 3D 内容。当性能不正确时,WPF 将恢复为别名 Viewport3D 内容。所以很可能你的有问题的应用程序消耗了太多的资源(CPU、GPU、内存)。我的经验是,这种情况在 Windows XP 下比在 Vista/Windows 7 下更频繁地发生。对于 Windows XP,设置antialiasing registry key 会有所帮助。除了提高应用性能之外,您无能为力。

      【讨论】:

      • 你有这方面的参考资料吗?该应用程序在运行 Atom 处理器和 Radeon 移动显卡的嵌入式设备以及运行 i7 处理器和 Radeon 4550 显卡的台式机上都展示了这个问题,并且两者都没有展示出大量的 CPU 负载。
      • 我们在这里做了很多 WPF 3D 并且我们经常看到这种行为。抗锯齿神奇地停止了工作。我们假设它必须与资源使用有关,因为我们通常可以通过在应用程序启动期间减少资源来解决它。
      • 嗯,很有趣,很遗憾,我们目前没有资源可用于进一步调查此事。我赞成你的回答,当我有机会时肯定会重新审视这种情况。感谢您的信息。
      【解决方案4】:

      来自 MSFT 的 Brendan Clark 说:

      当您尝试 在子像素位置绘制内容。 如果你试图在一个 半像素边界,WPF通常会 抗锯齿线以将其混合 包含它的两个像素(其中 导致它变得不那么锋利, 更轻,或“模糊”)。如果你强迫 混叠渲染,子像素上的线条 有时会最终绘制边界 完全在一个像素内;其他时间 四舍五入将使得 他们消失了。

      您是否尝试为 ElementHeight 设置不同的值?

      【讨论】:

      • 感谢您的建议,我之前尝试过各种类似的方法都无济于事。修改 ElementHeight 我能够将测试应用程序设置为别名,但不能将实际应用程序设置为抗锯齿
      猜你喜欢
      • 2014-02-18
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 2012-12-23
      • 1970-01-01
      • 2016-06-28
      • 2011-07-05
      • 2014-03-19
      相关资源
      最近更新 更多