Great new features available with new version of Ab3d.DXEngine

by abenedik 23. February 2017 21:45

A new version of Ab3d.DXEngine library has been published.

Again, I am very excited about the new features in the engine. Just check the images below and you will see that the new Ab3d.DXEngine allows you to create some amazing effects in 3D graphics.

Let's start with added support for rendering 3D models that can have different colors in each vertex (position).

The following screenshot shows a new "heat distribution map" sample:

In the bottom center part of the screenshot you can see two red rays that connect over the 3D model. The position where the rays are connected is used to calculate the 3D position on the teapot - this position is used as ray hit position. Then, for each position in the teapot model, the distance from the position to the ray hit position is calculated. The calculated distance is then converted into specific color that shows the amount of heat (red is hot and blue is cold). This way we get different color values for each positon of the teapot.

After we have the colors for positions, we can use the new VerextColorMaterial to render the 3D model.

This is very useful for showing scientific data on 3D models.


Another use of this technique is to render height map with different colors. The color at each height map position is based on the height of the position. To demonstrate that, there is a new "landscape generation" sample:

This sample is also showing how to use Diamond square algorithm ( to generate realistic height maps. This algorithm starts with a few positions and then iteratively adds additional details to the map. To show how this process works, the sample can animate the size of the map from 3x3 to the map with much higher resolution (1025 x 1025 or higher).

Additionally, as you see in the lower right corner, the sample shows a nice legend with linear gradient. The control that shows the legend is also part of the sample and can be easily customized and reused in your own project.


If you are using Ab3d.DXEngine to create a CAD like application, you will be happy to hear that the new version allows rendering hidden 3D lines with special line color and line thickness. Hidden 3D lines are lines that are behind other 3D objects - thin yellow line in the following screenshot:

The previous version of Ab3d.DXEngine already supported rendering 3D lines that were visible though 3D objects, but you could not change the appearance of the hidden part of the line. The new version allows using new HiddenLineMaterial that renders only the hidden part of the line (part that is behind other 3D objects) and that allows specifying different color and line thickness for that hidden part.

Another improvement regarding rendered 3D lines is that the new version now automatically renders thin connected 3D lines (PolyLineVisual3D, LineArcVisual3D, TextVisual3D and other lines where line thickness is less or equal then 3) as disconnected 3D lines. This allows full hardware acceleration of connected 3D lines (rendering millions of connected 3D lines instead of thousands).

Connected 3D lines are 3D lines where the end point of one line is the start point of the next line and where the connection between the two lines is "smoothed". In Ab3d.PowerToys library the connected 3D lines are created with the following objects: PolyLineVisual3D, LineArcVisual3D, RectangleVisual3D, MultiPolyLineVisual3D, TextVisual3D, LineWithTextVisual3D, CenteredTextVisual3D. The problem with connected 3D lines is that additional triangle needs to be added to create the smooth connection between the lines. This is quite complicated operation and is not supported in DXEngine's geometry shader that creates 3D lines.

But when the LineThickness is small, then the additional triangle between connected lines is very small and hardly noticeable - in this case the connected lines can be rendered as disconnected 3D lines - without additional triangle to smooth the connection between lines. When the lines are rendered as disconnected lines, the geometry for the lines can be generated in geometry shader and this allows rendering millions of lines.

In the previous version of DXEngine, it was possible to set the RenderConnectedLinesAsDisconnected property on DXScene to true to render all connected lines as disconnected. In the new version it is possible to fine tune that with specifying the LineThickness limit that will define which connected 3D lines will be rendered as disconnected lines - this is done with new RenderConnectedLinesAsDisconnectedLinesThicknessLimit property (by default it is set to 3).

The following screenshot from an updated ConnectedLinesRendering sample shows fully accelerated 3D lines shown in red:

The thick lines (black lines with LineThickness 10 and 20) are still rendered the old way - the geometry for the 3D lines is generated by the code in the Ab3d.PowerToys library. There the smooth connections between line segments is easily seen. On the other hand, the thin lines (red lines with LineThickness 1 and 3) can be safely rendered without smooth connections and can be therefore fully hardware accelerated.

To get better understanding of this please check the ConnectedLinesRendering sample - there you can dynamically adjust the RenderConnectedLinesAsDisconnectedLinesThicknessLimit with a slider and see the results.

3D lines got another improvement - now the actual LineThickness that is used to render the 3D lines also takes the monitor DPI settings into account - 3D line on high DPI monitor will be actually rendered thicker so that for the user they will look the same as on the monitor with standard DPI (96).


If you have checked the DXEngine forum, then you know that there is now support for rendering many pixels. The number of pixels that can be rendered by modern graphics card is really amazing. The following screenshot from DXEngine samples is showing 100 million (!) pixels:

Each of the cubes in the screenshot is actually created from 1 million pixels (100 x 100 x 100 pixels). To see interesting patterns (instead of solid red color), each pixel's size is only 0.1.

The easiest way to show many pixels is to use new PixelsVisual3D object. After creating the object, you only need to set the color of the pixels, size of the pixels and an array with pixel locations. There are also other ways to render pixels - see PixelRenderingSample sample for more info.


The new version also improves showing VisualBrushes, DrawingImages and other textures that need to be rendered into bitmap to be shown with DXEngine.

In the previous versions, the size of the rendered bitmap was determined by the DXEngine. It was possible to change that by changing the RenderedBrushTextureWidth and RenderedBrushTextureHeight properties on the WpfMaterial object. But this was not very user friendly.

The new version greatly improves that and provides an easy way to set the desired size of rendered bitmap with using the CachedBitmapSize DXAttribute. The following example will set render size to 512 x 512 for the BigPlane's Material:

BigPlane.Material.SetDXAttribute(DXAttributeType.CachedBitmapSize, new SharpDX.Size2(512, 512));

An improved VisualBrush sample shows that in more details. It also demonstrates how to dynamically adjust the rendered bitmap size based on the distance from the camera - so objects that are closer to the camera gets higher resolution rendering (to make text better readable) and objects that are far from the camera can use smaller bitmaps (to save memory).


The new version also provides a few improvements for rendering many instances of objects. The first improvement related to this is a new UseAlphaBlend property on InstancedMeshGeometry3DNode - when it is set to true, the InstancedMeshGeometry3DNode will use alpha blending which will allow rendering semi-transparent instances - the actual alpha level is specified with the color that can be set for each instance.

InstancedMeshGeometry3DNode object also get a fix for using IsBackFaceMaterial property which makes rendering back faces of the instances correct. Also, InstancedModelGroupVisual3D now support rendering GeometryModel3D objects that have BackMaterial set.


There are also a few other improvements and fixes. The full list of changes is here:

  • Added VertexColorEffect and VertexColorMaterial - this adds support for rendering 3D objects with specifying color for each vertex (position).
  • Added PixelEffect, PixelMaterial and PixelsVisual3D - allows rendering millions of 3D pixels.
  • Added HiddenLineMaterial that can render 3D lines that are behind other 3D objects (should be hidden).
  • Added RenderConnectedLinesAsDisconnectedLinesThicknessLimit property to DXScene and set its default value to 3. This will render connected 3D lines (PolyLines, LineArc, Text3D, ect.) as disconnected 3D lines and therefore provide full hardware acceleration of 3D lines when LineThickness is less or equal then 3.
  • Added scaling LineThickness and PixelSize with current DPI scaling factor.
  • Fixed WpfMaterial.Refresh method to update VisualBrush.
  • Added CachedBitmapSize to DXAttributeType - this simplify setting the size of the rendered bitmap with calling SetDXAttribute extension method on WPF's material (instead of using RenderedBrushTextureWidth and RenderedBrushTextureHeight on WpfMaterial).
  • Added RenderToBitmapOnEveryFrame property to WpfMaterial - this instructs DXEngine to render the WPF material into bitmap before each frame is rendered.
  • Improved using RenderedBrushTextureWidth and RenderedBrushTextureHeight on WpfMaterial object for rendering materials with DrawingImage.
  • Fixed using IsBackFaceMaterial property in InstancedMeshGeometry3DNode.
  • Added rendering BackMaterial for GeometryModel3D objects rendered with InstancedModelGroupVisual3D.
  • Added UseAlphaBlend property to InstancedMeshGeometry3DNode and added support for rendering semi-transparent objects in InstancedModelGroupVisual3D.
  • Added "Get camera info" action to DiagnosticsWindow (and to DXEngineSnoop) to get detailed information about the camera that is currently used.
  • Added a new overload of WpfMaterial.SetUsedDXMaterial method that does not take parentDXDevice as parameter (the existing method that takes parentDXDevice is marked as Obsolete).
  • Fixed problems with showing and updating the 3D Scene that could sometimes occur on monitors with high DPI settings and with high UI thread usage before the first frame is rendered.
  • Added protected virtual Dispose method to SceneNodeVisual3D so that derived classes can dispose their resources in the overridden Dispose method.
  • Added IsDisposing to SharedDXResource (base class to most of the classes in DXEngine).

Tags: , , ,


New Oculus Rift support with updated OculusWrap project and full DXEngine support

by abenedik 6. January 2017 00:03

Let's start with a screenshot:

Ab3d.DXEngine rendering for Oculus Rift

This screenshot shows you that the Ab3d.DXEngine now fully supports Oculus Rift. And as you can see from the the window title and Oculus Performance overlay it has no problems with rendering at 90 FPS and still having plently of performance headroom.

What is more, because there were no up-to-date wrapper library for Oculus SKD available (the newest was OculusWrap, but it was discontinued on April 2016), I have decided to update the OculusWrap library to support the latest Oculus SDK (1.10.2) and published the updated library to GitHub to

The previous two paragraphs mean two things:

1) If you would like to use Oculus Rift in .Net and would like a low level access to the native Oculus library, you can do that now with the updated Ab3d.OculusWrap library.

