Balder Silverlight 3 optimization – round 1

Working with Balder really gets me nostalgic. Nowadays, working with graphics programming one would choose OpenGL, DirectX or Xna to get real performant. Back in the days (mid 1990s), we didn't have the luxury of high-speed CPUs and dedicated 3D accelerated graphics adapters. Everything had to be done by the CPU. Balder has turned out to be just that kind of project, everything is done by the CLR and then the CPU.

Balder is now closing in on the beta stage, which means that we're getting close to the featureset we want to have for version 1 of the engine. While completing the features for the engine, we're also dabbling a little bit with optimizations. The true optimizations will happen in the final stages between beta and release, but its natural while working with features to increase performance on some parts of the engine. We've only scratched the surface of what is possible to optimize, the potential is great.

The first optimization we did was a couple of weeks ago, when getting Balder ready for Silverlight 3. Silverlight 3 introduces something called WriteableBitmap which gives access to a pixel buffer that can be manipulated pixel by pixel. After seeing the results from René Schultes speed tests, its obvious that WriteableBitmap is the right choice for the job, allthough I put quite a bit of work into the Png streamer.

Over the course of this weekend, I managed to get quite a bit of work done – focusing on optimizations. One of the focus areas we've been having is to get things running in parallel. Silverlight has great threading capabilities and are able to utilize multiple CPU cores very efficiently. In the release version of Silverlight 3, Microsoft has allowed for cross thread access to the pixels in a WriteableBitmap. This is good news for us. The previous version, the 0.8 alpha version, had one thread doing all the job. This was not exploiting the posibilities, and left the CPU pretty much doing nothing half the time. The new solution has 3 buffers and 4 threads, one thread for syncronizing all the work being done and one for each of the buffers. The buffers has special purpose; one for clearing, one for rendering and one for showing – showing being the copying of pixeldata to a WriteableBitmap. 

The flow is as follows: 


In addition to this, the rendering is no longer working on bytes for every color component, but writes an entire 32 bit int to the buffer for every pixel. These optimizations has truely paid off, on my computer with the regular teapot test (about 1000 polys), gives a framerate between 50 and 60. This is promising, considering we've hardly started optimizing at all.

A demo can be found here. It should look something like this:

