views:

273

answers:

4

I am getting strange aliasing behaviour in a WPF app using FluidKit's ElementFlow control. We are using the control in an app at work for presenting content, and when the elements of the ElementFlow are tilted, the edges alias as per the following image: Aliased edges

In order to avoid the aliasing, we decided to get rid of the tilt angle, so I created a quick test app where I bound the tilt angle, item gaps, and popout distance to sliders so I could find out what looked best.

However, in the test app using the same settings, the edges are nicely anti-aliased: Anti-aliased edges

I am assuming there is some setting somewhere up the XAML hierarchy that is controlling this but I've tried setting SnapsToDevicePixels on various elements and styles, both at design time and run time (with bindings and tools like Snoop) to no avail.

The XAML for the ElementFlow is as follows:

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

I've also tried both apps on two different machines (one running XP Pro, one XP Embedded, both have differing levels of dedicated graphics) and both demonstrate aliasing in one app and anti-aliasing in the other.

Does anyone know of any setting or XAML attribute that can be used to control this?

A: 

Brendan Clark from MSFT says:

Errors like this occur when you try to draw content at subpixel positions. If you attempt to draw a line on a half pixel boundary, WPF will normally anti-alias the line to blend it across both pixels containing it (which causes it to become less sharp, lighter, or "blurry"). If you force aliased rendering, lines on subpixel boundaries will sometimes end up drawn entirely within a pixel; other times the rounding will work out so that they disappear.

Have you tried to set different values to ElementHeight?

Ike
Thanks for the suggestion, I had previously tried various approaches similar to this to no avail. Modifying ElementHeight I was able to get the test app to alias, but not the actual app to anti-alias
jeffora
+1  A: 

If I remember correctly there is a bug in WPF 3.5 regarding aliasing in this scenario, I can't for the life of me find the relevant information, but from what I remember it was a Direct X flag that was not being set correctly by WPF.

I remember finding that if you wrap the offending element in certain types of parent elements it seemed to fix the problem. For instance I think wrapping the offending element in an empty border fixes the problem? Again, I can't for the life of me find the information again, but if I find it I will update my answer.

I assume the differences you are seeing between applications are related to this. In the app that show aliasing are the items in the ItemTemplate wrapped in some sort of parent element (where as the test app they are not)? Or vice-a-versa?

Sorry I can't be of more help, still looking for the information but my Google powers seem weak today.

UPDATE: Ok I found what I was thinking of.

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

This was related to effects so maybe this isn't the same thing you are seeing but worth a shot.

Foovanadil
Thanks for the article. I tried changing a few layout containers in both the test and real app and was unable to change the aliasing issue, but it might be worth looking into more deeply.
jeffora
Given that the depth/complexity of the visual tree is the only difference between the apps I'm going to assume this is the correct answer until I have time to test further one way or another. Thanks
jeffora
The FluidKit ElementFlow is a Viewport3D. All of the above does not apply for WPF 3D.
bitbonk
A: 

One thing to consider is the location of the ElementFlow control. If it's arrange rect isn't on a whole pixel, that may throw off everything. SnapToDevicePixels will not help with the arrange rect.

This generally happens when you use TextBlocks, since their heights/widths are generally not whole numbers.

In .NET 4, there is a new FrameworkElement.UseLayoutRounding that fixes this issue.

Tom Goff
+1  A: 

This a common problem of WPF 3D. FluidKit's ElementFlow uses WPF 3D. The items in the control are acutal 3D objects (Viewport3D, ContainerUIElement3D). Subpixel rendering issues, LayoutRounding and SnapToDevicePixels do not apply to 3D content. WPF reverts to aliased Viewport3D content when the performance is not right. So most likeley your problematic app is consuming too much resources (CPU, GPU, memory). I have made the experience that this happens much more freqeuntly under windows XP than under Vista/Windows 7. For Windows XP it helps a bit to set the antialiasing registry key. Other than that and improving the perfomance of your app, there is not much more you can do about it.

bitbonk
Do you have references for this? The app demonstrates this problem on both an embedded device running an Atom processor and Radeon mobility graphics, as well as a desktop machine running an i7 processor and Radeon 4550 graphics card, and neither demonstrate a substantial CPU load under use either.
jeffora
We have done a lot of WPF 3D around here and we have seen this behavior very frequently. Antialiasing magically stopped working. We assumed that it must have to do something with the resource usage because we mostly could solve it by decreasing resource **during startup** of the application.
bitbonk
Hmm interesting, unfortunately we don't have the resources to allocate to further investigation in this matter at this time. I've upvoted your answer and will definitely revisit the situation when I get the chance. Thanks for the info.
jeffora