New versions of 3D libraries released

by abenedik 28. April 2022 19:57

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

This is a maintenance release with many improvements, fixes, and some new features.

The most interesting new feature in the Ab3d.DXEngine is added support for XRayEffect. The XRayEffect can render objects that look as they would be photographed by an x-ray. This can be useful when you work on a complex model with many parts and want to select one part while the other parts are just barely visible. In that case it is possible to make other parts semi-transparent. Another option that is available with the new version is to use the new XRayEffect or XRayMaterial. This works especially well when showing models with many triangles and with curved shapes. See example (this is a screenshot from slightly modified XRayEffect sample):

X-Ray effect on Ab3d.DXEngine

The new XRayEffect can be also used in the updated "Model Viewer" sample in the Ab3d.DXEngine samples (to use it check the new "Use X-Ray material" CheckBox in the second tab).

Another new feature can be used by those who use object instancing to render thousands of objects and want to do fast hit testing on the instanced objects. In this case, the new version allows rendering instance id bitmap from instanced objects. This generates a bitmap where colors represent the ids of the instances. By checking the color at a specific pixel, you can get the instance id that was rendered at that screen coordinates. This can also be used to do a rectangular selection or selection of the instance around the mouse cursor.

Also, the standard RenderToBitmap method got an improvement. With the new version it is possible to get direct access to the memory of the rendered bitmap. This way you can reuse the WritableBitmap or use any other method of using the rendered image. This is very useful when you are calling RenderToBitmap method very often because you can optimize and reuse the used objects (before a new WritableBitmap object was created on each call of RenderToBitmap method and this could generate many objects on the large memory heap).

The new version also improves stability in case of disconnecting an external monitor. Stability is also improved in some cases when rendering through a remote desktop.

The previous version introduced two-sided material that doubles the performance of rendering models that had the same front and back side materials. But this did not work in all the cases. This version fixes this issue.

There are also some other fixes and improvements. See the full list here: https://www.ab4d.com/DXEngine-history.aspx

 

The Ab3d.PowerToys library also got a few new features and improvements.

One interesting new feature is an improved algorithm for extruding a shape along a path. Now you can use two new options. One is to preserve the size of the shape at junctions and the other is to preserve the orientation of the shape's Y direction. See screenshot (the right side shows the extruded model using the new option):

Extrude a shape along a path

