Ab3d.DXEngine maintenance update available

by abenedik 15. March 2016 10:51

I would like to inform you that a smaller maintenance update for Ab3d.DXEngine has been published.

The update does not add new functionality to the rendering engine. It improves the performance of the engine and fixes a few issues.

The following is a list of changes:

  • Greatly improved performance of WireframeVisual3D when the 3D objects showing with WireframeVisual3D are animated with changing transformations.
  • Prevented black edges that sometimes appeared when showing textures.
  • Fixed rendering transparent objects that were not visible sometimes because of incorrect object order.
  • Fixed rendering specular highlight for directional light shader.
  • Fixed getting camera's view and projection matrices for left handed coordinate system (when IsRightHandedCoordinateSystem is false).

Tags: , ,


New version of svg reader for .Net applications published

by abenedik 8. March 2016 21:34

I am happy to announced that a new version of Ab2d.ReaderSvg is available.

textPath svg element shown in ViewerSvg

As shown in the image above, the ReaderSvg now supports textPath svg element that positions text on a referenced path element.

Another very interesting new feature is a new GetElementSvgText method that returns the original svg text of the element specified with its name. This way it is possible to read data from svg file that are not recognized by ReaderSvg. The following image shows svg text for the selected element in ViewerSvg:

Showing svg text from selected element in ViewerSvg

There are also some other great new features and fixes:

  • Added support for vertical text (glyph-orientation-vertical svg property).
  • Improved support for rounder corners on rectangles in case when only rx or only ry is specified - in this case the other value is set to the same value.
  • Fixed reading text decorations (Underline and Strikethrough).
  • Added support for reading metafiles embedded into image's base64 encoded string.
  • Added support for reading images in foreignObject created in Microsoft Visio.
  • Added ReadForeignObjects property to Ab2d.ReaderSvg that enables or disables reading foreignObject elements (enabled by default).
  • Added support for reading data from number lists that end with comma - for example the following string in svg file was not read: "12, 34, 56,".
  • Improved writing images in XAML. They are now written in more clear format. Also fixed setting Source for images that are created from foreign objects.
  • Fixed writing new line characters in XAML.


As alwasy, the customers can get the latets version from their User Account page. Others can try the new version with downloading the evaluation version.

And if yuo find a svg file that is not read correctly, please send it to me and I will my best to improve ReaderSvg.



Rendering reflections and many other great new features with new versions of Ab3d.DXEngine and Ab3d.PowerToys

by abenedik 11. February 2016 23:01

The new version of Ab3d.DXEngine brings three big new features:

  1. Added support for rendering reflections with environmental and reflection maps.
  2. Added support for rendering unlimited number of lights with using multi-pass rendering.
  3. Improved rendering instanced objects with adding support for rendering many instances of Model3DGroup objects. Simplified hit testing on instanced objects with a new GetHitInstanceIndex method.

Rendering DirectX reflection in .Net with Ab3d.DXEngine


The Ab3d.PowerToys library also got some great new features. Some of the main new features are:

  1. Added ModelRotatorVisual3D that allows users to rotate selected 3D model. Improved ModelMoverVisual3D so that it also works in Ab3d.DXEngine.
  2. Greatly reduced the initialization time when creating many instances of SphereVisual3D and BoxVisual3D objects.
  3. Simplified working with hierarchically organized 3D models with new model iterators.

Rotating 3D models with ModelRotatorVisual3D

Let’s see some more details about the new features.</p> <p>Showing reflections pushes the boundaries of what is possible to achieve with WPF 3D API even further. The above image with reflective teapot shows a fully reflective 3D model. The level of reflection can be adjusted and specified for the whole object. Or, it can be specified for each part of the model with using a reflection map. The following image shows that is action (the reflection map is shown on the right):

Using DirectX ReflectionMap to specify reflection for each part of the 3D model

The handle and top of the teapot are shown with green color (specified in the teapot’s texture on the bottom image) and do not reflect the environment – those parts are almost black on the reflection map (upper image). But the rest of the teapot is fully reflective – defined by white color on the reflection map (in the bottom 1/3 of the image and on the smaller white rectangle on the right side).

To support scenarios where additional DXEngine properties need to be added to the existing WPF objects, the new version of Ab3d.DXEngine introduces a new set of extensions methods that allow adding additional attributes to WPF objects. 

