Great new features in new Ab3d.PowerToys and Ab3d.DXEngine

by abenedik 12. April 2024 11:22

Even though a new Ab4d.SharpEngine, a cross-platform rendering engine, was released a few months ago, work on the Ab3d.PowerToys and Ab3d.DXEngine has not stopped. The proof of that is the just published version that brings many great new features and improvements. Here is a list of the most important:

  • Added many new options to render pixels and point-clouds.
  • Added hardware support to render millions of textures as billboards.
  • Added support for Screen Space Ambient Occlusion (SSAO).
  • Significantly improved performance of line selection and generating edge lines.
  • Added sample that shows how to render objects with glow.

The previous version of Ab3d.DXEngine already provided great support for rendering pixels and point-clouds. It was possible to render millions of pixels with various sizes and colors. There was an OptimizedPointMesh class that could optimize the rendering of large point-clouds. On top of that, the new version adds the following new options:

  • The pixel size can be defined in screen or world size. Before, pixel size was defined only in screen size, but now you can also define the size in 3D world size so when using perspective camera the pixels that are farther away from the camera are smaller.
  • Pixels can be rendered as rectangles or as circles. Before, only rectangular pixels were possible. Now circular pixels can be rendered and this looks nicer for some point-clouds.
  • It is possible to specify a texture that will be rendered on each pixel. This can be used to render millions of billboards that are always facing the camera.
  • It is possible to fix the up vector of each pixel so the pixels do not fully face the camera. For example, this can be useful when rendering trees that are always growing vertically and should not face the camera when the camera is looking straight down.
  • The Ab3d.DXEngine samples project comes with new PlyPointCloudReader and PlyPointCloudWriter classes (available with full source code). They can be used to read and write point-clouds from and to ply files.

Here are a few screenshots:

Importing point-cloud with more than 12 million pixels from a ply file.

(Point-cloud with 12 million points)

Cropping point-cloud and exportin it to a ply file.

(New point-cloud importer sample supports exporting a cropped point-cloud)

Rendering may 3D textures as billboards (the screenshot shows 15.000 tree textures, but modern GPU can also easily handle many more textures).

(Rendering may 3D textures as billboards. The screenshot shows 15.000 tree textures, but modern GPU can also easily handle much more textures).


Another big new feature is support for Screen Space Ambient Occlusion (SSAO). If you look around you, you can see all the places around the room. All receive at least some light even if the lights or windows do not directly illuminate them. This light is called an ambient light. To correctly render that light, we need to use ray tracing. But in real-time computer graphics, we can usually specify an ambient light with just one value. This will illuminate all the objects in the scene with the same amount of light. But if you look around you, you will notice that, especially at the corners, the amount of ambient light is much lower, and a shadow is visible. Those shadows can be approximated by using the Screen Space Ambient Occlusion. This reduces the amount of the applied ambient light in places that have some objects around them.

See the difference in the following two screenshots (one with and one without SSAO):

Screen Space Ambient Occlusion (SSAO) that can dynamically shadow ambient light
SSAO disabled

Note that to see SSAO shadows, you need to use a lot of ambient light and should not use camera's lights (set camera.ShowCameraLight to ShowCameraLightType.Never). If you are using camera's light, it can illuminate the areas dimmed by the SSAO effect. So, using fixed directional or point lights and strong ambient light is recommended to see SSAO shadows.


The next major change in the new version is not a new feature but a significant improvement of the existing functionality that many of you are using. The new version of Ab3d.PowerToys greatly improves the performance of line selection and generating edge lines.

Showing edge lines can significantly improve the clarity of the shown 3D model. But with the previous version, if you had complex 3D models, calculating edge lines was very slow. The new version significantly speeds up this process. For example, the next graph shows the time in ms that was needed to generate edge lines for a complex P51 oil rig model (3.7 mio triangles; 1000 individual models, some have more than 100,000 positions; CPU: AMD Ryzen 9 5900X):

Graph that shows performance improvement of new edge lines generation

The previous version required 13 seconds in .Net Framework 4.8 (11 seconds in .Net 8). In the new version, this is almost 50 times faster: 350 ms in .Net Framework 4.8 (280 ms in .Net 8).

So, when using the previous version the user needed to wait for quite a while until the edge lines were generated, but now this is hardly noticeable.

What is more, if you know that your mesh is nicely defined or does not have duplicate positions, you can speed up this process even further. Duplicate positions are very common because they are required to create sharp edges by defining different normals for each position (for example, BoxVisual3D defined 24 positions and not only 6). But if you know that you have a smooth mesh without duplicate positions, you can set the ProcessDuplicatePositions property to false to skip the step of finding and collapsing duplicate positions. Also, if you know that the mesh has nicely defined triangles where each triangle edge is fully covered by any adjacent triangle edge (except on the outer mesh borders), then you can set the ProcessPartiallyCoveredEdges property to false. This skips code to process complex meshes (for example, such complex meshes can be produced by Boolean operations). If users of your application can import any 3D model, then you should have all the settings enabled, but if you have fixed 3D models, then you can experiment by turning off some settings and get even better performance. What is more, the updated "Edge lines creation" sample in Ab3d.PowerToys samples has code that shows how to easily write and read the calculated edge lines to and from a file.


