CPU and memory Optimizations concerning shaders in Silverlight

Aucun commentaire

Recently, I had to use Silverlight shaders for my personal needs, that article explains memory and CPU usage when you define shaders on objects.

First, each time you apply one of the shaders provided by default (DropShadow and Blur) on a UIElement, actually you generate two bitmaps into RAM at runtime. The first bitmap is a simple rasterization of the UIElement, the second bitmap is that bitmap with the effect applied to it. In terms of performance, that behavior, wich is logic, can lead to some issues if you don't take care about few points :

First, we can calculate the memory used by an effect applied to a 200 * 200 UIElement. We consider that each pixel (40000) are encoded into 4 bytes :

  • Alpha is coded on 1 byte (called octet in french) and 8 bits, leads to 256 possible values from 0 to 255 or 0x00 to 0xFF in Hexadecimal
  • Red | 1 byte | 8 bits | 0xFF | 0-255
  • Green | 1 byte | 8 bits | 0xFF | 0-255
  • Blue | 1 byte | 8 bits | 0xFF | 0-255

The first rasterized bitmap is contained by the RAM as it is made at runtime. As there's no compression for it you can calculate his weight with the formula below :
PixelsWidth * PixelsHeight * 4 Bytes = total weight of the intermediate bitmap in RAM

In our case the bitmap is about 160 Kbyte, but it's just the first bitmap. The second will at least take 160 kBytes plus extra size needed to render effect. The total size is about 400 kbyte if you consider that these effect create a bigger rendered surface area than the original bounding box does.

Concerning customs pixels shaders, the behaviors is slighty different as there's a direct rasterisation wich creates by the way, a single bitmap into memory. This is a pretty good advantage in terms of memory usage but CPU usage increases. Indeed, the intermediate bitmap is here to aleviate CPU as it avoid to calculate it each time for translate transforms. When you translate an UIElement wich displays an effect, the intermediate bitmap is not recreated. For other operations, it is always regenerated. For example, if you decide to animate the scale or rotation or skew of a rectangle, the intermediate bitmap will be recreated each time. For a 60 max fps, Silverlight will create about 60 intermediate bitmaps and 60 bitmaps with final effect. Designers and developers must take care about that, as memory and CPU charge could increase drasticly and reduce performances... To avoid or limit that behavior, Microsoft has limited the max size of an effect to 2048 pixels for width and height.

All bitmaps, including intermediates, hang around for the life of the Effect+UIElement pairing. When the Effect is removed or a UIElement destroyed, all surfaces are released at once. CacheMode (bitmap cache) or 3D usage will create intermediate bitmaps in every way.

Jason Prado in charge at Microsoft on that topic kindly helps me to clarify some Silverlight behaviors concerning shaders. You will find some best practices below :

* Smaller area is better.

* The most important thing is to not trigger rerasterization of a UIElement. Rerasterization means we have to run the effect again, and both of these steps are expensive. Many changes, e.g. changing the color of a Rectangle, trigger rerasterization.

* Don't run effects on elements that change every frame. Trigger rerasterization as rarely as possible..

* BlurEffect is slow. It's a separated two-pass gaussian blur, but it is still an inherently slow operation if you want visual quality that is at all passable. Keep the radius low. At Radius >= 10, you start to notice serious performance degradation.

Bookmark and Share

CustomControl ColorChooser and ColorPicker

Aucun commentaire

Hi, I recently have to find a solution create two customs controls

I recently needed controls customizable type ColorPicker ColorChooser and, finding none, I have designed from scratch, here's a demo.

Install Microsoft Silverlight

They are in beta but I think provide a final version by November 15. In the meantime, if you want to test those controls and download the dll to test in SL3 is here.

Ps: the Silverlight plugin for wordpress provided by Tim Heuer, is powerful and useful, so thank you to him, I will only use this solution from now.

Bookmark and Share

3DLightEngine Library preview

4 commentaires

I will quickly provide an opensource (ms-pl) library named LightEngine3D. The main goal is to achieve basics 3D scenario that Plane projection can't solve easily. By the way, it is based on Silverlight Matrix3D structure. Automatic Z-sorting, backface culling, Camera, Vector3D ( and maybe directionnal light) will be include and managed without the need of 3D knowledge. The final release will be lite and extensible.