For example the following two lines set EnvironmantMap and ReflectionMap to an existing WPF material:

usedMaterial.SetDXAttribute(DXAttributeType.Material_EnvironmentMap, _dxCubeMap);
usedMaterial.SetDXAttribute(DXAttributeType.Material_ReflectionMap, bitmapImage);

The new version of Ab3d.DXEngine also adds support to render unlimited number of lights. Previous version supported rendering only 16 lights + ambient light. This limit is now lifted with using multi-pass rendering. This means that when there are more than 16 lights in the scene it is rendered multiple times – each time different 16 lights are used and then all the rendered scenes are combined into the final image. The following screenshot shows a sample that animates the intensity of 64 PointLights:

Rendering many lights with using multiple-pass rendering

Multi-pass rendering is great for such scenarios. But it also has some disadvantages. If you need to use many lights, please check the additional comments in the “Many lights” sample.


I would also like to write a few words about new object instancing capabilities.

Object instancing is the ultimate performance optimization – if you show really many 3D objects and you convert your code to use object instancing than you have almost reached the peak of the performance. Some additional performance gains are still possible with tweaking the shaders, but most of the work was already done.

The trick is that when object instancing is used, the applications sends one mesh geometry to the graphics card and then tells it to render it many times – for each instance of the mesh you can specify different color and different transformation. Because the data about all the instances is send in one draw call, this can be done very quickly on the CPU. So the usual performance problem where GPU waits for the CPU to send commands is completely eliminated. 

Because instancing is so great for improving performance, the new version also allows you to render many instances of Model3DGroup objects (and not only many instances of MeshGeometry3D). The following screenshot shows many instances of RobotArm model:

Rendering many instances of Model3DGroup

Another improvement with instancing is that a GetHitInstanceIndex method was added to the InstanceData class. That method can be used in hit testing to get the index of the hit instance. This way you can easily connect the hit object with the background data that are connected to the hit instance.

If you are rendering many 3D objects, I would really advice you to try to convert your code to use instancing. You will be amazed on how fast the graphics cards can become when they are not waiting for the CPU (a newer graphics card recommended).


There are still lots of other new features and fixes. Also Ab3d.PowerToys library has been greatly improved.

But I do not want to make this blog post too long. 

To check new features in action, please check the new samples that come with the libraries. And for the record here are the full list of changes:


Ab3d.DXEngine v1.2:

  • Added support for rendering reflections with using EnvironmentalMaps
  • Added support for ReflectionMaps
  • Added support for rendering more than 16 lights (+ ambient light) with using multi-pass rendering.
  • Added support for Transform on InstancedMeshGeometryVisual3D
  • Added InstancedModelGroupVisual3D that can render many instances of all 3D models defined in the Model3DGroup.
  • Added GetHitInstanceIndex method to InstanceData to get an index of hit instance
  • Fixed showing transparent objects in some cases
  • Added TextureBlendState to IDiffuseTextureMaterial interface
  • Fixed rendering textures from files that use different DPI settings
  • Added extension methods that simplify adding additional DXEngine attributes to the existing WPF's objects (SetDXAttribute, GetDXAttributeCollection, GetDXAttribute, IsDXAttributeSet, ClearDXAttribute, GetDXAttributeOrDefault). This is currently used to specify the EnvironmentalMap and ReflectionMap.
  • Prevented memory leak when 3D model that was shown inside WireframeVisual3D was changed (further performance improvements in this case will follow).
  • Prevented rendering strange 3D lines that sometimes occur when the 3D lines were completely behind the camera
  • Fixed rendering transparent 3D lines
  • Fixed rendering transparent objects with emissive materials
  • Some other smaller bug fixes and improvements

The InstancedGeometryVisual3D was renamed into InstancedMeshGeometryVisual3D – the renaming was needed because a new InstancedModelGroupVisual3D was introduced and the previous name did not describe the class well enough.