2) If you want to stay in the comfort of using WPF 3D, Ab3d.PowerToys and Ab3d.DXEngine libraries and would like to add Oculus Rift support, you can now do that with adding just a few lines of code.


So if you have an Oculus Rift headset, you are most welcome to go to the above GitHub address and enter the VR world generated by .Net code.

Tags: , , , ,

Ab3d.PowerToys | DXEngine

Major new version of DXEngine (DirectX 11 rendering engine) bring many new features including shadow rendering

by abenedik 30. November 2016 22:40

I am really happy to inform you that after many hours of coding that resulted in tons of new features and improvements a major new version of Ab3d.DXEngine is released. Ab3d.DXEngine is a super fast 3D rendering engine that uses DirectX 11 and SharpDX and can be used in .Net Desktop applications.

The biggest new feature is support for shadow rendering. Ab3d.DXEngine uses variance shadow mapping technique that can produce nice soft shadow with little artifacts (based on the article in GPU Gems). The following screenshot shows an example taken from samples that come with the library:

In the lower right corner of the screenshot you can see various shadow settings that allow easy control over shadow resolution and amount of softness.

Another great improvement is a new option that allow rendering 3D lines that are visible through solid objects. This is a great feature for showing selected 3D objects.

The new version also improves handling frozen WPF 3D objects – for example frozen DiffuseMaterial or MeshGeometry3D. Before frozen objects were not very well reused by DXEngine. The new version handles this much better and this can improve initialization time, memory usage and rendering performance.