The code for that example is very simple :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//we define a 60 degres angle
double FovY = Matrix3DUtils.DegresToRadians(60); 
//default displayed bitmap
Uri BitmapUri= new Uri("Blend3_logo3.jpg", UriKind.Relative);
 
Element3D E3D;
 
Scene3D s;
 
public MainPage()
{
   // Required to initialize variables
   InitializeComponent();
 
   ResetBtn.Click += new RoutedEventHandler(ResetBtn_Click);
 
   E3D = new Element3D(MonUIElement);
 
   E3D.NormalDirectionChanged += new Element3D.DirectionChanged(E3D_NormalDirectionChanged);
 
   E3D.DotProductChanged += new Element3D.DirectionChanged(E3D_DotProductChanged);
 
   #region Personalize perspective and ViewPort
   /*
   Perspective p = new Perspective(FovY,		            //Field of view
   LayoutRoot.ActualWidth / LayoutRoot.ActualHeight,   //ratio
   1.0,                                                //near clip plane 
   3000.0);                                            //far clip plane
 
   Viewport v = new Viewport(LayoutRoot.ActualWidth, LayoutRoot.ActualHeight);
 
   s = new Scene3D(LayoutRoot, p, v);
   */
   #endregion
 
   #region Personalize clip plane
   /*
   s = new Scene3D(LayoutRoot, FovY,1,3000);
   */
   #endregion
 
   #region Personalize Field of view angle
   s = new Scene3D(LayoutRoot, FovY);
   #endregion
}
 
//dot product change event handler
void E3D_DotProductChanged(Element3D sender, int normalDirection)
{
   ProduitScalaireTxt.Text = sender.DotProduct.ToString();
}
 
//normal direction change event handler
void E3D_NormalDirectionChanged(Element3D sender, int normalDirection)
{
   DirectionTxt.Text = normalDirection.ToString();
   Uri BitmapUri = normalDirection == 1 ? new Uri("Blend3_logo3.jpg", UriKind.Relative) : new Uri("Blend3_logo.jpg", UriKind.Relative);
   MonUIElement.Source = new BitmapImage(BitmapUri);
}
 
private void onTranslateXChange(object sender, RoutedPropertyChangedEventArgs<double> e)
{
   E3D.GlobalOffsetX = e.NewValue;
   s.RenderScene();
}
//

You just have to instanciate Element3D and pass the FrameworkElement in the constructor
Il suffit d'utiliser la classe enveloppante Element3D et d'instancier une nouvelle scène. I will add very quickly ContainerElement3D class. By default the object is not in a container but directly in the Scene3D. This example shows that it is relatively simple to extend the existing capabilities of Silverlight in 3D. The next step, make some features of DirectX ...

Bookmark and Share

ProxyRenderTransform Library v2

Aucun commentaire

proxyRenderTransform.jpg
I've just released V2 of ProxyrenderTransform. ProxyRenderTransform use extensions methods to allow easy access to renderTransforms nodes. These are difficult to target by C# when they are not named. If you add the reference ProxyRenderTransform.dll, you will easily reach RenderTransform for any FrameWork element by extensions methods :

  • SetX / GetX
  • SetScaleX / GetScaleX
  • SetRotate / GetRotate
  • SetSkewX / SetSkewY

You can get PropertyPath corresponding the way Blend create RenderTransformGroup via static properties

  • _SCALE_X_PATH // (UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)
  • _SCALE_Y_PATH
  • _SKEW_X_PATH
  • _SKEW_Y_PATH
  • _ROTATE_PATH
  • _TRANSLATE_X_PATH
  • _TRANSLATE_Y_PATH

You can also get reference to transform nodes themselves

  • GetScaleNode
  • GetTranslateNode
  • GetRotateNode
  • GetSkewNode

there's an example below :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Page_Loaded(object sender, RoutedEventArgs e)
{
//any FrameworkElement can now have direct access to his RenderTransform
rec.SetX(605);
Debug.WriteLine( rec.GetX());
//rec.SetX(105);
//rec.SetRotate(60);
//rec.SetScaleX(2);
 
dp.Interval = TimeSpan.FromMilliseconds(10);
dp.Tick += new EventHandler(dp_Tick);
dp.Start();
}
 