Another very commonly used feature was line selection. The line selection in Ab3d.PowerToys allows selecting lines when the mouse is close to the line (the user can specify the max selection distance). When you were showing a lot of lines or lines have lots of line segments, then the line selection could eat a lot of CPU cycles. Before, 2D screen coordinates were calculated for all line segments. Then the 2D distance from the mouse to each line segment was calculated. The line with the closest distance was the result of the line selection. The new version significantly improves the performance of line selection for lines that have more than 30 segments. In this case, only 2D screen bounding box of the line is calculated and if the mouse position is in the bounding box or close to it, then the 2D screen positions for all line segments are calculated. This can skip a lot of calculations because only lines that are close to the mouse are fully processed. Note that to use the new faster code path, you need to set the new CheckBoundingBox property to true. This is needed to preserve the behavior of the GetClosestDistance method. Before, this method always returned a valid distance value, but now, when CheckBoundingBox is true and when the mouse position is not close to the bounding box, then double.MaxValue is returned.

What is more, if you are using ScreenSpaceLineNodes instead of lines derived from Visual3D objects (this significantly improves the initialization time but is harder to work with), then you can use the new DXLineSelectorData that is the same as LineSelectorData but works with Vector3 structs instead of Point3D structs. This will give you even better performance because of reduced memory usage (using float values instead of double values).

The following screenshot shows a new sample that shows 5000 lines each with 5000 line segments and still achieving super-fast line selection time:

Super fast line selection where lines can be selected by specifying the distance to the lines (moving mouse close to the line).


The next new feature did not need any change in the Ab3d.DXEngine library but it just needed a special rendering setup. It is implemented in a new "Glowing objects" sample that can be found in the Advanced section of the Ab3d.DXEngine sample project. As its name suggests, it shows how to render glowing effect to objects with an emissive material. I know that this is not an essential feature, but I am sure that some of you will be able to use it to achieve some very nice visual effects.

Rendering glowing objects.


As always, there were many other new features, fixes and improvements. You can check them by starting the updated sample projects (Ab3d.PowerToys or Ab3d.DXEngine) and checking for samples with NEW or UP icons. You can get the list of all changed in Ab3d.PowerToys change log and Ab3d.DXEngine change log


When speaking about fixes, I would like to mention one nasty bug that occurred when many 3D lines were rendered (using multi-threader rendering), and after the size of the window was changed, then in some cases the lines could be rendered with invalid line thickness. If this also happens in your application, then please upgrade to the latest version. If this is not possible, then disable multi-threader rendering for 3D line or the whole scene (contact support for more info).