Ab3d.DXEngine is using SharpDX library for providing access to native DirectX API. The previous version of Ab3d.DXEngine used SharpDX version 2.6.3. The reason for this was that version 2.6.3 was the latest version that supported .Net 4.0 framework. Later version of SharpDX require .Net 4.5. Because Ab3d.DXEngine comes with build for both .Net 4.0 and .Net 4.5, it was possible to update the .Net 4.5 version so that it now uses the latest SharpDX version 3.1.0. The build for .Net 4.0 still uses SharpDX 2.6.3 - here a slightly updated version is used that supports feature level 11.1 (before 11.0 was supported).

This release also comes with a new diagnostics tool that is called DXEngineSnoop. As the name suggests, the tool can “snoop” (from WPF Snoop) into a running WPF application, finds the DXViewportView and attaches to its events and then provides live diagnostics and performance data. The tool also allows starting many actions that show various details about the rendering process – for example hierarchical view of SceneNodes.

The following screenshot shows the DXEngineSnoop window after it has been attached to a running DXEngine (right side shows context menu that is opened when user click on the menu icon):

This tool can help improve understanding of how Ab3d.DXEngine works behind the scene.

I will write more about that in one of the future articles. Now I can just quickly describe the process: first the DXViewportView converts all the WPF 3D models that are defined in Viewport3D into different SceneNodes. The hierarchical organization of SceneNodes can be seen with clicking on “Dump SceneNodes”. The SceneNodes than create low level objects that are put into various Rendering Queues (for example transparent objects are put into “Transparent RenderingQueue”). Those two steps are done in the Update part of the rendering (on the left side seen as UpdateTime). Then rendering of objects in Rendering Queues begin. The operations that happen there are defined in the RenderingSteps collection (can be seen with clicking on “Dump RenderingSteps”). Those steps can change when different rendering modes are used – for example shadow rendering require some additional rendering steps that render shadow map; stereoscopic rendering require a simple loop that repeats some rendering steps for left and for right eye. RenderingSteps collection is fully customizable and provides a great extensibility point for many engine customizations.