Ab3d.PowerToys v7.4:

  • Added ModelRotatorVisual3D that allows user to rotate selected Model3D around any axes.
  • Added SubscribeWithEventManager3D method to ModelMoverVisual3D and ModelRotatorVisual3D to allow them to use EventManager3D for processing mouse events. This allows using the ModelMoverVisual3D and ModelRotatorVisual3D in Ab3d.DXEngine.
  • Greatly reduced the initialization time when creating many instances of SphereVisual3D or BoxVisual3D objects
  • Added ModelIterator class and two extension methods (ForEachVisual3D and ForEachGeometryModel3D) to simplify working with hierarchacly organized 3D models.
  • Added FitIntoView and GetFitIntoViewDistanceOrCameraWidth methods to TargetPositionCamera, SceneCamera, TargetRect3DCamera and ThirdPersonCamera. The method has greatly improved algorithm then it was available in the "Scene Editor" sample in the previous versions of Ab3d.PowerToys.
  • Fixed showing transparent 3D lines when LineColor's alpha value is less than 255.
  • Improved support for TextureCoordinates in ModelOptimizer
  • Added WidthDirection and HeightDirection to WireGridVisual3D that allows to set custom direction of the WireGrid (not only horizontal or horizontal in another coordinate system)
  • Added CreateWireGrid to Line3DFactory that allows creating WireGrid object with custom widthDirection and heightDirection vectors.
  • Added GetTargetViewport3DSceneBounds method to all Camera classes in Ab3d.PowerToys – the method calculates the scene bounding box
  • Change validation of Size property on BoxVisual3D, WireBoxVisual3D, MultiMaterialBoxVisual3D and PyramidVisual3D to allow having one component of size zero.
  • Fixed calculating scene size in SceneCamera when the scene hierarchy is complex
  • Added GetBounds and CombineTransform methods to Ab3d.Utilities.ModelUtils
  • Added CompositionRenderingHelper to help work with CompositionTarget.Rendering (allowing subscribed objects to be recycled by Garbage Collection and therefore preventing infinite rendering subscription in case when the Rendering is not unsubscribed)
  • Improved ModelMoverVisual3D so that it can also use EventManager3D for mouse event processing - this allows using ModelMoverVisual3D inside Ab3d.DXEngine.
  • Prevented throwing "Object reference" exception in ModelOptimiter that could occur sometimes when ImageBrush is used.
  • Added HeightDirection to TubeVisual3D and TubeMesh3D – this allows orienting the object in any direction and not only in up (0, 1, 0) direction.
  • Fixed throwing exception when Is3DAxesShown is initially set to false on CameraAxisPanel
  • Added "Custom Up Axis" sample that shows how to show data in another coordinate system - for example where Z is up.
  • Added "Perspective Transformation" sample that shows how to convert 3D positions to the 2D positions on the screen

Moved the ModelMovedEventArgs class from Ab3d.PowerToys.Common to Ab3d.Common namespace

Tags: , , , , ,

Ab3d.PowerToys | DXEngine

Greatly improved performance, new features and a new real-time HLSL shader editor come with new versions of Ab3d.DXEngine and Ab3d.PowerToys

by abenedik 3. December 2015 23:01

New versions of Ab3d.DXEngine and Ab3d.PowerToys libraries have been published.

The new versions bring improved performance, new features and many bug fixes. 

But let me talk about that later and start with a very interesting new sample that comes with Ab3d.DXEngine – a real-time HLSL shader editor. The following screenshot shows it in action:

Real-time shader editor in Ab3d.DXEngine

On the left side you can see the HLSL editor with full syntax highlighting. The editor is using great AvalonEdit component. The right side shows some options and a real-time preview of the 3D scene and used shader.

The real-time preview means that after each change of HLSL text, the HLSL text is compiled and the new shaders are used to render the preview image on the right.

The opened ComboBox shows that the editor comes with 6 shaders that can be used as a simple step by step HLSL tutorial. The first sample shows how to render all objects with a single color (you can experiment with changing the color components). The following effects add some interesting coloring. And the final shader shows how to create a shader with directional light lighting and with added fog.

So, if you have not tried to program in HLSL, this is your best and easiest chance to try it out.

And if you want to change the 3D scene, you can just open the XAML editor and change the 3D objects defined there.


And there are more great news. 

The new version of Ab3d.DXEngine has significantly better performance. In some cases (for example where many BoxVisual3D or similar objects are shown) the frame rate can be 3 times the previous frame rate. And already the previous version had some impressive performance. Also the time spend in the Update method is greatly reduced.