The new version of the library also comes with an updated Assimp importer and exporter. It now supports reading embedded textures and saving textures into fbx and glft files. There is also a new native Assimp library v5.2.3 that should improve the accuracy of importing and exporting files (https://github.com/assimp/assimp/releases/tag/v5.2.3)

To see the full list of changes see the change log here: https://www.ab4d.com/PowerToys-history.aspx

 

You can get the new version by updating the NuGet packages or by downloading the new evaluation or commercial version from your User Account web page. Note if you are using libraries from NuGet and you have recently renewed the updated subscription, then you will probably need to generate a new license activation code for the new version to work (this code can be generated from your User Account web page).

 

The list of new features is not as long as with some previous versions. The reason for this is that a lot of development effort is now spent on the new Vulkan based rendering engine (Ab3d.SharpEngine). This new engine is progressing very well. This engine will be fully cross-platform so the same code should be able to run on many different hardware devices. Recently we were able to run the code that works on Windows and desktop Linux on Raspberry Pi with a small touch screen attached - see photo:

SharpEngine on Resberry Pi with touch screen (pre-alpha)

Such a setup makes the engine great for controlling some industry machines or equipment.

The engine can also work on Android:

SharpEngine on Android phone (pre-alpha)

Many features from Ab3d.PowerToys and Ab3d.DXEngine were already ported to the new engine. But before releasing an alpha version, the core of the engine still needs some polishing and testing. I expect that the first alpha can be released in a month or two. The plan is to release a closed alpha version and later an open beta version. If you are interested in trying the new engine, please write me an email or feedback and you will be informed when the alpha version is available. This will allow you to test the engine on your hardware and on your devices. It will aso give you some influence on which features will make it to the first official and production-ready version.

Tags: , , , , , ,

Ab3d.PowerToys | DXEngine | SharpEngine

New major versions for 3D libraries released

by abenedik 26. November 2021 10:08

I am happy to inform you that new major versions for Ab3dPowerToys and Ab3d.DXEngine libraries have been released. 

The Ab3d.DXDXEngine has reached version 5.0. This is the 21st release of the library. The Ab3d.PowerToys library has climbed even higher and has reached version 10.0, having the 34th release of the library. The high number of releases is even more impressive when checking the actual change logs (see https://www.ab4d.com/PowerToys-history.aspx and https://www.ab4d.com/DXEngine-history.aspx). The long list of new features and changes that were often requested by the users shows that the libraries have become very mature and that they can be used for many different types of business, technical and scientific applications with 3D graphics. To make the numbers even more interesting, the build number of the new version is set to 8000. Because the build number is calculated as the number of days since 1st January 2000, this means that this release has happened on the 8000th day of the new Millenium (on 26th November 2021).

The highlights of the new versions are:

  • New Model viewer sample.
  • Rendering two-sided materials in one render pass.
  • Triangles sorting for transparent meshes.
  • Updated assimp importer that can read 3D models from almost any file format.
  • Added FitIntoView method for FreeCamera.

 

The first great new added value of the new version is a new Model viewer sample:

DXEngine Model Viewer

This sample does not provide any new feature but demonstrates many features of the Ab3d.PowerToys and Ab3d.DXEngine libraries. And because almost any application with 3D graphics requires object loading, mouse selection, wireframe and solid object rendering and showing object hierarchy, the sample is an excellent source of code snippets that you can use in your applications.

You can also use the sample to inspect the 3D models that are loaded from many file formats with Assimp importer. As shown in the following screenshot, it is possible to show mesh normals, position indexes and triangle orientations for the selected model:

DXEngine Model Viewer

Additional information can be obtained when an object without children (a GeometryModel3D) is selected. Then clicking on the "Show info" button will show the details about the mesh with a generate c# code that defines the mesh (creating arrays for all positions, normals, texture coordinates and triangle indices).

I am sure that you will find the new Model viewer interesting. Now let me provide some information about new features. Let me start with some background knowledge.

In 3D graphics the most fundamental building block of a 3D object is a triangle. And each triangle has its front and its backside. By default the front side of the triangle is the side where the vertices are defined in counter-clockwise order. The backside is the other side where the vertices are defined in clockwise order (see more here https://www.khronos.org/opengl/wiki/Face_Culling). In 3D graphics you can assign one material to the front side of the triangles and another material to the back side of the triangles. When using a GeometryModel3D object, the front material is assigned to the Material property, and the backface material is set to the BackMaterial property.

Many times the 3D models are solid and closed so we cannot see inside the 3D model. In those cases we can render only the front sides of the triangles and skip rendering the backsides. This reduces the number of rendered pixels by half. For example, 3D box and 3D sphere are solid and closed models and therefore the graphics card does not need to render the inner sides of the triangles. But when rendering a 3D plane, opened cylinder or any other model with holes, the graphics card needs to render both front and back triangles (both Material and BackMaterial properties need to be set). This is needed because the user can rotate the camera to see the other side of the plane or inside the model. The other case when we need to render both sides is when the object uses semi-transparent material. There the user can see the inner side of the 3D model. The models that use the same material for both the front and back sides are described as using a two-sided material. Two-sided materials are used many times for all the objects in technical 3D graphics.

Usually, the rendering of two-sided materials is done in two passes. First, the backside of the material is rendered, then the front side is rendered. When rendering the backside, the DirectX rasterizer state needs to be changed to prevent culling (skipping) the backside. Also, the code in the shader needs to invert the normal vector so that the lighting calculations are correct. This means that rendering models with two-sided material requires two DirectX draw calls and therefore takes twice as much time as rendering models with single-sided materials (actually, there is also an additional performance penalty because of rasterizer state changes).

The new version of Ab3d.DXEngine can use the DirectX SV_IsFrontFace semantics (https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics) that is used in the shader to check if the front side or the backside of the triangle is being rendered. This information is needed to invert the normal in the case of backside rendering. Also, the backside culling needs to be disabled in the DirectX rasterizer state. This allows the new version of Ab3d.DXEngine to render two-sided materials in one rendering pass. This means that 3D scenes where all 3D models have two-sided materials will be rendered twice as fast as before.

When using DXEngine's materials (supported by StandardMaterial, VertexColorMaterial, PhysicallyBasedMaterial and WpfMaterial), the two-sided rendering can be enabled by setting the IsTwoSided property to true. When using WPF 3D objects, then two-sided rendering will be used when the Material and BackMaterial on the GeometryModel3D are set to the same material instance. This will set the IsTwoSided property to true in the DXEngine's WpfMaterial that is created from the WPF's material. 

It is possible to prevent this new functionality by changing the static DXViewportView.UseTwoSidedMaterialsForSolidObjects and DXViewportView.UseTwoSidedMaterialsForTransparentObjects fields. As seen from the field names, there are different settings for solid and for transparent objects. By default, solid two-sided objects are rendered in one rendering pass (UseTwoSidedMaterialsForSolidObjects is true). But by default, transparent objects are still rendered in two passes (UseTwoSidedMaterialsForTransparentObjects is false) - first rendering the back material and then the front material. This is needed to preserve the rendered result as it was before. It is possible to set the UseTwoSidedMaterialsForTransparentObjects to true, but then it is recommended to set the new DefaultTransparentDepthStencilState field to DepthRead (from DepthReadWrite). This will render transparent objects in one render pass and correctly render the inner side of the objects. See the new "TwoSided materials" sample for more info.

DXEngine Model Viewer

 

The next new feature of the engine is the support for sorting individual triangles in a mesh. This may be required when showing semi-transparent meshes that have complicated geometry, as for example the following torus knot:

DXEngine Model Viewer

On the left the screenshot shows the object without sorted triangles. Red arrows mark the parts that are not correctly visible through the mesh. Green arrows indicate the correctly rendered pars of the object. Note, if the object would be rotated to the other side, then the correctly visible parts would change.

The new version of Ab3d.DXEngine has a highly optimized triangle sorting code that works on low-level triangles and positions data (WPF's MeshGeometry3D objects are not used because they are very slow). The code changes the data in the index buffer. After sorting is done on the CPU, then the changed index buffer needs to be sent to get GPU. Those two processes can take some time, so you should consider using triangle sorting only when really needed. 

Ab3d.DXEngine has got some other great new features and bug fixes. And there are also two new additional samples that are designed to improve understanding of GraphicsProfiles and different options to render wireframe lines. See screenshots:

DXEngine Model Viewer

DXEngine Model Viewer

 

The Ab3d.PowerToys library also got some great new features. In my opinion the most important new feature is an updated Assimp importer. The Assimp importer is a third-party native library that can import 3D models from more than 40 file formats. The previous version 5.0.1 of Assimp was released a long time ago, in January 2020. After that release, the library got many improvements and also some breaking changes that crashed the .Net wrapper. But because there was no increase in the library's version number, it was not possible to update the wrapper to work with the newer build of the library. Finally, on 20th November (last week) a new official version 5.1.1 of Assimp library was released. This meant that it was possible to update the AssimpNet (.Net wrapper for the native library) and the Ab3d.PowerToys.Assimp library (helper library that converts the read 3D models into WPF 3D objects). The new libraries improve support for many file formats and add some new file formats to the supported list.

Those two libraries and the compiled native Assimp library are available with the new Ab3d.PowerToys sample on GitHub (https://github.com/ab4d/Ab3d.PowerToys.Wpf.Samples/tree/master/lib). Those libraries are also installed by the evaluation installer of the AB4D products (https://www.ab4d.com/Downloads.aspx) and the commercial installer for the Ab3d.PowerToys library (available from User Account web page).

The new version of Ab3d.PowerToy also comes support for calling the FitIntoView method when using FreeCamera (a highly requested feature). This provides the same functionality to FreeCamera as available by the TargetPositionCamera.

 

As always, please update to the new versions and check the new samples projects (https://github.com/ab4d/Ab3d.DXEngine.Wpf.Samples, https://github.com/ab4d/Ab3d.PowerToys.Wpf.Samples). In the new samples check the samples that are marked with NEW and UP icons. The icons mark new samples and the samples that were updated in the last version (hovering the mouse over the UP icon will show you more information about the change).

Tags: , , , ,

Ab3d.PowerToys | DXEngine

Improved versions of Ab3d.PowerToys and Ab3d.DXEngine published

by abenedik 28. June 2021 15:48

Another new version of Ab3d.PowerToys and Ab3d.DXEngine libraries have been released.

Though this is a minor release, it still brings some amazing new improvements. For those of you that are rendering complex 3D graphics and also need to show WPF controls on top of the 3D scene, the new version of Ab3d.DXEngine brings two new great features:

1)

The performance of DirectXImage presentation type (required to show WPF controls on top of 3D scene) has been significantly improved. This was done by improving the Ab3d.DXEngine so that it can wait in a background thread until the graphics card finishes rendering the 3D scene. Then Ab3d.DXEngine invokes the code on the main thread that sends the rendered scene to the WPF composition engine. This means that the main thread does not need to wait anymore for the graphics card to complete the rendering of the 3D scene.

The most significant performance improvement of this new feature can be seen when the graphics card is rendering objects with a very big number of triangles or when using mesh instancing. In this case only a few DirectX commands issue a lot of GPU work. On the other side, when many DirectX commands are called, the performance improvement is not that big because Ab3d.DXEngine still needs to wait on the main thread until the graphics driver finishes processing the commands (DirectX Flush command needs to finish executing on the main thread). Anyway, in both cases the performance improvements (the time that you have on the main thread for your tasks) are significant. And what is best, you do not need to do anything except switching to a new version. 

 

2)

If you need even more performance and would also like that most of the drivers's work is done on the background thread, then you need to use DirectXOverlay presentation type. In this presentation type, the DirectX gets its own part of the screen (a hwnd handle) where it can present the rendered 3D scene when the graphics card finishes rendering. This presentation type is the fastest because the main thread is freed immediately after the Ab3d makes the last draw call by the Ab3d.DXEngine - both the driver's work and rendering are done in the background.

The problem with this presentation type is that it is impossible to render WPF controls on top of the 3D scene. Actually, WPF is not aware that the controls are hidden by the overlaid 3D scene so it will still render the controls, pass mouse events to the controls so they will be fully functional, but not visible.

The new version of Ab3d.DXEngine can solve the problem of hidden WPF controls in DirectXOverlay mode by using 2D sprites (also a new feature in this version) to show the static WPF controls (for example a TextBlock or a MouseCameraControllerInfo) or WPF controls that use Viewport3D (for example CameraAxisPanel or ViewCubeCameraController). The controls with Viewport3D are actually rendered by Ab3d.DXEngine. The trick is to render Viewport3D in a secondary DXViewportView control. This DXViewportView is created with the same DirectX device as the DXViewportView control that renders the main 3D scene. This way all DXViewportView controls can share the rendered results. For example, the secondary DXViewportView renders the CameraAxisPanel into a 2D texture and then this texture is shown on the main DXViewportView as a 2D sprite.

This can be done very easily with two new classes: WpfElementOverlay and Viewport3DObjectOverlay. What is more, the full source code of those two classes is available in the main Ab3d.DXEngine samples project.

 

The new version of Ab3d.DXEngine also comes with improved InstancedTextNode. This object can be used to render millions of characters. With the new version it is possible to change the individual texts and also remove some texts. For advanced users, the new version comes with a new InstancedMeshNode object that can show instanced meshes without using WPF's MeshGeometry3D (you can use any mesh derived from DXEngine's MeshBase). Also, the new version can prevent WPF's rendering thread exception (UCEERR_RENDERTHREADFAILURE) that may happen when the primary monitor has changed (for example when a laptop is connected to a docking station and uses more than one monitor; disconnecting the monitors can trigger a WPF excepton).

The Ab3d.PowerToys library also comes with a few new features and fixes. The new SphericalZoneVisual3D (and Ab3d.Meshes.SphericalZoneMesh3D) can show part of a 3Dsphere. This 3D object can be used to add a rounded end to a 3D cone or a 3D tube line. In addition, the FitIntoView method got two new overloads so you can call the method with passing a custom Rect3D (bounding box) or a custom list of 3D positions.

To see the full list of changes, check the history web pages: Ab3d.PowerToys history, Ab3d.DXEngine history.

 

I am also happy to inform you that the work on a new Vulkan based cross-platform rendering engine is also progressing very well. Here are two sample screenshots:




The first screenshot shows a test scene with the content of the memory dump command that shows advanced Vulkan memory management capabilities.

The second screenshot shows a simple 3D scene that is rendered in Linux and composed with Avalonia UI (Avalonia UI buttons are rendered on top of Vulkan 3D scene).

The current plan is to provide an alpha version in September 2021.

Tags: , ,

Ab3d.PowerToys | DXEngine

.Net 5.0 support with some exciting new features

by abenedik 18. December 2020 13:47

Though this year was very unusual, I am happy to conclude it by providing you additional great new features in the new version of Ab3d.PowerToys and Ab3d.DXEngine. And what is more, I am also giving you a 30% discount for any source code purchase.

In the last blog post, which was written just slightly more than one month ago, I have already mentioned that the libraries were tested with .Net 5.0 but not enough for me to release an official .Net 5.0 version. Anyway, if you checked the web page or your User Account page a few days after the release, you could see that the .Net 5.0 builds were already included in the installers. 

I also wanted to update the NuGet packages, but it is not possible to change an existing version of the NuGet packages. And I also did not want to increase the version number without any change in the code. 

Therefore I have uploaded an updated version of NuGet packages (.nupkg files) to the Downloads web page. I have also decided to provide a new version in December with some additional new features and an official .Net 5.0 support. 

So, official support for .Net 5.0 is the most significant new feature. But the new version offers much much more.

The first new feature that I would like to highlight is the new InstancedTextNode class. It can be used to render millions (!!!) of characters in any font and style. It can be also used to demonstrate the immense power of modern graphics cards. See that by yourself:

Showing 8000 texts with new InstancedTextNode object in new Ab3d.DXEngine

This screenshot is showing 8000 texts with different coordinates in the format "(xxx yyy zzz)". As seen in the screenshot, 94800 characters were used in the image. Impressive, isn't it! But what will you say if this screenshot is there only to make the texts easier to read and not to demonstrate the power of the new InstancedTextNode? To see the real power see the screenshot with 1 million texts (13.2 million characters):

Showing 1 million texts with new InstancedTextNode object in new Ab3d.DXEngine

This can easily run with 60 FPS on a modern GPU. Get the latest version and check this out by yourself. It is really amazing!

Though the previous two images used only black text, it is possible to set each text's position, orientation, size, and color. And after the text is shown, it is very easy to hide, show, move, scale and change its color. The following image shows that:

Showing different text with new InstancedTextNode object in new Ab3d.DXEngine

The InstancedTextNode achieves this level of performance by using DirectX object instancing and multiple textures - one texture for each character. When adding different texts to the InstancedTextNode, the code checks which characters are used in the text and when a character that was not used in any previous text is found, it renders the new character to a new texture. Then for each character in the text, it calculates a world transformation matrix and uses it for the InstanceData. Then it uses object instancing to render all instances (all appearances in all texts) of one character in one draw call. This is done for each character. Because some parts of the character textures are transparent, the InstancedTextNode uses alpha-clipping to discard the transparent pixels. This preserves the excellent performance because it avoids sorting the individual characters by their distance to the camera.

So the InstancedTextNode can be used when you need to render a lot of text. It can also be used to render just a few characters. But in this case I would still recommend using the TextBlockVisual3D object because it provides more options and is faster for rendering just a few characters - it requires one draw call to render the whole text while the InstancedTextNode requires individual draw calls for each character.

And the TextBlockVisual3D also got a few new improvements in this version. First, its Material and BackMaterial properties preserve the DiffuseMaterial instance (before new instances can be created when the properties were changed). Because the instance is now preserved, this means that you can easily assign special DXEngine's attributes to the Material and BackMaterial properties - for example, to use alpha-clipping. In the new version you can also assign a new UseSolidColorEffect DXAttribute. When UseSolidColorEffect is set to true, the text will be rendered without any lighting calculations. This can prevent dimming the text when the text does not face the lights. There is a new ImprovedTextBlockVisual3D sample available that demonstrates that and shows the benefits of using ImprovedTextBlockVisual3D in Ab3d.DXEngine.

This version also (finally) shows how to use object id bitmap. Object id bitmap is created by rendering the objects to a bitmap by setting each object's color to a unique color that represents object id. This way it is possible to get the object id from the color of each rendered pixel. The new version demonstrates that by showing how to make a rectangular selection of objects.

Because Ab3d.DXEngine can render millions of 3D lines with different display styles (line thickness, pattern, hidden lines), it is also used in some applications to show 2D lines and 2D shapes or to create a 2D shapes editor. To provide a demonstration on how this can be achieved, the new version comes with a new TwoDimensionalCamera class and 3 new samples. The TwoDimensionalCamera creates a camera that can show a 2D scene. The objects in that scene are still standard 3D objects - there the x and y coordinates represent the position in the 2D scene; the z value is usually set to 0 (but can be changed to render some lines or objects in front of or behind other lines or objects). The TwoDimensionalCamera supports moving and zooming the camera. A simple 2D lines editor sample shows how to create a line editor with snipping to positions.

When speaking of lines, there is another new feature that I want to talk about. It improves support for rendering 3D lines that are always rendered exactly to screen pixels. The previous version of Ab3d.DXEngine introduced super-sampling support that can produce very nice smooth lines. But because line coordinates are defined as float values, the lines on the screen can be rendered between screen pixels. For example, if a 1 screen pixel thick horizontal black line is rendered on a white background and if the line falls between two screen pixels, the line will appear as 2 pixels thick gray horizontal line - the black color will be distributed between 2 pixels. When rendering multiple thin horizontal and vertical lines (for example, in a grid) this may produce some unwanted effects. This can be seen because some lines appear black and sharp (rendered exactly to the screen pixels), some are gray and twice as thick (rendered between two screen pixels) and others are in between.

It was already possible to render lines that are rendered exactly to screen pixels. This can be done by setting UseGeometryShaderFor3DLines and RenderAntialiased3DLines properties on DXScene object to false. But this setting is applied to all lines. So also angled lines will be shown without any anti-aliasing. What is more, lines rendered without geometry shader can be only 1 pixel thick. Therefore this option was rarely used. 

So each rendering option provides its benefits and its drawbacks. In the previous version it was not possible to mix them in a single scene. Now, this is possible. You can set the new UseGeometryShaderFor3DLines and RenderAntialiased3DLines DXAttributes to the selected 3D lines and specify how you want to render them. So you can render the horizontal and vertical grid lines as sharp 1 screen pixel lines and all other lines as standard smooth lines. Unfortunately, there is still a small catch - you cannot use super-sampling when using 1 pixel thick non-anti-aliased lines. The problem is that when using super-sampling, the line thickness needs to be increased by the SuperSamplingFactor so that when the super-sampling texture is down-sampled, the final line thickness is correct. But without using a geometry shader, it is impossible to increase line thickness, so when down-sampling the 1 pixel thick lines will appear 1/2 or 1/4 thinner. Anyway, you can still use multi-sampling. In the future, I plan to solve this problem by providing options to snap 3D lines to screen pixels.

And one final new feature that you may also consider important: the new version can prevent the UCEERR_RENDERTHREADFAILURE exception in WPF's render thread that can crash the whole application. That exception can sometimes occur when the primary monitor is changed. For example, when a laptop is connected to a secondary monitor with a duplicate screen option and then the laptop is closed. In this case, the secondary monitor becomes the primary monitor. It looks like there is a bug in the WPF that may crash the application. But I was able to prevent that by detecting the primary monitor's change and then recreating some of the internal objects. This seems to prevent the crash.

 

So, plenty of reasons to be excited about the new version. As always, start the new samples project and check the NEW and UP icons to see new and updated samples. For more details read the change log - here: https://www.ab4d.com/DXEngine-history.aspx and here: https://www.ab4d.com/PowerToys-history.aspx

And if you were wondering what is going on behind the scenes and wanted to peek into the Ab3d.DXEngine and Ab3d.PowerToys source code, now is the best time to purchase the source code. Just go to the purchase web page. The 30% discount is already applied to all source code items.

 

I wish you a nice and peaceful conclusion to this year. And also a few pleasant surprises (I hope this new version is one of them). And of course, happy and successful 2021!

Tags: , ,

Ab3d.PowerToys | DXEngine

Super-smooth lines with many other features in new versions of 3D libraries

by abenedik 12. November 2020 11:12

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

By the new version numbers you may think that this is just a smaller update, but I am sure that the content that follows will persuade you that this is another big and great update that can significantly improve the value of your application and provide you with some great new tools for your work with 3D graphics.

Here are the highlights of the new version:

  • Added support for super-sampling provides rendering of super-smooth 3D lines and better rendering of details.
  • Added support for creating edge lines and improved support for rendering object outlines. This can render the scene in a way that is standard for CAD programs.
  • Improved support for rendering the same 3D scene with different DXViewportView (each with different camera and render settings).
  • Significantly improved the performance of the DXEngine's update step.
  • Simplified hierarchical organization of Visual3D objects with using ContentVisual3D that defines IsVisible property and now also supports showing and hiding Visual3D objects in Children collection. This also greatly improves the performance of showing and hiding Visual3D objects.
  • Improved ViewCubeCameraController - the new version supports clicking on cube edges and corners. 
  • Added custom wpf3d file format that can store WPF 3D scene. The full source code to read and write wpf3d file is available with the samples project. This way the code can be adjusted to your needs.
  • Many other improvements and fixes.

 

The following image demonstrates the first two highlights:

Super-smooth 3D lines with using super-sampling in new Ab3d.DXEngine

The first step in creating the image above was to import an aircraft engine model from a file. Then a new EdgeLinesFactory.AddEdgeLinePositions method was called. This method analyses the 3D model and creates edge lines if the angle between two adjacent triangles is bigger than the specified angle. This way it is possible to get much more accurate edge lines than by showing the wireframe of the model. The problem with showing the wireframe is that it shows lines around all triangles even if they lay on the same plane (for example, a diagonal line on cube sides). After having the edge lines, we can show the lower part of the image.

But as the upper part of the image shows, with the new version of Ab3d.DXEngine it is possible to create a superior and much more professional looking result. 

The first thing that can be done with the Ab3d.DXEngine is to set line depth bias. This moves the 3D lines towards the camera and away from the solid model so it cannot occlude the lines when they occupy the same 3D space. In the upper image, this can be seen in the lower right part of the image where the line thickness changes because the solid model occludes the lines. The new version of Ab3d.DXEngine also improves using line depth by preventing the lines from being moved away from the 3D model (when using a perspective camera). This simplifies setting the correct line depth bias.

The second feature that improves appearance in the image above is the object's outline. This renders a thicker line around 3D models. The line is also drawn on places where there are no edge lines - for example, when a curved model ends - in the image above this is just below the "objects outlines" text.

But the most significant improvement of using the new Ab3d.DXEngine is the use of super-sampling that can produce super-smooth 3D lines. In the last few months a lot of effort was put into improving the quality of 3D lines. I first tried to create smooth lines by adjusting the alpha values on pixels near the edge of the line. This slightly improved line quality. But because of using transparency on the edges, this could create artifacts if lines were not rendered in the correct order. After some other tests, it finally became apparent that using super-sampling can provide the best results. Click here to see a screenshot from a line quality testing sample.

Super-sampling (SSAA) is an anti-aliasing technique where the 3D scene is rendered to a bigger image and then down-sampled to the final image. For example, 4x SSAA means that the rendering is performed to an image that has twice the width and twice the height of the final image (has 4 times the number of pixels). The image quality can be further improved when down-sampling uses a special filter that reads samples in a slightly rotated pattern and uses different weights on the read samples. As the image above shows, this can produce highly superior results.

The difference between super-sampling and multi-sampling is that with multi-sampling, the number of pixel shader invocations is the same as with no multi-sampling. In this case, the color that the pixel shader returns is saved to multiple pixels (samples). At the end of rendering the multi-sampled texture is resolved so that all the samples are used to produce the final pixel color. This can significantly improve edge aliasing. But because there were no more pixel shader invocations, this does not produce an image with more details. For example, 4x MSAA requires 4 times the memory because each pixel shader result is shared with 4 pixels, but the number of pixel shader invocations is the same as when no multi-sampling is used. This is the main difference compared to super-sampling. There the scene is rendered to a bigger texture. This means that 4x SSAA requires four times the memory and also four times the number of pixel shader invocations. As seen in the image above, using 4x MSAA can significantly improve line quality compared to using no multi-sampling. But using 8x MSAA does not provide any more significant quality improvement. But using super-sampling can provide much better results.

Because of much higher memory usage and the number of pixel shader invocations, using super-sampling comes with high costs. This may not provide a significant difference on a high-end graphics card, but on an integrated graphics card, the slow-down may be noticeable. Though the max supported super-sampling count is 64 (rendering to 8 times width and height), the high super-sampling count should be avoided in most cases. You should also be careful because the maximum texture width and height in DirectX 11 is 16384. For example, this limit is reached on a 4k monitor when 16x SSAA is used. The Ab3d.DXEngine knows about this limitation and can dynamically reduce the super-sampling count to stay below this limit. Also, because SSAA can be combined with multi-sampling (MSAA), the recommended setting to achieve super-smooth lines is to use 4x SSAA with 4x MSAA (this was also used to produce the image above). To see the memory requirements of the various settings, open the diagnostics window that now shows the required amount of memory. The diagnostics window can be opened in the samples project by clicking on the Diagnostics button. In your application you can show the diagnostics window by using the DXEngineSnoop tool and attaching to your application (more info on Ab3d.DXEngine diagnostics web page).

Also note, that because of super-sampling, the settings for standard GraphicProfiles have changed:

  • NormalQualityHardwareRendering is the same as before - using 4x MSAA and no super-sampling.
  • HighQualityHardwareRendering is now using 4x MSAA and 4x SSAA (before 8x MSAA was used - so now twice the memory is required and 4 times the number of pixel shaders invocations).
  • UltraQualityHardwareRendering is now using 2x MSAA and 16x SSAA (before 8x MSAA was used - so four times the memory is required and 16 times the number of pixel shaders invocations).

This is important because if you are using HighQualityHardwareRendering or UltraQualityHardwareRendering you should not be surprised if the new version will be slower than the previous version. To compare the performance, use the same settings, or keep in mind that the new super-sampling requires much more work behind the scene.

To summarize, if you show 3D lines, then the superior line quality should justify the costs of super-sampling - especially using 4x SSAA with 4x MSAA. But my recommendation is that you still use it wisely. The easiest option is that your application provides a setting that can change the graphics quality. This way users on slower computers can disable or reduce the super-sampling and still enjoy in great application performance but with reduces quality. To provide a suitable default quality setting, you may check the amount of graphics card memory, display's size and monitor DPI setting (see source code of SystemInfo class for a sample on how to get GPU memory size; you can get DPI settings by a new static GetDpiScale method on DXViewportView).

 

Ok, we have covered the first two points in the highlights list. Let's move on. The most obvious way to hide some of the 3D objects is to remove them from the 3D scene. But when this is done with Ab3d.DXEngine (and if the objects are not added back to the scene in the same frame), then the DirectX resources for the removed objects are disposed and removed from the graphics card. This also means then when those objects are added back to the scene, then the DirectX resources will need to be regenerated and sent to the graphics card.

Ab3d.DXEngine tried to solve this with improved support for IsVisible property that was available with the BaseVisual3D class from Ab3d.PowerToys library. In this case when the IsVisible property was set to false, then all the DirectX resources are preserved, but the rendering of the object is skipped in the rendering loop. This means that when the IsVisible property was set back to true, the object can be shown instantly as no resources need to be created.

Because all Visual3D objects from Ab3d.PowerToys are derived from that class, they all received that improved support. With using ContentVisual3D (also derived from BaseVisual3D) it was also possible to show and hide any GeometryModel3D or Model3DGroup objects that was set to ContentVisual3D.Content property. But if you want to show or hide a hierarchy of Visual3D objects, then you still needed to remove those objects from the scene and then add them back. This was finally solved with the new version of Ab3d.PowerToys and Ab3d.DXEngine that now also fully supports showing and hiding Visual3D objects from ContentVisual3D.Children collection.

What is more, because ContentVisual3D now defines a new ChildrenChanged event, it is much easier (and requires much less CPU time) for the Ab3d.DXEngine to check the changes in the Children collection. This makes the ContentVisual3D class a much more appropriate object to hold other 3D objects than the ModelVisual3D class. To simplify the usage of ContentVisual3D, there is also a new CreateContentVisual3D extension method that can simplify creating ContentVisual3D objects from any GeometryModel3D or Model3DGroup objects.

So using ContentVisual3D with Ab3d.DXEngine can reduce the time in the update phase (in this phase the objects are checked for changes and the RenderingQueues are updated). The new version also significantly reduces update time in some other very common cases. One such case is when an object's transformation is changed. Now, this is processed much faster and in a 3D scene with many objects can provide significantly lower update times. Also, changing individual positions or triangle indices in MeshGeometry3D now takes the faster update path.

Another great new feature is improved support for having different views of the same 3D scene. Each view can have a different camera and use different rendering settings. Before, this was possible only by creating new Viewport3D objects and duplicating the Visual3D objects in each Viewport3D (the MeshGeometry3D and Model3D objects can be shared). What is more, it was not possible to use the same SceneNode objects in multiple views. With the new version of Ab3d.DXEngine it is possible to create a DXViewportView by passing a master DXViewportView as a constructor parameter. This creates a child DXViewportView that uses the same 3D scene (DXScene object) but can provide its own camera and its own rendering settings (rendering scene as wireframe, rendering just some objects of the scene, or using some special effects on some views).

The new samples projects for Ab3d.PowerToys library also comes with a new Wpf3DFile class. This class provides the full source code to read and write wpf3d files. wpf3d is a custom binary file format that can save WPF 3D scene. It can save the hierarchy of Model3D objects with their materials. It can also save model metadata with a preview bitmap. This way you can quickly read the metadata and show that to the user. The following screenshot is showing a sample with four possible wpf3d files:

Simple dialog to import wpf3d files shows some file metadata and preview bitmap

The main use case for using this file format is to convert existing files in other file formats (for example fbx) into wpf3d files. Then you can simply use the Wpf3DFile class to read the files and do not need to distribute the native Assimp library with your application anymore. You can also change the Wpf3DFile source code and store some additional data relevant to you into the file. You may also want to encrypt the data, use any other file extension (not .wpf3d), or make any other change to the file structure.

The last feature that I would like to mention is an improvement to the ViewCubeCameraController.  Because the ViewCubeCameraController provides such an intuitive way to show the orientation of the camera, it is used by many users. Therefore, you will be happy to hear that the new version of ViewCubeCameraController supports clicking on the cube's edges or corners to rotate the camera. For users this is a very nice and useful feature. And what is the best - you just need to update to the latest version of Ab3d.PowerToys and do not need to change anything in your core to provide this new feature.

As always, there are many other new features and fixes. The best way to check them is to see them in action with new samples projects that come with both libraries - start the samples and pay attention to the NEW and UP icons in the samples list on the left (the UP icon also provides a tooltip of what is changed). You can also read the full change log on Ab3d.PowerToys history and Ab3d.DXEngine history.

You can get the new versions from new NuGet packages. If you have a valid updates subscription, you can download new installers from your User Account web page. To just test the new version you can also download the new evaluation version from the Downloads page.

 

Let me conclude with some future plans. 

The .Net 5 was just released two days ago (on 10 November). I did some testing with .Net 5 RC versions and both Ab3d.PowerToys and Ab3d.DXEngine compiled and ran without any problems there. But I run out of time to thoroughly test and update the release process to provide an official .Net 5 versions of the assemblies. But this will be done in the near future. So stay tuned for news about that.

And finally, a sneak peek of a more distanced future:

Early preview of Vulkan rendering engine for .Net running on Linux

This screenshot shows v0.2 of the new Vulkan based rendering engine. The screenshot shows it can run on Linux. There is a Rider IDE in the background. See great performance figures in the window title - note that this is running on an older system with i7 3770 @ 3.4 GHz and NVIDIA 970 GTX. The new rendering engine is being written from the ground up and will use the latest .Net features and all the know-how from Ab3d.PowerToys and Ab3d.DXEngine.

It is hard to say when the first official version of the new engine will be available. Using Vulkan API and different platforms is much more challenging than using DirectX 11 and Windows. Therefore, if you would like to speed up the development, participate in the development by providing feedback and testing on other platforms or would just like to share your wishes and ideas, you are most welcome to contact me.

As always, the goal is to provide you an awesome cross-platform rendering engine for technical, scientific and CAD-like 3D visualizations.

Tags: , , , , , ,

Ab3d.PowerToys | DXEngine

New version of Ab3d.DXEngine comes with DirectX command list caching and many new features

by abenedik 1. June 2020 11:48

I am proud to inform you that a new major release of the Ab3d.DXEngine has been released. There is also a new minor version of Ab3d.PowerToys.

Let's start with a question: what makes a rendering engine faster? The answer is simple: a faster rendering engine will render the 3D scene quicker and achieve higher frames per second. This can be achieved in two ways. The first option is to provide special rendering techniques to the end-user that can optimize the rendering (for example, object instancing). The second option is to organize the data for the 3D scene so that it can be sent to the graphics card as quickly as possible and in a way that allows the graphics card to render the scene the most optimally.

This part of the job is done internally by the DXEngine. This process was already highly optimized for CPU, memory access and can be executed using multiple threads. Still, a 3D scene with a few thousand objects may require a few milliseconds of CPU time to render. In this case, a rendering engine written in C++ or another low-level language may be faster because its code can be better optimized.

But with the introduction of DirectX commands caching in the new version of Ab3d.DXEngine, this advantage of low-level languages is significantly reduced. In case when only camera or lights are changed (the majority of cases in a typical business or scientific 3D application), then the new version of Ab3d.DXEngine can render the new frame with only updating the camera and lights data and then "instructing" the graphics card to re-render the new frame with using the DirectX commands that were recorded in one of the previous frames. This requires so little code to be executed on the CPU, that even if the engine were written in C++, the performance difference would not be noticeable.

Therefore I would like to conclude the first part of this post with a statement that in cases when DirectX commands caching can be used (in a typical business 3D application this is most of the cases) the Ab3d.DXEngine is as fast as if it would be written in C++. 

Let me show you that in action:

Ab3d.DXEngine with DirectX command list caching

As seen from this screenshot, in case of rendering 160.000 individual 3D objects, the time required to send all that data to the graphics card is only 0.14 ms (see DrawRenderTime which shows time to execute 160.000 draw calls with all required state changes). This way, it would be possible to achieve almost 3000 FPS. When the command list caching would be disabled, then the DrawRenderTime would be around 16 ms. This is still a fantastic result and can be achieved using multi-threading and many other optimizations.

Another area that received some great new features is rendering transparent objects. Rendering transparent objects can be hard in 3D graphics. The reason for that is that when a transparent object is rendered, the colors of the already rendered objects are blended with the color of the transparent object. This means that if we want to see the objects through transparent objects, they need to be rendered before the transparent object. Usually (when the objects are not self-intersecting), this can be solved with sorting the objects so that the objects that are farther away from the camera are rendered first. To help you with sorting, you can use the TransparencySorter class from the Ab3d.PowerToys library. But this class work only for WPF 3D objects. What is more, sorting WPF 3D objects can be a very slow process and in case of complex hierarchy, it may not be possible to sort all the objects correctly.

The new version of Ab3d.DXEngine provides a better way of sorting transparent objects. With setting the DXScene.IsTransparencySortingEnabled property to true (by default it is set to false to make the engine work as in the previous version), the engine automatically sorts all the objects in the TransparentRenderingQueue. Because the objects there are defined in a flat queue, there is no problem with the hierarchical organization of objects. Also, sorting is highly optimized and uses multi-threading, so it is much faster than TransparencySorter. And finally, the DXEngine's SceneNodes can also be sorted in this way.

Another new feature regarding transparent objects is the added support for alpha-clipping and alpha-to-coverage. Those two techniques can be used to render textures that have opaque and also transparent pixels (for example, text with a transparent background or threes). An advantage of those two techniques is that they do not require the objects to be sorted by camera distance. But they can produce some artifacts on the areas where the transparent part of the texture is transitioned to the opaque part. If this transition is small, then the results can be very good. In the case of using alpha-clipping, the user can select an alpha clip threshold - this is a value that specifies at which alpha value the pixels are clipped. When using alpha-to-coverage, it is possible to use MSAA (multi-sample anti-aliasing) to provide a more accurate level of transparency with making some sub-pixel samples transparent and some opaque. See the comments in the new sample for more information.

There are also improvements in how textures are loaded. First, all textures that are created from WPF BitmapImage objects are checked if they actually contain transparent pixels. In the previous version, only the file format was checked and if it supported transparency, then the texture was considered transparent. In this case, the object that used that texture was put into the TransparentRenderingQueue - requiring alpha blending (more GPU memory transfer), transparency sorting and having no rendering optimizations. In the version, the DXEngine "knows" if the texture does not have any transparent pixels so its object can be put into the StandardGeometryRenderingQueue. This way, it gets support for multi-threaded rendering and DirectX commands caching.

The last new feature related to transparency is that the TextureLoader.LoadShaderResourceView method has been significantly improved. The method loads a texture into a DirectX resource and now also sets a new TextureInfo class that describes the loaded texture: image size, dpi, format, has transparent pixels. That information can help you correctly set the properties in the StandardMaterial or any other material that is showing the texture.

There are also some other great new features. Let me quickly mention some of them.

Object instancing also received a few improvements. The first improvement is that it is now possible to quickly hide (discard) some instances when setting their alpha color to 0. In the previous version, such instances were still rendered - they were not visible because of alpha value 0, but their depth values were still written and therefore this prevented rendering of all objects behind them. So in the previous version, you needed to re-create the InstancesData array with removing some items from the array.

The next new feature is that now you can render instanced objects with a single color without any light shading. Another instancing improvement is that it is now possible to specify the size of each instance in screen-space units. This means that even when you zoom in or out, the size of the instances on the screen will remain the same (the size calculations are done on the graphics card).

Another performance-related improvement is that now multi-threaded rendering is also supported for 3D lines. Before, it was supported only for standard and opaque 3D objects. It is still better to combine many 3D lines into a single 3D line object (for example, MultiLineVisual3D or even better ScreenSpaceLineNode), but if you happen to have many individual 3D line objects, then the new version could now render at more then 4-times the speed.

If you are an advanced DXEngine user, you will be interested in that the GeometryRenderingQueue has been split into 4 different rendering queues: 

  • ComplexGeometryRenderingQueue - used for instanced objects and very complex meshes (with more than 100.000 triangle indices or 20.000 lines) - the idea is to send such objects to GPU as soon as possible,
  • StandardGeometryRenderingQueue - highly optimized for rendering standard 3D objects - supports multi-threading and command list caching,
  • OtherGeometryRenderingQueue - used for other 3D objects with non-standard effects,
  • LineGeometryRenderingQueue - used for opaque and solid color 3D lines - support multi-threading),

The old GeometryRenderingQueue is still defined in the DXScene class. But it is marked as obsolete and points to the OtherGeometryRenderingQueue. If you are using the GeometryRenderingQueue, please change that to any of the 4 new rendering queues instead.

Advanced users will be also happy to hear that there are some interesting improvements in the Diagnostics project that is also used in the DXEngineSnoop tool (see also Diagnostics Guide). Now you can render an object-id bitmap of the 3D scene - there the colors in the bitmap represent the ids of the rendered objects. You can also disable and enable rendering of some RenderingQueues and RenderingSteps. With those new features, you can diagnose some low-level rendering problems and get some additional understanding of how the rendering engine works.

 

As always, there are many other new features, improvements and bug fixes. This is also true for Ab3d.PowerToys. To get the full list of changes see Ab3d.DXEngine versions history and Ab3d.PowerToys versions history.

From the number of support requests, I have seen that the corona crises have significantly slowed down the development worldwide. This lasted for around a month and a half. Then suddenly, there was a burst of activity that highly exceeded the time before the pandemic. So it looks like during the quarantine, you had time to gather many great new ideas. So, when the development started again, you wanted to try them right away. I was pleased to see that. I hope that the newly published versions will allow you to realize your ideas even more quickly and have better results.

Tags: , , , ,

Ab3d.PowerToys | DXEngine

.NET Core 3.1 support and many other new features for the 3D libraries available

by abenedik 12. December 2019 10:30

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

The new libraries bring many new features and improvements. But probably the most important is that both libraries now support .NET Core 3.1 (released on 3rd December) - see more: https://devblogs.microsoft.com/dotnet/announcing-net-core-3-1/. This version of .Net is a long-term supported (LTS) release. Therefore it is recommended to use that version instead of .NET Core 3.0.

 

Let's go back to the new features.

Probably the most interesting new feature is support for planar shadows. Shadows are very important to give the viewer a real sense of depth and distances between objects. Consider the following two images that show the differences.

Ducks lake sample showing difference between rendering shadows or not


Planar shadows sample showing difference between rendering shadows or not

The first image is showing a Ducks lake sample - there a VarianceShadowRenderingProvider is used to provide nice soft shadows that add a much more realistic feeling where it is very clearly seen that the ducks are actually swimming in the lake. In the right part of the image the ducks might also be floating in the air.

The image below is showing a new sample that uses a new PlanarShadowRenderingProvider. Again, in the part with shadows it is very easy to see the distance between the spheres and the plane. But in the right side without shadows this information is totally lost.

What are the differences between those two shadow rendering techniques?

The VarianceShadowRenderingProvider uses a variance shadow mapping algorithm that can render nice soft shadows with minimal artifacts (compared to some other shadow rendering techniques). The shadows can be rendered to all 3D objects.

In this algorithm, the whole 3D scene is rendered from the light's position into a special texture - a shadow map. The values in this texture do not represent object colors but float values that describe distances from the light. Because the shadow information for the whole 3D scene (not only for visible part) is written into one texture, the resolution of the shadow depends on the size of the shadow texture and the size of the 3D scene. Sometimes it is desirable to have a more blurry shadow. But other times, especially in technical applications, users want to have more precise shadows. To increase the shadow resolution, the shadow texture size needs to be increased (with ShadowMapSize property), or the size of the whole 3D scene needs to be decreased. Increasing the shadow map size can significantly reduce performance. Also, decreasing the size of the 3D scene is not always possible. So this shadow rendering is not ideal for all the cases (there is actually no such technique except ray tracing).

On the other hand, the planar shadow rendering always renders perfectly sharp shadows without any loss of details. But as its name suggests, the shadows can be rendered only to a 3D plane. This techinque is also faster to render. There the shadows are rendered with applying a shadow matrix transformation to all objects. This matrix flattens all the objects so that they have no height and become only 2D shapes that represent the shadows. Those shapes are then rendered as 3D objects on top of the 3D plane.

Disadvantages of planar shadows are that they can be rendered only to 3D planes, they cannot have soft edges, shadows are also rendered for objects behind the plane or point light, some objects that lie on the plane or are very close to the plane may get invalid shadow (too wide). But still, they are an excellent choice for many scenarios.

Anyway, you as a user now have more choice regarding the shadow rendering. What is more, the planar shadows can be also rendered with WPF 3D rendering and do not require Ab3d.DXEngine.

In this case the new PlanarShadowMeshCreator class from Ab3d.PowerToys can generate the 3D mesh that can be rendered as a planar shadow. This class can even clip the shadow to the edges of the 3D plane. But the mesh generation is 100% done on the CPU. And each time the light or the objects are changed, the whole shadow mesh needs to be regenerated. When the 3D scene is complex, this shadow mesh generation can present a performance problem. What is more, WPF 3D cannot render semi-transparent shadows correctly. The problem is that the shadow is darker and less transparent in the areas where multiple parts of the 3D objects are rendered. This means that with WPF 3D only opaque shadows can be correctly rendered. But still, it is possible to significantly improve the visual appearance of some 3D scenes by adding planar shadows without any transparency.

To correctly render the semi-transparent shadows and to avoid the slow 3D mesh generation on the CPU, it is possible to use the PlanarShadowRenderingProvider from Ab3d.DXEngine library. It provides full hardware acceleration for rendering planar shadows and uses the stencil buffer to clip the shadow to the edges of the plane and to prevent semi-transparent shadow artifacts (it ensures that each shadow pixel is rendered only once).

 

Another great new feature of the Ab3d.DXEngine library that was requested from some users is the ability to render 3D lines with different start and end colors. In this case, the line color is interpolated from the start to the end color. It is also possible to specify color's alpha values so that the line slowly fades away (its alpha value goes from 1 to 0). This is very useful for showing trails of moving 3D objects (for example orbits of planets). The following image shows a screenshot from a simple sample that demonstrates that new feature:

Rendering 3D lines with different start and end color

Ab3d.DXEngine can already render huge point clouds with hundreds of millions of points. To optimize rendering in such extreme cases, a OptimizedPointMesh can be used. This object can significantly reduce the number of points that need to be rendered. But until now all the points need to be in the same color. With the new version of Ab3d.DXEngine it is possible to specify a different color for each point.

The new version also improves the mouse rotation and movement when showing point clouds. This is done with new methods that return the 3D position that is closest to the mouse position. This way it is possible to use camera rotation around mouse position when showing point cloud data. Also, because the distance from the camera to the position under the mouse can be correctly calculated, the mouse movement is more precise.

The last new feature in Ab3d.DXEngine that I would like to mention here is that with the new version of the library it is possible to recover from rare cases when the DirectX device is removed or reset by the OS. This happens when the graphics driver is updated while the application is running. This can also happen in case when there is some problem with the driver (very rare). Note that this does not happen when the operating system is restored from sleep or hibernation or when the window is minimized and then opened again.

To handle the DirectX device removal, there is a new DeviceRemoved event in the DXScene class. In the event handler the application can save the current state of the 3D scene, then dispose the current DXViewportView and other 3D objects and finally create a new DXViewportView and recreate the 3D scene from the saved data. There is a simple sample that demonstrates that.

 

Regarding the new Ab3d.PowerToys library I would like to mention that now it works with a new Assimp library v5.0. This provides improved support for importing 3D models from many file formats. What is more, the Ab3d.PowerToys has improved skeletal (skinned) animation that can animate 3D objects with a more complex hierarchy of bones.

Another nice new feature is that the ViewCubeCameraController can now show different bitmaps for selected planes. This gives users a nice indication that they can click on the plane to rotate the camera to see the 3D scene from the selected angle.

 

And finally, I would like to mention two new samples that come with Ab3d.PowerToys.

The first one is called "Basic WPF 3D objects tutorial". I have seen many users that wanted to create an application with 3D graphics and just jumped in and started using the Ab3d.PowerToys library. They may be able to do some complicated things because some powerful features of the library are very easy to be used. But sometimes, when it comes to some relatively simple tasks, they are stuck because they do not know the basics of the WPF 3D objects. This new sample should help such users to be quickly back on track.

Another new sample is called "Standard WPF hit testing". The reasons why I wrote this sample are very similar to the reasons mentioned before. When it comes to 3D hit testing, many users thought that the only way to do that is to use the EventManager3D. The reason for that was that the samples that come with Ab3d.PowerToys were only showing the features of the library and therefore only the usage of EventManager3D was mentioned. So many users were not aware that there is also a low-level way to do the 3D hit testing. In this way, the user can get the closest or all the 3D objects that are behind some specified 2D position (for example mouse position). This approach is actually more useful and can be used in more cases, especially in situations when there are many possible hit objects and when the objects are dynamically added and removed. EventManger3D is more suited for simple 3D scenes where the number of 3D objects is low and does not change a lot.

As always, there are many other new features and improvements. For the full list of changes see the https://www.ab4d.com/DXEngine-history.aspx and https://www.ab4d.com/PowerToys-history.aspx.

 

At this point, I would also like to tell you something about an exciting new feature that is already in development and is planned for the next version. It is called "reused DirectX command lists". With technical 3D applications it is very usual that the 3D scene is mostly static and many times only the camera is changing. With DirectX 11 it is possible to render such 3D scenes extremely fast with almost no CPU overhead. This is done with recording a command list that contains all the DirectX commands that are required to render one 3D scene. After the command list is generated, we can reuse it for other frames. So if only the camera is changed, then we just send new camera information to the graphics card and then instruct it to render the same command list as before. This can be done with almost no CPU time spent. The results are stunning. See the following screenshot:

Stunning performance with reusing DirectX commands list

The arrow is pointing to the area that is showing the CPU time to render the scene. In this case, the CPU time to render 160.000 individual boxes (without using instancing but with creating one draw call for each object) is only 0.10 ms. Now compare that with what is possible to achieve with standard rendering process and with full multi-threading - see the screenshot from https://www.ab4d.com/images/DXEngineGallery/DXEngine-Multi-threaded-rendering.png

There you can see that the CPU time to render the scene is almost 15 ms. This is still an incredible achievement, but compared to 0.10 ms it is a lot.

There are some complex challenges that need to be solved before reused command lists can be used in a generic purpose rendering engine as Ab3d.DXEngine is. As you can see, a special demo version is already running. A more generic version will be ready for the next release, so stay tuned.

 

As it was already announced in the previous blog post, the new versions of Ab3d.PowerToys and Ab3d.DXEngine are available through multiple sources:

  • NuGet packages (https://www.nuget.org/packages/Ab3d.PowerToys/ and https://www.nuget.org/packages/Ab3d.DXEngine/). This distribution includes assemblies for .NET Framework 4.0 and 4.5+ and for .NET Core 3.1. The same dll (assembly) is used for both evaluation and commercial usage. By default, the evaluation license is started. The commercial license can be activated with calling the SetLicense method and providing the license information. In the near future, it will be possible to get the license parameters from the Users Account web page. Until then, please contact us for the parameters.
  • The commercial version installer can be downloaded from the User Account web page. Because the old licensing system that uses license.licx files cannot be used in .NET Core, this distribution contains only assemblies for .NET Framework 4.0 and 4.5+.
  • The evaluation installer can be downloaded from Downloads web page - https://www.ab4d.com/Downloads.aspx. Also contains only assemblies for .NET Framework 4.0 and 4.5+.

Tags: , , , , , , ,

Ab3d.PowerToys | DXEngine