DXEngineSnoop can be also used to diagnose memory issues with providing simple way to start tracking object creation and to easily show reports of live objects. There is also a new section in the DXEngine help file that describes how to check for memory leaks.

The new version also brings many stability and performance improvements.

For example, when rendering thousands of models with object instancing, it is now possible to do a faster update of data when only a few objects were changed (their color or transformation is changed). For cases when object data are changed often it is now possible to further improve performance with creating a dynamic instance buffer (with UseDynamicInstanceBuffer property).

There are also some other minor performance improvements. But the majority of work was done on improving support for customizing the engine. This means that it will be easier to add new features and extend the engine to provide additional rendering functionality.

Also, users that know how to program with SharpDX and DirectX and would like to include existing SharpDX code into the engine have now more options to do that. There are also a few new samples with extended code comments about that. If you are doing a low-level customization, I would recommend that you contact me and we can discuss the best options for your use case.

To show new functionality, there are also a few new samples. Some older samples were also improved.

What is more, the new version comes with a new WinForms project that shows three different ways how to use DXEngine to easily show great DirectX 11 graphics inside WinForms application. The following screenshot shows one of the samples:


I do not want to make this blog post too long. Therefore, I will not publish the huge change log here but would rather invite you to check it on the DXEngines’s web page.

Instead, I would like to conclude with a few future plans.

First, I would like to publish the sample that shows how to use DXEngine with Oculus Rift. Actually, there is already a working sample that brings full Oculus Rift support to WPF and WinForms (and without need to understand the world of DirectX). The samole just need some additional plising before being published. If you cannot wait for an official release, you can contact me and I will send you the current version.

Then I will start working on a new version of Ab3d.PowerToys. I already have many many great ideas. The main focus will be to make the library better suited for CAD like scenarios. As a result, I want to create a big sample that will be a simple CAD like application written in .Net and that will use Ab3d.PowerToys and Ab3d.DXEngine.

Tags: , , ,


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


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