void dp_Tick(object sender, EventArgs e)
{
double newX = (double)rec_Copy.GetX() ( 500 - (double)rec_Copy.GetX() ) * .2;
rec_Copy.SetX(newX);
}

In that release, you will have access to 3D projection plan too...

You can get library under MS-PL licence on Code Plex here.
Don't hesitate to send me an email or post a comment if you encounter bugs or difficulties when you use it :)

Bookmark and Share

ProxyRenderTransform Library and Extensions methods

Aucun commentaire

As you maybe already know, since C# 3 extensions methods are availables. Their goal is pretty simple : they permit to extend natives' object capabilities. extensions methods must be contained in static class and are also static. That's the example shows below :

static class MyExendsMethods
{
public static bool IsBiggerThan (this int myInt, int compare){ return myInt &gt; compare; }
}

You will notice the use of keyword "this" for the first parameter. It means that it will impact integers the second parameters is, in fact, the first parameter of the method IsBiggerThan when it will be called :

int monEntier = 37;
bool myBoolean = monEntier.IsBiggerThan ( 13 );

recently, I used extensions methods to allow easy access to renderTransforms nodes. These are difficult to target by C# when they are not named
if you add the reference ProxyRenderTransform.dll, you will easily reach RenderTransform for any FrameWork element by extensions methods : SetX, GetX, SetScaleX, GetScaleX, etc...
download ProxyRenderTransform library on Code Plex.
Don't hesitate to send me an email or post a comment if you get bugs or difficulties when you use it :)

Bookmark and Share

Using Reflection Api in Silverlight

Aucun commentaire

Recently i needed to get static method contained by a Class to display their visual result.
Indeed The idea was to display Robert Penner's Equation used by tweened. For doing such task you just have to use Reflection Api provided by Silverlight Framework that you can find in System.Reflection package. You will find the code I used in this article. Read more »

Bookmark and Share

Penner’s Equations Tweened show

2 commentaires

You can find here the visual behavior of penner's equations, you will notice that some missing. You can find TweenedEquations here.

Bookmark and Share

Tweened Library for Silverlight 2 is released

8 commentaires

I put online Version 2 of Tweened. Tweened is an open-source CSharp 3 Animations generation library more oftenly called Tweens. Tweened is licensed under GNU General Public Licence v3.

The main purpose of this project is to provide a very simple way to animate any Xaml Objects you want in Silverlight 2. To reach this goal you just have to Reference Tweened.dll in a Silverlight 2 project. You will have access to color, RenderTransform and simple propertie Animation easily with many options like AutoReverse , BeginTime , SpeedRatio,etc...

It's released and maintained for Silverlight 2 or higher. In layman's terms, Tweened helps you move things around on the screen using only code, instead of the timeline. The general idea of a tweening Class is that dynamic animation and transitions (created by code) are easier to maintain and control, and more stable than animation based on the regular Silverlight timeline. The Tweened syntax is created with simplicity of use in mind, while still allowing access to more advanced features.

the general idea is to make doable the automatic creation of Storyboards resources type. Internally class Tween operates two Storyboards, the first is used for animation to go, the other is used if necessary to animation back. Storyboards Each of these contains a number of objects DoubleAnimation XAML. They serve as animated sequences. Each DoubleAnimation refers to an Xaml object and a lively targeted property, for example X or ScaleX. So a tween can animate lot of objects in several different equation of movement with different duration and behavior. For example a double animation could loop.

URL :: http://library.tweened.org/
Online Documentation :: http://library.tweened.org/doc/html/
Chm Documentation :: http://library.tweened.org/doc/Tweened.chm

Bookmark and Share

VisualStateManager available in Blend 2 SP1 for WPF projects

Aucun commentaire
Visual State Manager

Visual State Manager

Until now VisualStateManager was a Silverlight 2 projects feature( You will find french video on how it works here ) but now with the WPF ToolKit you will find here, it's possible to create Blend 2 projects including WisualStateManager. To get this feature I encourage you to go here where you will find full explanations. It's a very good news that permit to understand the direction blend 2 has taken. For myself I have tried it et all work perfectly but there's no a real integration into controls as we have in Silverlight 2 Projects. Of course you can create States in Controls but they are not defined by default in the Design view.

Bookmark and Share

« Previous Page