Also the problems with hardware accelerated 3D lines are now fixed. Because of some problems in the production version preparation, the previous version of Ab3d.DXEngine in many cases did not render the 3D lines with full hardware acceleration.

The biggest performance improvement in Ab3d.DXEngine can be achieved with using object instancing – rendering many instances of the same mesh. The performance is really amazing the following screenshot is showing 16.000 bunnies (each bummy model has 11.553 position) rendered at aroud 20 FPS (on i7 6700 and NVIDIA 970 GTX). Note that statistics in the lower right corner is showing that 184.848.000 positions are rendered:

Instancing in Ab3d.DXEngine

The problem with instancing in the previous version was that it did not support hit testing. This has been improved in the new version. Now you can set the IsWpfHitTestVisible property on InstancedGeometryVisual3D to true and hit testing (also the EventsManager3D from Ab3d.PowerToys) will begin to work. Though this will increase the initialization time because WPF objects need to be created before WPF hit testing can work. 

The new version also adds support for Binding on objects inside DXViewportView. For example, now you can bind IsVisible property on ModelVisual3D objects to CheckBox.IsChecked property.

The following is the full list of changes and improvements:

  • Fixed using Binding on objects inside DXViewportView.
  • Fixed rendering 3D lines with hardware accelerating geometry shader (instead of Ab3d.PowerToys's LinesUpdater).
  • Improved support for transformations on TileBrush (used on ImageBrush, VisualBrush and DrawingBrush).
  • Added IsWpfHitTestVisible to InstancedGeometryVisual3D - this allows WPF hit testing of instanced geometry (though this increased initialization time because WPF's GeometryModel3D objects needs to be created).
  • Improved InstancedGeometryVisual3D so that it is not needed any more to call Update method when the InstancesData is set for the first time. Also fixed problems when the objects were not shown if Update was called before the InstancedGeometryVisual3D was added to Visual tree.
  • Improved performance with moving some matrix calculations to vertex shader.
  • Added support for rendering WPF's UIElement3D objects. NOTE: WpfUIElement3DNode can only show 3D models but does not support the input events on the UIElement3D (MouseEnter, MouseMove, etc.). Those events cannot be supported because Viewport3D control is not visible and does not provide the events to the UIElement3D.
  • Greatly improved Update method call performance when many Visual3D objects from Ab3d.PowerToys are used (for example BoxVisual3D objects).
  • Added IsCheckingChildrenForChanges field to WpfModelVisual3DNode that can be used to skip checking ModelVisual3D's Childen collection and improve Update performance.
  • Added IsCheckingChildrenForChangesDefaultValue static field to WpfModelVisual3DNode - used to set the default value of the IsCheckingChildrenForChanges field.
  • Fixed problems where wrong image was shown when multiple DrawingImage brushes or VisualBrshes were used.
  • Prevented throwing exception when unsupported type of Visual3D (for example UIElement3D) or Model3D was used in the scene.
  • Added Refresh method to Ab3d.DirectX.Material and its derived classes. This allows user to manually update the materials properties and its resources (textures are regenerated).
  • Fixed hit testing on some Viewport3D objects (usually when the Viewport3D was removed from visual tree and then added to DXViewportView).
  • Fixed using IsAutomaticallyUpdatingDXScene when the DXScene was created after the IsAutomaticallyUpdatingDXScene property was set.


The Ab3d.PowerToys library also got some fixes. The following is a full list of changes:

  • Fixed showing 3D lines that were created with IsVisible property set to false. When later the IsVisible is set to true, sometimes the 3D lines were not shown.
  • Fixed rendering 3D lines with arrows that were not rendered correctly under some circumstances.
  • Fixed reporting MouseLeave event that was sometimes not triggered when CustomEventsSourceElement was used.
  • Fixed changing BoxVisual3D and SphereVisual3D objects after Position is changed under some circumstances.
  • Added GetCameraMatrixes to BaseCamera that can calculate view and projection camera even if TargetViewport3D is not assigned to the camera.
  • Prevented throwing null reference exception in Dumper.Dump method when TextureCoordinates or Normals collection was null.
  • Prevented throwing null reference exception that could sometimes occur in MouseCameraControllerInfo when in XAML designer.


The wrapper for assimp importer was also improved. The new library should read some models more correctly (especially models from fbx files). Also, the AssimpWpfImporter class now supports IDisposable interface. This means that it can be now easily disposed to release all managed and unmanaged resources. The following is list of all the changes in this library:

  • AssimpWpfImporter now implements IDisposable and have new Dispose method to easily dispose all managed and unmanaged resources.
  • Improved reading transformations - in case the transformation matrix is identity, the Transform property is set to null; in case the matrix is a simple translation, a TranslateTransform3D is created; in case of simple scale a ScaleTransform3D is created; otherwise a MatrixTransform3D is created.
  • Improved reading 3D models that are stored in left coordinate system.
  • Added ForceConvertToRightHandedCoordinateSystem property to AssimpWpfImporter and AssimpWpfConverter.


I hope that you share the excitement of the new versions with me. And I promise to bring you more great news in the future versions.

Tags: , , , ,

Ab3d.PowerToys | DXEngine

The first version of the new DirectX 11 rendering engine for .Net applications is available

by abenedik 4. November 2015 09:57

The first official version of the new DirectX 11 rendering engine for .Net applications is finally available. 

Car engine model shown with DXEngine (DirectX 11 rendering engine for .Net and WPF)

For example the model shown above is created from 891.840 triangles. The image is showing solid model with wireframe lines.

It is almost impossible to show such complex model with wireframe with WPF 3D rendering. It takes more than 13 minutes (!!!) to prepare the wireframe geometry and then WPF can render only 2 frames per second.

When the same model is shown with Ab3d.DXEngine, it is shown instantly (no need to prepare the wireframe geometry) and on my computer with NVidia 970 GTX it is easily shown with 60 frames per second (rendering takes only around 4 milliseconds – this theoretically means that it could render around 250 frames per second if WPF would not limit rendering to 60 frames).


This sample nicely shows the power of Ab3d.DXEngine and its advantage over WPF 3D especially when rendering wireframe models.

Another advantage is that Ab3d.DXEngine is by default using per-pixel lighting. This means that the lighting calculations are done for each rendered pixel and not per each vertex as in WPF 3D. This can produce much more accurate results that are best seen when using specular materials and SpotLights. The following screenshot shows the difference:

Comparison between WPF and Ab3d.DXEngine

Another great advantage of Ab3d.DXEngine is that it is not a closed box as WPF 3D. The engine has been designed with customizability in mind. This means that it is possible to change almost any part of the rendering pipeline. You can create your own shaders, create new effects and otherwise change the rendering process. 

In the following days I plan to release a sample application with live HLSL shader editor that immediately reflects any changes on the rendered 3D scene - I already have a working prototype but I need to improve and polish it a little bit. In the future I also want to improve documentation on how to provide new shaders and otherwise customize the engine.

And in my opinion the best feature of the new rendering engine is that it can render existing WPF 3D scenes created with using Viewport3D element. This means that you can very easily upgrade the existing applications into DirectX 11 rendered applications. It also means that you can work with a known API that already has a lot of documentation and samples.

This allows you to easily start with WPF 3D and later change to Ab3d.DXEngine. And this does not require rewriting the whole application from ground up (usually needed when rendering engine is changed) but need just a few small changes in the code. 

The first version of Ab3d.DXEngine is already a great leap forward in showing 3D graphics in .Net application. And it is also a great base platform for future improvements: I already have a prototype of dynamic shadows that will be added into the future version of the engine. I will also add support for environmental and bump mapping and many other great new features.


I still think that WPF 3D rendering can be used for many cases when you need to show 3D graphics in a business application. But when you need to show complex models, need to show many 3D lines or would like to customize the rendering process, then the Ab3d.DXEngine is a much better choice.


You are most welcome to try the Ab3d.DXEngine - it can be installed with other trial products - installer can be downloaded from the Downloads page.

Before trying the new engine I would like to inform you that it is recommended to try it with the latest version of Ab3d.PowerToys library (v7.2). The engine also works with older version of Ab3d.PowerToys but some features might not work well - see DXEngine help file for more info. You can use the latest version from the trial installer (it will not overwrite your commercial version if you have it).


Let’s complete this blog post with another great news: in November 2015 the Ab3d.DXEngine is available with 20% launch discount. And what is more, if you are our existing customer with valid updates subscription for Ab3d.PowerToys library, you can get an even bigger 30% discount for Ab3d.DXEninge – just write me an email and I will send you the discount code.


New maintenance release of Ab3d.PowerToys has been published

by abenedik 7. October 2015 16:13

I would like to inform you that a new maintenance release of Ab3d.PowerToys has been published.

Here is the list of new features and fixes:

  • Fixed problems with EventManager3D when events on wrong ModelEventSource3D object were triggered. This could happen when multiple GeometryModel3D objects were using the same MeshGeometry3D.
  • Improved performance of EventManager3D.
  • Improved design time behavior for MouseCameraControllerInfo with preventing calling BeginInit method when it was already called by WPF initializer (prevents thorwing exception in design time).
  • Added IsEmissiveSolidModelColor to WireframeVisual3D - when set to false it uses standard shaded color instead of single color produced by EmissiveMaterial.
  • Added modelSelectorFunc parameter to CreateWireframe method - it can be used to select which models are converted to wireframe.
  • Added new constructor to ModelMoverVisual3D that takes xAxisVector3D, yAxisVector3D and zAxisVector3D. This allows using custom axes for ModelMoverVisual3D.
  • Improved ModelDecoratorVisual3D when TargetModel3D is not defined in RootModelVisual3D.Content but in a ModelVisual3D that is defined in RootModelVisual3D.Children.



New DirectX rendering engine for 3D graphics in .Net applications is available

by abenedik 7. September 2015 15:28

I am very proud to present you a brand new DirectX 11 rendering engine – Ab3d.DXEngine.

The main purpose of the new engine is to bring you two mutually exclusive things: great power of DirectX and super easy to use WPF 3D API. 

Using WPF 3D API means that there is already a lot of documentation and samples on the internet and in the books. What is more, the existing WPF application that show 3D graphics can be preserved and with only a few little changes converted into DirectX powered applications.


You can already try the release candidate version of the new engine – it is available from our downloads page as part of the trial products installer.


The road to the Ab3d.DXEngine was not easy and short. Creating a rendering engine is not an easy task. The following picture shows my pile of DirectX related books (I have started with learning XNA and then moved to pure DirectX; countless articles on the web are not photographed):

DirectX books

Working with DirectX is not easy. You need to understand many new concepts that are quite different from the traditional development used when developing standard applications. The amount of required knowledge is huge – you need to understand how modern graphics cards work, understand DirectX API with all its methods and properties and finally understand how to program graphics shaders and how to use GPU debugging tools. And it is not enough that you are satisfied with the rendered image. Everything also need to be optimized as much as possible for performance and memory usage. To achieve 60 frames per seconds, the whole rendering code have only 16 milliseconds to render all the objects (in reality there is less time than 16 ms available because of WPF overhead). Because rendering usually happens at 60 frames per second, the rendering code is executed a lot of times. This means that you need to be especially careful with memory usage. Every small memory inefficiency can become a big memory leak in minutes. This also means that creating new objects should be avoided to minimize running garbage collector.

So, working with DirectX is quite challenging. And probably even more challenging was to make the existing WPF 3D API work well with completely different DirectX API.

But the really great news is that you will not need to bother with all that complexity anymore because the new Ab3d.DXEngine allows you to use DirectX with the comfort of the WPF 3D API.

To make the transition from the WPF 3D rendering to DirectX rendering, you will only need to add one element to your XAML (sometimes some additional smaller changes are needed – see Ab3d.DXEngine help file for more info; it is also advisable to add some additional configuration options).

Instead of standard WPF 3D rendering:

<Viewport3D Name=" width="360" height="471"" />
        <!-- WPF Viewport3D content -->

You will need to enclose the Viewport3D into DXViewportView:

<dxControls:DXViewportView Name="MainDXViewportView">
    <Viewport3D Name="MainViewport">  
        <!-- WPF Viewport3D content -->

This means that you can preserve the existing WPF 3D solutions and with just minimal changes you can achieve great improvements in rendered graphic.


This leads us to the advantages of using DirectX rendering over WPF 3D rendering.

The biggest advantage of the new rendering engine is that it is fully customizable (it will be also possible to buy full source code). You can create your own shaders, effects or otherwise change the rendering process. This also solves the biggest problem of WPF 3D – it was a closed box with no way to change it.

Another advantage of the Ab3d.DXEngine is the speed of rendering. Simply by using DirectX 11 instead of DirectX 9 (that is used by WPF) means that there will be performance improvements because of lower API overhead (less time is spend in DirectX and graphics card driver’s code). Additional improvements can be achieved because of more advanced API. For example WPF uses only 16 bit index buffer. This means that it can render 65535 triangle indices with one draw call. So if you are rendering an object with one million triangles, this means that 3 million triangle indices is needed – so WPF needs to split that into 46 separate index buffers and require 46 draw calls (one draw call is a DirectX method that issues drawing on the graphic card – lowering the number of draw calls is the easiest and most efficient method to improve performance). On the other hand, Ab3d.DXEngine uses 32 bit index buffer so it can render the same object with only one draw call. 

For example the Predator model from the following screenshot has only a single GeometryModel3D with 2.9 million positions:

Predator 3D model rendered with Ab3d.DXEngine

On NVIDIA GTX 970 and i7 3770 and with Ab3D.DXEngine it can be rendered in 0.3 milliseconds (theoretically allowing more than 3000 frames per second). With WPF 3D rendering the frame rate drops to only 14 frames per second.


The performance gains do not come only from DirectX API improvements but also from the design of the Ab3d.DXEngine. The engine internally organizes the objects in such a way that the number of draw calls and state changes is as low as possible and therefore rendering can be very fast.

The performance gains are even bigger when WPF objects are frozen (Freeze method is called on them). In such case Ab3d.DXEngine aggressively reorganizes and combines the models so that they are rendered blazingly fast.

I am also happy that the Ab3d.DXEngine eliminates the most common performance problem in WPF 3D – rendering many 3D lines. In WPF 3D rendering many 3D lines really kills the performance. The problem is that 3D lines need to be converted into triangles and each time the camera was changed all the triangles needed to be recalculated. This requires a lot of CPU time. In Ab3d.DXEngine this problem does not exist because the 3D lines can be very efficiently generated on graphics card in its geometry shader – so the Ab3d.DXEngine just send the 3D lines data (collection of start and end positions) to GPU and it rendered the lines very efficiently.

For example the wireframe scene from the following screenshot is rendered in around 0.7 ms (theoretically allowing around 1400 frames per second) when using Ab3d.DXEngine and gets only 3 frames per second when WPF 3D is used (on NVIDIA GTX 970 and i7 3770):

Wireframe ship model rendered with Ab3d.DXEngine

The list of performance improvements is not over. The Ab3d.DXEngine allows hardware instancing. This can achieve incredible performance gains when many instances of the same geometry need to be shown. Usually this is rendered in such a way that each instance is rendered individually and the position of the instance and its color is sent to GPU with its own draw call. When using instancing instead of drawing each instance individually we draw all instances at once – here we use a special draw command that requires data of the geometry and an array of colors and world matrixes (define the position, scale and rotation of each instance). So instead of many draw calls we can use only one.


Another advantage is that the it Ab3d.DXEngine can render graphics in much better quality. The biggest difference is that WPF is using per-vertex lighting and Ab3d.DXEngine is using per-pixel lighting. This means that in WPF lighting calculations are done only for each vertex. Then the colors are interpolated between vertexes. In Ab3d.DXEngine the lighting calculations are done for each displayed pixel. This is best seen in the following screenshot where WPF rendering is on the left and Ab3d.DXEngine rendering is on the right (note the accurate spot light cone and accurate reflections on the sphere – despite having low number of segments):

Comparison between WPF and Ab3d.DXEngine

The image above shows that the rendered quality is already significantly improved. But because Ab3d.DXEngine can get easily customized, it will be possible to add many great visual effects in the future.


I am planning to add support for shadow mapping. Actually I already have a working sample, but it still needs some polishing to be publicly available:

Shadow mapping in Ab3d.DXEngine

Shadow mapping is only one of the effects that will be added to the engine. I am also planning to add support for environmental maps (enabling natural looking reflections on metallic objects), screen space ambient occlusion (adding subtle shadows that make objects look more realistic), bump mapping, depth of field, etc. Because of the open nature of the engine this list is practically endless.


I would also like to point out one aspect of the new engine. It allows you to slowly get familiar with DirectX and graphic shaders. Usually if you would like to add DirectX to your application, you need to acquire a lot of new knowledge – how to set up DirectX environment, prepare the buffers, render objects, write graphic shaders and lots of other tiny details that each must work or you will see just a black screen. The great thing that Ab3d.DXEngine brings is to allow you to slowly dive deeper and deeper into the DirectX world. You can start with simple WPF 3D API – cameras, lights and models (geometry with material). Then you can use the source of the existing shaders and play with it. This will slowly introduce you to the hlsl shaders language. After that you can try to create your own shaders that require different constant buffers or input semantics. You can also prepare special objects that use some other draw methods. (note that the current version does not come with shaders source code; also I would recommend to wait until version 1.1 – the reason is that I am planning to significantly change the layout of the constant buffers and will also focus on improving support for custom shaders).


I would also like to quickly describe the difference between the Ab3d.DXEngine and many other DirectX game engines. 

There are really many different game engines available – from top class engines for AAA games to free and open source game engines. As the name implies, the main purpose of the game engine is to build a game. This means that a product of a game engine is a package with its own executable and many game resources. The user of the game engine spends most of his time in the game editor where he designs game levels, defines model properties and write some scripts.

If you want to create a business application that requires some 3D graphics, you could theoretically still use a game engine to render the 3D graphics. But practically this would mean that you will need to hack the engine to become something that it was not designed for. You will also need to significantly change your application to meet the constraints of the game engine.

On the other hand the Ab3d.DXEngine was designed to be used in business applications. 

The biggest advantage of this design is that it is very easy to integrate the 3D graphics into existing user interface. For example, a thing that all WPF developers take for granted is to be able to mix layout elements so that you can place elements on top of each other. Also if an element on top has some transparent parts, the elements below will be visible. This is something that is almost impossible to achieve when using game engine – game engines complete the frame drawing with calling the DirectX Present method – this method requires that SwapChain is used and the SwapChain requires its own window handle – practically this means that the area of screen that is used by the 3D engine cannot be used by any other application. This means that you cannot put a button on top of the 3D scene. With the Ab3d.DXEngine the rendered image can be used just as any other WPF element (this is the default presentation type - DirectXImage; with simple change of a PresentationType property you can change that to DirectXOverlay presentation type that uses the same presentation technique as game engines – this is needed when you want to use graphics debugging tools).

The engine is also optimized to support the most common use cases for 3D graphics in business applications. For example the engine supports both perspective and orthographic cameras. The engine can also easily render back face materials (rarely used in game engines). There is also a very good support for object picking and for rendering 3D lines and wireframe models.

And finally, you do not need to learn C++ to use DirectX. You can stay in the most efficient environment for developing application - .Net. Note that Ab3d.DXEngine is primarily meant to be used in WPF application, but it can be also easily used in WinForms applications.


I would really like to invite you to try the new rendering engine. It can be downloaded from our Downloads page as part of the products trial. The engine also works well with the Ab3d.PowerToys library (though it is recommended to use the lasts 7.1 version – it also works with older version but you might need to adjust some things – see the DXEngine’s help file for more info). If you already have an older commercial version of Ab3d.PowerToys installed, you can still safely install the latest trial version (you will need to manually enable the Ab3d.PowerToys in the installer at the products selection page). 

If everything goes well, I am going to release the Ab3d.DXEngine in October 2015. 

This will be only the first version of the engine. It will not contains all the goodies of DirectX graphics like shadow mapping and other effects. But it will already have enough powerful features to significantly improve your existing WPF 3D applications. And one of its main purposes is also to establish a good foundation for the future expansions.

If you would like to receive news about the Ab3d.DXEngine, please subscribe to the newsletter. If you are an existing customer, you can do this with visiting your User Account page and subscribing to changes for Ab3d.DXEngine. Otherwise you can also subscribe to newsletter on our blog

Also, please give us some feedback. You can do this by simply sending me an email to support@ab4d.com or write to a new DXEngine forum section.


I really hope that you are as excited about the Ab3d.DXEngine that I am. This will really bring a new era to the 3D graphics programming for business applications.