Lastly, I would like to mention that the new version comes with a new native Assimp importer that can import 3D models from many 3D file formats. The previous official version of Assimp importer v5.3.1 was released more than half a year ago (2023-09-25). The new version was released just a few days ago (2024-04-07) and comes with many improvements ( You can build the new version by yourself or get prebuilt dlls from the libs folder in the Ab3d.PowerToys or Ab3d.DXEngine samples.


Here, I would also like to announce that in the coming weeks, I will be releasing a fully managed glTF importer and exporter. This will allow you to import 3D models with full details without using a native Assimp library. Currently, if you do not want to use Assimp importer, you could use ReaderObj (part of Ab3d.PowerToys library) to read obj files or use Ab3d.Reader3ds library to read 3ds files. However, both obj and 3ds file formats have their limitations. Obj files do not support hierarchy and animations, are text only, and have limited materials. 3ds files support only 8.3 file names for textures. So, those two file formats could be used only in a limited number of cases.

On the other hand, the glTF 2 file format is a modern file format that was developed by Khronos group and can store meshes, hierarchies, materials, transformations and animations in a text or binary format. Suppose you distribute 3D models with your application and are currently using Assimp importer to load the models from various files. In that case, you will be able to convert the files into glTF (using Assimp importer and exporter or by using some other third-party or online glTF converter) and then distribute your models as glTF files. This way, you will not need to distribute native Assimp's dlls with your application anymore.


As seen here, the new version can significantly improve the performance of your application and the new features can make it even more visually appealing.

Now, the primary development focus will switch back to the new Ab4d.SharpEngine. I am really happy with the adaptation of the new engine. It seems that the first version already had enough features for many of your projects. Some new features have already been developed, but many are still to be implemented. I am planning to publish a new version in June 2024. So, if you have any feedback or a new feature request for the new version, now is the best time to provide that.

Tags: , , ,

Ab3d.PowerToys | DXEngine

New Ab3d.PowerToys and Ab3d.DXEngine version published

by abenedik 14. December 2023 16:06

New maintenance release for Ab3d.PowerToys and Ab3d.DXEngine has been published.

The new version does not come with any bigger new features and only brings a few fixes and improvements. Because of this, only the build version was increased, but the major and minor versions remained the same.

This version also comes with a new build for .Net 8.0. .Net 8.0 that was released a few days ago. At that point, I would like to thank the .Net team, which is doing a great job with each new .Net release. For example, the last version again came with many new performance improvements - see the article about that: Performance Improvements in .NET 8. This means that without any changes in the code, your code will run faster just by using the latest version of .Net.

I did a quick performance test by running the DXEngine multi-threading sample in .Net framework 4.8 and then in .Net 8.0. I used only single-threaded rendering with disabled commands caching and by showing 160.000 3D boxes and 3D lines. This means that for each frame the engine needed to set shader states and issue 160.000 draw calls. The results were astonishing. When running in .Net framework 4.8, the code required around 47 ms to render one frame. But when using .Net 8.0, only around 33 ms was needed for the same job. This is a 30% performance improvement. 

Ab3d.DXEngine performance in .Net 8.0

The new version also comes with an updated Assimp importer. There is a new native Assimp library (v5.3.1) and a new managed Ab3d.PowerToys.Assimp library. Using a newer native library provides a more accurate importer and can read more files correctly. On top of that the Ab3d.PowerToys.Assimp was also improved. This version adds support for reading files with non-ASCII file names. Also, now it is possible to read diffuse textures with emissive materials. And in case you were using hardcoded object names, then I need to inform you that the new version also comes with a breaking change because the new version may set the object names differently. The latest version tries to use names so that they are as close to the original name as possible. In case when an object group also defines its own meshes, the previous version set the name of the Model3DGroup by adding the "__Group" suffix. The new version set the Model3DGroup's name to the original name without any suffix. To prevent using duplicate names, it adds a mesh name as a suffix to the GeometryModel3D's name that is added as a child of the Model3DGroup. If you want to preserve the previous naming, then set the PreserveGroupNames property to false. Note, then in WPF, an object's name must start with a letter or underscore and can contain only letters, digits, or underscores. Because of this, the object names may still be different from the original names in the file. For example, "12-material#10" would become "_12_material_10".

The updated Assimp importer files can found in the libs folder on GitHub.

To see the list of other fixes and changes, see the change log web pages: Ab3d.PowerToys history and Ab3d.DXEngine history.

As mentioned last week, when the new SharpEngine was released, I am planning to release a new major version of Ab3d.PowerToys and Ab3d.DXEngine at the end of Q1 2024 . The following are planned new features:

  • Add support for Screen Space Ambient Occlusion (SSAO) - this can significantly improve the visual quality.
  • Add new options to render pixels and point clouds (world-size pixels in addition to screen-size; render circular pixels or pixels with custom textures).
  • Add support for rendering 3D lines and line segments to an object ID bitmap (can be used for faster line hit testing; especially for MultiLineVisual3D).
  • Add options to copy only part of the object ID bitmap from GPU memory to CPU memory - this would make using ID bitmaps for hit objects much faster.
  • Trying to improve the performance of calculating edge lines by using oct-tree.

For 2024, I would also like to introduce a new product that would allow importing 3D models from STEP and IGES file formats that are commonly used by CAD applications. Later, there would also be improved support for geometric and surface modeling that is based on mathematical surfaces and not triangles.

If you have any additional requests or wishes, please contact us. Otherwise, stay tuned.

Tags: , , , ,


Ab4d.SharpEngine v1.0 published

by abenedik 8. December 2023 11:30

Ab4d.SharpEngine logo

Ab4d.SharpEngine v1.0 has been published!

The new cross-platform 3D rendering engine is ready for apps that work on Windows, Linux, macOS, Android and iOS. The engine uses Vulkan, which is a next generation graphics API that provides high-efficiency, cross-platform access to modern GPUs. The engine is also built by using the latest .Net technologies like Numerics and harware intrinsics. The combination of Vulkan and highly optimized .Net code provides super fast rendering. Based on long-time experience with Ab3d.PowerToys and Ab3d.DXEngine I have designed the API for the new engine to be very easy to use. Especially users of the Ab3d.PowerToys and Ab3d.DXEngine libraries should feel right at home.

The new engine can work on almost all devices that support .Net runtime. It can run on high end PCs and tiny Rasberry PI computers (with full hardware accelerated graphics). By using a software rendering LLVM pipe, the engine can also run on systems without a graphics card (for example, a web server, virtual machine or tiny embedded device). This provides many new very interesting options, for example, showing 3D graphics on a display that controls a CNC machine and runs on a Rasberry PI or some other embedded device. See here and here for more info.

The Ab4d.SharpEngine can be integrated into almost any UI framework. The following UI frameworks are currently supported: WPF, WinUI 3, Avalonia, MAUI, SDL / Glfw, LinuxFramebuffer. Better support for WinForms is coming soon. In all other UI framework it is also possible to render to an offscreen texture and than show that as a bitmap. Another proof that the engine is meant for any 3D developer is also that the engine supports any 3D coordinate system (y-up or z-up; left or right-handed; see the second screenshot below). What is more, the engine's main assembly, Ab4d.SharpEnine, does not have any third-party dependencies. To be able to provide great cross-platform capabilities, the engine even have a build-in png reader and writer, so you do not need to use platform specific bitmap libraries.

The first version of Ab4d.SharpEngine still lacks some of the features from Ab3d.PowerToys and Ab3d.DXEngine. But it should already have all the tools to create great apps with 3D graphics. Here are some of the screenshots:

3D model from fbx file with shown edge lines
Custom 3D coordinate system with Ab3d.SharpEngine
Ab4d.SharpEngine in an Avalonia UI application on macOS (Input events sample)
Ab4d.SharpEngine in an Avalonia application on Ubuntu Linux (3D lines sample)
Ab4d.SharpEngine in a generic SDL / Glfw application on Rasberry PI 4

The easiest way to start exploring the new engine is by checking the samples project that is hosted on GitHub: Note that some of the existing samples will be improved in the following days and many new samples are planned to be added.

The Ab4d.SharpEngine is distributed only by NuGet packages and cannot be installed by using a commercial version installer (as it was possible with other products). To use the engine it needs to be activated by calling the SetLicense method. The samples come with a special license that can be used only by the samples. To use the engine in your applications, you will need to get a trial license from (no email is required) or purchase a commercial license and then activate the commercial license.

The purchase options provide the standard "Single developer", "Team developer", "Site developer" and "Corporate developer" options that define how many developers are allowed to use the library. The standard license allows developing applications for Windows, Linux and macOS - it is called a "Desktop developer" license. To develop apps for mobile devices (Android and iOS) an additional "Mobile developer" license is required. With a standard commercial license you are allowed to use the Ab4d.SharpEngin to create applications for uses that do not have the Ab4d.SharpEngine license. But if you want to create a commercial library that uses Ab4d.SharpEngine, then a new "SDK license" is required. Contact us for more information.

To celebrate the launch, there is a 20% discount for all Ab4d.SharpEngine licenses. The discount is valid until January 7th, 2024.

I know that some of the Ab3d.PowerToys and Ab3d.DXEngine users did not look at the development of a new engine with a lot of gratitude. That development meant that less time was dedicated to the existing engines. I admit that lately not a lot of work has been done for other libraries. But this will change now. Next week, a new maintenance version of Ab3d.PowerToys and Ab3d.DXEngine will be published. That version will have some fixes and smaller improvements already implemented in the last few months.

What is more, for Q1 2024 I plan to release a new major version of the Ab3d.PowerToys and Ab3d.DXEngine. The following are planned new features:

  • Add support for Screen Space Ambient Occlusion (SSAO) that will significantly improve the visual quality.
  • Add new options to render pixels and point clouds (world-size pixels in addition to screen-size; render circular pixels or pixels with custom textures).
  • Add support for rendering 3D lines and line segments to an object ID bitmap (can be used for faster line hit testing).
  • Add options to copy only part of the object ID bitmap from GPU memory to CPU memory - this would make checking for hit objects much faster.
  • Trying to improve the performance of calculating edge lines by using oct-tree.

For 2024, I would also like to introduce a new product that would allow importing 3D models from STEP and IGES file formats that are commonly used by CAD applications. Later, there would also be improved support for geometric and surface modeling that is based on mathematical surfaces and not triangles.

So, it looks like 2024 will be another very busy year.

Please try the new Ab4d.SharpEngine. I really hope you will like it and that it will help you build awesome apps and bring 3D graphics "where no 3D graphics has gone before" (adapted from).

Tags: , ,


Major versions for Ab3d.PowerToys and Ab3d.DXEngine published

by abenedik 5. July 2023 20:27

I am happy to inform you that new major versions of Ab3d.PowerToys and Ab3d.DXEngine have been published.

The new release brings many great new features and one bigger breaking change.

The breaking change is the removal of the ViewCubeCameraController:


A customer recently informed me that the ViewCube is patented by Autodesk. It seems that the patent is active only in the USA. See here:

Therefore I have decided to remove that control from the library. Instead of ViewCubeCameraController the new version of the Ab3d.PowerToys library now provides the CameraNavigationCircles control. See the screenshot of the new sample that demonstrates the CameraNavigationCircles:

CameraNavigationCircles Sample


And an animation showing that control in action:

CameraNavigationCircles animation

As you can see, the new control provides many customization options and can be used in many different ways. What is more, it can replace both ViewCubeCameraController and also CameraAxisPanel.

However, if you are already using the ViewCubeCameraController and would like to continue using it, then please first carefully study the patent, and consult with a layer. If you still want to use the ViewCubeCameraController, then please contact me and I will send you the source code for that control so you will be able to integrate it into your project.


Another major new feature of this release is improved support for line caps (line endings). Previous versions supported only arrow line caps. The new version adds support for additional arrow types, boxes, diamonds and circles. See the screenshot from the new sample that demonstrates that:

3D lines with different line caps

What is more, the Ab3d.DXEngine finally gets full hardware acceleration of all 3D lines, including lines with line caps. Before, lines with line caps were generated on the CPU (on each camera change the MeshGeometry3D of the line was regenerated and this was very slow). The new version solves that and moves the generation of the lines to the geometry shader. This means rendering millions of 3D lines with different line caps is now possible.

The new Ab3d.DXEngine also improves line initialization time, so if you define many 3D lines, the engine will show them faster. Also, the order in which lines and other 3D objects are rendered is defined by an improved sorting mechanism, so there should be fewer DirectX state changes when rendering, resulting in slightly faster rendering.

The new release also comes with a new build of native Assimp library that can be used to import 3D models from almost any 3D file format. Unfortunately, it seems that the version number of that library has been stuck at v5.2.5 for almost a year, regardless of hundreds of commits. To still be able to see what version is used, a new GitCommitHash property was added. It returns the Git commit hash of the version. For example, the Assimp library that comes with this release has GitCommitHash set to 0dcfe2f - from 2023-07-03. 

The new Ab3d.PowerToys.Assimp library now also supports reading lights and camera data from the imported file.


There are also many other improvements and fixes. Even though a lot of time was spent on the new Ab4d.SharpEngine, the list of changes is still very long - see the change logs for Ab3d.PowerToys and Ab3d.DXEngine.

Tags: , , , ,

Ab3d.PowerToys | DXEngine

Ab4d.SharpEngine beta 2 comes with many new samples

by abenedik 18. April 2023 09:30

The second official beta version of the new cross-platform 3D rendering engine has been published. You can get the new samples from: (on GitHub also click on the Watch button to be informed of future changes).

The new version comes with many new samples that demonstrate a lot of functionality of the new engine. There are samples that demonstate cameras, mouse camera controller, materials, lights, different 3D objects and lines, model importers and animation. The following screenshot shows the samples running in a WinUI 3.0 application:

Ab4d.SharpEngine Vulkan samples in WinUI 3.0 application

You can see that the samples are organized in a similar way as the samples for Ab3d.PowerToys and Ab3d.DXEngine.

Because the engine can run on multiple platforms and UI frameworks, most samples are now defined in a common samples project (Ab4d.SharpEngine.Samples.Common). That project uses a generic UI provider that can create UI elements like Labels, CheckBoxes, ComboBoxes, Sliders, Buttons and other elements that are required for the sample. Then the project for the specific platform references that common project and provides rendering of the UI. This way the same sample code can be used for WPF, WinUI and Avalonia. The Avalonia sample works on Windows and without any change in code the same sample also runs on Linux and macOS (see screenshot with Rider IDE in the back):

Ab4d.SharpEngine Vulkan samples in Avalonia application running on Linux

Ab4d.SharpEngine Vulkan samples in Avalonia application running on macOS

There are also two special samples for Android. They show only a single 3D scene. Their purpose is to demonstrate two different ways on how to initialize the engine in Android. From there on, the code to create and manipulate the 3D scene is the same as for desktop operating systems. The following screenshot shows the engine running in Android:

Ab4d.SharpEngine sample in Android application

The current version does not support iOS yet. The problem there is that AOT (ahead-of-time) compilation that is required for iOS does not support function pointers ( that are used by the engine to communicate with Vulkan. It is interesting that for Android or desktop it is possible to use AOT compilation and there function pointers work without problems. If you have any recommendations on how to use function pointers on iOS, I would be glad to hear that. Otherwise, it seems that a special build of SharpEngine will be required for iOS. That build would use a different and less efficient way to call Vulkan functions (using standard delegates and UnmanagedFunctionPointer attribute). This needs some additional research so the support for iOS has been moved to the next version.

The major goal of this beta version was to provide new samples that demonstrate how to use the engine. But there were also many improvements behind the scene.

The most important is updated code for sharing the rendered 3D scene with WinUI and Avalonia. In this case the 3D scene that is rendered by Vulkan stays in the GPU memory and is shared by the WinUI or Avalonia. The code for WinUI now uses SwapChainPanel instead of SurfaceImageSource. This is faster and better supported - SurfaceImageSource had problems on older computers or computers with integrated Intel GPU. In Avalonia the previous code for sharing texture created OpenGL vertex and pixel shaders and rendered the shared Vulkan texture to an OpenGL context. This was very complex and did not work well on all platforms. The developers of the Avalonia UI were also aware that this was not done well, so we worked together to define a new interface that can be used for sharing an external texture with Avalonia (after some private discussions with the developers the following was issued: External GPU memory interop (OpenGL, Vulkan, DirectX). The new version of the engine uses that new interface. This works very well so that shared texture can be used on computers where the previous approach did not work. What is more, Avalonia currently uses OpenGL to render its user interface, but there already exists a build of Avalonia that uses Vulkan to render the interface. This will be publicly available in one of the future versions. This means that it will be even easier and faster to share the 3D scene created with Ab4d.SharpEngine because whole application could use the same Vulkan device.

If you have not tested the beta 1 version, I would like to encourage you to try the new beta version. If you know how to create a 3D scene by using Ab3d.PowerToys, then it should be easy to work with the new library because the general concepts are the same. There are some differences in object names, but when working with the new engine, you will quickly see that the new API is much more polished than when using the Ab3d.PowerToys and Ab3d.DXEngine. The problem with those two libraries was that they were based on WPF 3D object model. That object model was extended by Ab3d.PowerToys and later by Ab3d.DXEngine objects. Because of this in those two libraries there exists multiple ways to define 3D objects: based on GeometryModel3D, Visual3D and on SceneNodes from DXEngine. Now, the 3D objects are all derived from SceneNode. All object grouping is done by GroupNode (instead of Model3DGroup, ModelVisual3D, ContentVisual3D, SceneNode). Also, when using Ab4d.DXEngine you need to use some tricks (using SetDXAttribute method) to define advanced properties on WPF materials. Now all material properties are directly accessible.

As promised before, the work on Ab3d.PowerToys and Ab3d.DXEngine will not stop. There are already many improvements and fixes in the current development version. Now I will focus on providing some additional new features and then prepare a new release. So if you have any recommendations, it is now a great time to provide that.

Tags: , ,


The first beta version of a new cross-platform rendering engine has been published

by abenedik 15. December 2022 14:03

I am really glad to inform you that the first beta version of the Ab4d.SharpEngine has been published. 

Ab4d.SharpEngine logo

Ab4d.SharpEngine is a cross-platform 3D rendering engine for desktop and mobile .Net applications.

The existing rendering engine, Ab3d.DXEngine, uses DirectX 11. Because of that, it can only be used on Windows. The new engine uses Vulkan API.  And because it is built using .NET 6, the new engine is truly cross-platform and can be used on Windows, Linux (including Raspberry PI 4), macOS, Android and iOS. 

I know that now you would want to ask me: what about web? I am monitoring the status of Blazor with WebAssembly. I think that things are developing in the right direction but currently this technology is not yet capable enough for a more complex application with 3D graphics. The main problem is that WebAssembly does not have direct access to the Canvas, so each call needs to go through java script. Because 3D rendering engine needs to execute a lot of WebGL (or WebGPU) calls, this would be very slow. Also, in my opinion web will always be slow for high end and demanding 3D graphics. Anyway, the long time plan is to also provide support for web so that the same c# code could also run in a browser.

Vulkan is also an API with very little overhead, which makes it much faster than DirectX 11. What is more, Vulkan supports all new features that are added to new graphics cards, including ray tracing. This does not mean that Ab3d.DXEngine already supports ray tracing, but it is possible to add that and other new features in the future.

Because the new rendering engine was built from the ground up, it was possible to use all the know-how and experience from Ab3d.PowerToys and Ab3d.DXEngine to make its programming API clean and very easier to use. I admit that when using Ab3d.DXEngine and Ab3d.PowerToys, the API is not very nice in all cases. The Ab3d.PowerToy was built on top of WPF 3D objects that are not very extendable, so some compromises were needed (for example, cameras are derived from FrameworkElement and not from Camera). Also, Ab3d.DXEngine converts all WPF 3D and Ab3d.PowerToys objects into its own objects. This means that the application has two versions of each object. In other cases, some tricks must be used to provide Ab3d.DXEngine features to Ab3d.PowerToys and WPF 3D objects (for example using SetDXAttribute). Therefore, having an easy-to-use API was one of the primary goals of the new engine. Please contact me if you have any recommendations or find something that bothers you. 


I hope that you are already excited about the new rendering engine.
In that case, just jump into the samples page on GitHub: Ab4d.SharpEngine.Samples

There you will find solutions that show how to use the Ab4d.SharpEngine with WPF, AvaloniaUI, WinUI 3, SDL, Glfw. Some samples will run only on Windows; some will also run on Linux and macOS. Some will run on Android. iOS samples are coming in the near future. I also plan to add support for WinForms and MAUI. If you know of any other well know UI framework, please let me know and I will try to provide support for that too.

Check also the readme on GitHub as it provides a lot of other information.


Because you are an existing user of Ab3d.PowerToys and Ab3d.DXEngine, you are probably very interested in comparing the new engine with the current libraries.

Let's start with advantages of Ab3d.DXEngine and Ab3d.PowerToys:

  • Ab3d.DXEngine and Ab3d.PowerToys are very mature products that are tested and proven in the "field" by many customers.
  • Those two libraries currently provide more features and come with more samples that can be used as code templates for your needs.
  • Ab3d.DXEngine supports multi-threading and currently provides faster 3D rendering in many use cases.
  • Ab3d.DXEngine can use software rendering when there is no graphics card present (for example in virtual machines or on a server).
  • Ab3d.DXEngine and Ab3d.PowerToys can run on older .Net versions, including .Net Framework 4.5+.

Advantages of Ab4d.SharpEngine:

  • Ab4d.SharpEngine can run on multiple platforms. You can start writing code for Windows and later simply add support for Linux, macOS, Android and iOS. Or port just a smaller part of the application to other platforms.
  • Ab4d.SharpEngine uses Vulkan API that is the most advanced graphics API. It is actively developed and gets new features as new versions of graphics cards are released. This provides options to support all current and future graphics features (for example Ray tracing - not possible with DirectX 11).
  • As mentioned before, Ab4d.SharpEngine has a very clean and easy to use programming API. 
  • Working with WPF objects is very slow (accessing DependencyProperties has a lot of overhead). Also, Ab3d.DXEngine needs to convert all WPF objects into its own objects. Working with objects in Ab4d.SharpEngine is much faster.
  • Vulkan is a significantly faster graphics API than DirectX 11. Though the Ab4d.SharpEngine does not use all the fastest algorithms yet (no multi-threading), in the future the engine will be significantly faster than Ab3d.DXEngine.
  • Ab4d.SharpEngine is built on top of .NET 6 and that provides many performance benefits because of using System.Numerics, Span and other improved .NET features.
  • In the future Ab4d.SharpEngine will provide more functionality than Ab3d.DXEngine with Ab3d.PowerToys.


So, if you have a big and complex application that uses Ab3d.PowerToys and Ab3d.DXEngine, I would not recommend you to try to port it to the new engine. You could not just copy and paste the code to the new engine. Though the ideas and principles of both engines are still the same, for example there are TargetPositionCamera and MouseCameraController - both with almost the same properties and methods. But there are many smaller differences, for example BoxVisual3D is now BoxModelNode. Anyway, if you know how to use the existing engine, you will feel very familiar with the new engine also.

But if you are starting to build a new application with 3D graphics or would like to port some smaller part of your big application (for example a viewer with a few additional functionalities) to a more mobile format, then the new engine is a perfect choice for that. Also, if you are curious about how to program in .NET for other platforms or will have a little bit more time in December, I would be really glad if you could try the new engine and provide some feedback (you can also use Discussions or Issues on GitHub, or simply use email, forum or feedback form).

But please don't be too demanding. This is the first open beta and some things may not work as expected. In those cases, please see the Troubleshooting section on GitHub for more info.


Let me also share the planned road map for the new engine.

In the following weeks and months I will try to release new beta versions with fixes and improvements. After a few months, probably in Q2 or maybe in Q3 2023, the first production-ready versions should be released. Maybe some parts of the engine will remain in beta, for example AvaloniaUI, MAUI, macOS and iOS support. The plan is to have the main and most common parts ready for production: Windows (WPF, WinForms, SDL, Glfw), major Linux distributions (SDL, Glfw) and Android. 


And finally, I would like to assure you that Ab3d.PowerToys and Ab3d.DXEngine will still be actively developed, will get new releases and features and will have full support in the future!


I hope that the new engine will allow developers to use the beautiful c# language to create amazing apps with 3D graphics that could run on all possible platforms. If you have the right tools, then even 3D graphics is not hard!

And of course: Merry Christmas and happy new year!

Tags: , ,

Ab3d.PowerToys | DXEngine | SharpEngine

New Ab3d.PowerToys and Ab3d.DXEngine with .Net 7 build

by abenedik 10. November 2022 19:58

New versions of Ab3d.PowerToys and Ab3d.DXEngine have just been released. The new versions bring many great new features and because they were released just after the .Net 7 release, the new versions also come with a new .Net 7 build.

Because this release is also linked to a new .Net version release, this blog post also shows some performance numbers related to running Ab3d.DXEngine by using different .Net versions. See the end of this blog post for more information.


Now back to new features. In the past there were many requests to improve the triangulator that was part of the Ab3d.PowerToys library. If we want to show a filled 2D shape, for example an ellipse, as a 3D object, we need to first convert 2D points to 3D points and then define the triangles that will connect the positions. This can be done by using a triangulator. The old version of Ab3d.PowerToys already has a triangulator, but it could process only simple polygons. This was improved in the new version so that the new triangulator can now process multiple polygons and also supports polygons with holes.

Triangulated 3D text

As seen from the image above, this allows generating a 3D mesh from any text (text is represented by a series of 2D shapes). The sample also shows how to generate a 3D mesh from multiple 2D shapes (ellipses, rectangles, paths with bezier curves, etc.). The lower part of the sample shows individual triangles that were generated. There is also a Slider control that can be used to show how the triangles are laid out from the first to the last.

In some cases the new triangulator can also be used instead of Boolean operations. This requires that the main 3D object has a constant height (for example represents a sheet of metal or wood). In case when user wants to subtract a cylinder or some other object that can be extruded from a 2D shape, then using the triangulator instead of a Boolean subtract operation will be much faster and will provide better results (fewer triangles will be created).

Another highly requested feature is better support for collision detection. By using bounding boxes it was already possible to do some collision detection. However, because the bounding box is only an approximation of the space occupied by the object, this was not very precise. The new version of Ab3d.DXEngine brings a new MeshCollider object that can be used to check if one 3D position is inside another 3D mesh. By checking all the positions of one mesh, it is possible to check if one mesh collides with another mesh. The new sample demonstrates that (when checking the sample use arrows, PgUp and PgDown keys):


An interesting new material type that will greatly simplify work for some users is the new FaceColorMaterial. It supports defining different colors for each of the triangles in the mesh. Before it was already possible to achieve that by using a VertexColorMaterial. But this required that the positions of the mesh were duplicated so that each triangle used its own unique set of positions. Now this is greatly simplified because the original mesh can be used. What is more, by setting the alpha color to zero, the individual triangles can be discarded from rendering. The new sample nicely demonstrates that:

Face color material

Improving the performance of the Ab3d.DXEngine is a never-ending job. This version brings two new performance improvements. The first one is for those that use DXEngine's SceneNode objects and meshes. The new version significantly improves performance of hit testing because it can use OctTree objects on DXEngine's meshes. Before OctTree objects were created only from WPF's MeshGeometry3D objects. 

OctTree object organizes the triangles in a mesh in hierarchically organized 3D space regions so that when triangles are checked if they are intersected by a 3D ray, the number of checked triangles is much much lower. This makes hit testing almost instant even on huge meshes.

Now the DXScene.DXHitTestOptions.MeshPositionsCountForOctTreeGeneration property is also used when doing hit tests on DXEngine's meshes. Its default value is 512. This means that an OctTree will be automatically generated when the mesh has more than 512 positions. You can also manually generate the OctTree by calling the CreateOctTree method.

The second performance improvement will be great news for those who are rendering many polylines (lines where line segments are connected to each other). Multiple polylines are usually defined by a single MultiPolyLineVisual3D object. But though one object is used to define multiple lines, each line was still rendered by its own DirectX draw call. And if there were thousands of lines to render, it took quite some time to issue draw calls for each line. The good news is that with the new version, all the polylines can be rendered with only one draw call. This means that there will be almost no CPU cost for rendering any number of polylines.

As always, there are also many other improvements and fixes. See the change logs for more details here: Ab3d.PowerToys changelog and Ab3d.DXEngine changelog. Also get the latest samples (Ab3d.PowerToys.Wpf.Samples and Ab3d.DXEngine.Wpf.Samples) and check for UP and NEW icons to see new or updated samples.


And as promised before, let me show you some additional performance numbers. Each .Net version brings many performance improvements. There are new classes that can be used to write faster code. But also existing .Net code can run faster because each version improves the JIT compiler so it produces faster assembler code. The following graph shows how performance of the Ab3d.DXEngine can be improved when the application is run in a newer .Net version (running in .Net 4.8 is shown with a blue rectangle that represents 100% of the time; running in .Net 6.0 and .Net 7.0 executed the code faster and therefore the rectangles are shorter):

Ab3d.DXEngine performance in .Net versions

(1) "Multi-threading and caching" sample was run with showing 20000 boxes, using no background threads and disabled DirectX caching. The DrawRenderTime performance parameter measures the time that Ab3d.DXEngine needs to issue all DirectX draw calls. This requires going through all objects, checking their state, setting the DirectX state and calling DirectX Draw method. In this sample most of the time is spent in native DirectX code so the performance gains cannot be huge. But still, there is almost 10% better rendering performance just by using a newer .Net version.

(2) "Instanced animated arrows" sample was run with showing 1 million arrows. The graph shows values for the time that is required to calculate 1 million transformation matrices - each matrix is defined so that an arrow mesh will point toward the animated sphere. The values are based on highly optimized code (manually inlined and optimized math operations) that run on multiple threads (using Parallel.For).

(3) "Instanced animated arrows" sample showing 1 million arrows but this time the source code without any manual optimization is executed. The graph shows that the new JIT compiler can greatly optimize the generated assembler and in this case can provide a 25% performance boost.

(4) "Transparency sorting performance" sample shows the performance of different sorting algorithms that sort 3D objects to prevent transparency artifacts (the sample was updated to show 7200 instead of 720 boxes). The values under (4) show the difference of sorting that sort WPF 3D objects and is implemented by TransparencySorter from Ab3d.PowerToy library. Working with WPF objects is not very fast and there will be no changes in the WPF to make this faster. So it is great news that only using a new version of .Net can significantly improve the performance.

(5) The values here are again from the "Transparency sorting performance" sample, but this time showing the performance improvements of the transparency sorting from Ab3d.DXEngine. The source code for this sorting algorithm is already highly optimized, but still newer versions of .Net can squeeze some more juice from that.

So, Microsoft, keep up the great work!


And finally, the first open beta version of the new Vulkan based cross-platform rendering engine will be available before the end of this year! Let's conclude with the new logo for the engine:

Ab3d.SharpEngine logo

Tags: , , , , , ,

Ab3d.PowerToys | DXEngine