17 thoughts on “Balder Silverlight 3 optimization – round 1

  1. Rene Schulte says:

    Sounds really great! It’s good to hear that you use multiple threads. This is really a huge benefit over Flash in time critcal applications.

  2. Rene Schulte says:

    Sounds really great! It’s good to hear that you use multiple threads. This is really a huge benefit over Flash in time critcal applications.

  3. Thanks.

    It really is benefiting from it. CPU utilization is now up at around 80%, so I guess we can still squeeze some juice out of it. I’m looking at a way to separate parts of the rendering into multiple threads as well. Could do all vertex calculations in one and all lighting math in another, have to see if it is practical and if it will gain any speed in doing it.

    Currently with the source as it is now, the scale have tipped from using most of the time in clearing and showing the pixels to actually spend most of the time in the renderer, so optimizing it would be the logical next step. I have an algorithm for rendering that I developed in 1996, targetting Pentium computers at that time, which was really fast. It will be the next step in the optimization. Also, I’ve implemented Frustum clipping in OpenGL, just need to port it from C++ to C# properly.

  4. Thanks.

    It really is benefiting from it. CPU utilization is now up at around 80%, so I guess we can still squeeze some juice out of it. I’m looking at a way to separate parts of the rendering into multiple threads as well. Could do all vertex calculations in one and all lighting math in another, have to see if it is practical and if it will gain any speed in doing it.

    Currently with the source as it is now, the scale have tipped from using most of the time in clearing and showing the pixels to actually spend most of the time in the renderer, so optimizing it would be the logical next step. I have an algorithm for rendering that I developed in 1996, targetting Pentium computers at that time, which was really fast. It will be the next step in the optimization. Also, I’ve implemented Frustum clipping in OpenGL, just need to port it from C++ to C# properly.

  5. Nirav Patel says:

    Hi,
    First of all thaks a lot for providing amazing tool. I am using the same tool in my silverlight 3 application. Will it work in silverlight 3?

    Currently on loading of .ase file an getting "Object Reference not set to an instance of object’ exception. Following is the statement which is throwing exception

    " Mesh mesh = ContentManager.Load<Mesh>("FileName.ASE"); "

    Please reply as soon as possible.

    Thanks & Regards,
    Nirav…

  6. Nirav Patel says:

    Hi,
    First of all thaks a lot for providing amazing tool. I am using the same tool in my silverlight 3 application. Will it work in silverlight 3?

    Currently on loading of .ase file an getting "Object Reference not set to an instance of object’ exception. Following is the statement which is throwing exception

    " Mesh mesh = ContentManager.Load<Mesh>("FileName.ASE"); "

    Please reply as soon as possible.

    Thanks & Regards,
    Nirav…

  7. Hi,
    the latest source at Codeplex is only for Silverlight 3, so getting that should get you going. We will put out binaries soon, just need to finish some code first.

    As for your exception. It seems that your Game class is not instantiated in the right way.
    Are you calling the TargetDevice.Initialize<>() with your game type as generic parameter?
    Please see tutorial:
    http://balder.codeplex.com/Wiki/View.aspx?title=Silverlight&referringTitle=Tutorials

    We have a couple of tutorials located here as well:
    http://balder.codeplex.com/Wiki/View.aspx?title=Tutorials

  8. Hi,
    the latest source at Codeplex is only for Silverlight 3, so getting that should get you going. We will put out binaries soon, just need to finish some code first.

    As for your exception. It seems that your Game class is not instantiated in the right way.
    Are you calling the TargetDevice.Initialize<>() with your game type as generic parameter?
    Please see tutorial:
    http://balder.codeplex.com/Wiki/View.aspx?title=Silverlight&referringTitle=Tutorials

    We have a couple of tutorials located here as well:
    http://balder.codeplex.com/Wiki/View.aspx?title=Tutorials

  9. Nirav Patel says:

    Hi Einar,
    Thanks for the quick response.

    For downloading the latest source code, I am seeing lot of change sets there. Can u tell me which one should I download for silverlight 3?

    Regarding exception, it occures while I call

    TargetDevice.Initialize<MyGame>(); from App.xaml and it goes to

    public override void LoadContent()
    {

    Mesh mesh = ContentManager.Load<Mesh>("filename.ASE");
    Scene.AddNode(mesh);

    }

    method from app.xaml. My .ASE file is in "Assets" folder only.

    One more question, is there any documentation guide using which I can customize it for my requirement?

    Is it an interactive tool? for example I perform some operation on 3D object and that make my application to perform some action accordingly.

    Thanks & Regards,
    Nirav

  10. Glad to help out.

    If you pick up the latest changeset, you’re set to go. It should be stable enough to be used.
    Did you set the property of the ASE file to be a Resource?

    I didn’t quite understand your last two questions? If you have features you’d like to see in Balder, you can add them on the issue tracker (http://balder.codeplex.com/WorkItem/List.aspx).

    As for interactivity, we have not implemented any interactivity yet, so you would have to do this yourself for now. We are planning to add functionality for handling mouse and keyboard input and possibly touch capabilities. We might also add functionality to easily rotate and scale objects interactively with mouse, keyboard and possibly touch.

  11. Glad to help out.

    If you pick up the latest changeset, you’re set to go. It should be stable enough to be used.
    Did you set the property of the ASE file to be a Resource?

    I didn’t quite understand your last two questions? If you have features you’d like to see in Balder, you can add them on the issue tracker (http://balder.codeplex.com/WorkItem/List.aspx).

    As for interactivity, we have not implemented any interactivity yet, so you would have to do this yourself for now. We are planning to add functionality for handling mouse and keyboard input and possibly touch capabilities. We might also add functionality to easily rotate and scale objects interactively with mouse, keyboard and possibly touch.

  12. Nirav Patel says:

    Hi,
    I have added .dll files from "Silverlight3" folder into my application. I have set properties of .ase file as mentioned in the tutorial. Now I am getting above exceptions. Actually there are two of them.

    1. Arithmetic operation is resulted in an overflow.
    2. Object reference not set to an instance of an object.

    Both of these error occurs in "MyGame" class when I instantiate the class from app.xaml.cs

    Please give your input.

    Thanks & Regards,
    Nirav…

  13. Nope says:

    Typo in Details: "Siverlight" does not parse.

  14. Nope says:

    Typo in Details: "Siverlight" does not parse.

  15. Hehe… Thanks for pointing that out. I guess I’ll have to fix that.. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *