I am doing some game-related rendering with Silverlight, and when I attach a pixel shader to an image that has a (rotational) transformation, I am seeing a strange, fuzzy, pixelation effect.
Here is a screenshot of the problem. The image on the left has just a transformation. The image on the right has a transformation and a pixel shader.
(source: andrewrussell.net)
You can see this in action here on my blog (click the Silverlight control to add the pixel shader).
The pixel shader in question is the one from SilverSprite used to tint an image's colour. You can view its source code here.
The transformation I am applying is a MatrixTransform
(with a hand-calculated translate, scale, rotate matrix). The problem appears when rotating the image.
The element that both the shader and the transform are being applied to is an Image
that is added to a Canvas
in code. The Image's ImageSource
is a WriteableBitmap
but the effect also happens with a BitmapImage
.
My question is: what is causing this fuzzy pixelation? and what can be done to reduce or remove it?
After watching this presentation from PDC09, I have a much better idea of how the rendering system in Silverlight works. This problem isn't directly addressed by the presentation, but knowing the rendering order of things helps.
The order of the rendering steps relevant to my question is: An object's children (and/or itself) are rendered, that rendering passes through the Effect
and then passes through the RenderTransform
.
It appears that in any case where a RenderTransform
is applied to an object where that object or its children have had an Effect
applied (ie: a RenderTransform
that comes after an Effect
in the rendering tree), that RenderTransform
is done in a "low quality" mode that produces this "fuzzyness".
The solution, then, is to move the Effect
to after the RenderTransform
. In my case this means putting the Image
on its own Canvas
, applying the RenderTransform
to the Image
, and the Effect
to the Canvas
.