UNIGINE 2.17: DX12 & Vulkan In Production State, PSDGI, More Performance, Tools Upgrade, Photon Networking
- DirectX 12 and Vulkan API support (production)
- Multiple performance optimizations
- Panorama space dynamic global illumination
- Spatial temporal denoiser
- Streaming improvements
- Improved spacers and deflectors for particles
- Multiple tools improvements in the editor
- IG updates (VR, weather radar, CIGI symbols)
- Photon engine integration (network)
- A set of new C++ samples
- Add-On Store update
This release brings you production-ready support for DirectX 12 and Vulkan, improved streaming and other performance optimizations for Engine and Editor, massive pack of updates for most of the Editor tools, a huge step to a full-scale GI solution (new spatial denoiser + panorama space dynamic GI) and many other updates.
DirectX 12 and Vulkan (Production)
We have put a lot of effort into implementation of features missing for DirectX 12 and Vulkan (like terrains, occlusion queries etc.), as well as into stabilization and related Engine modifications. And now we are ready to say: DirectX 12 and Vulkan support is now production-ready and available for everyone (both in the Editor and runtime)!
The immediate effect is increased CPU performance. Please be aware that this release is the last one to support OpenGL (starting from 2.18 Vulkan will be the main graphics API for Linux).
Panorama Space Dynamic Global Illumination (PSDGI)
We have added a new Raymarching mode for the Environment Probe light source. This is a far more advanced high-quality dynamic GI technique than any other solution used in UNIGINE before.
In Sphere and Box Projection modes the probe provides imitation of reflections as if we were inside a spherical or box-shaped room respectively. New mode enables the probe to render reflections taking the geometry of surfaces around.
You can think of it as Screen Space Global Illumination but for a 360-degree range. This approach does not substitute a full-scale global illumination solution but provides similar quality for outdoor scenes. Lighting is calculated using physically-correct formulas ensuring that reflections as well as diffuse lighting will become much more realistic in comparison with traditional cubemap-based techniques.
This approach is very resource-consuming, so we don't recommend using it everywhere. It is an experimental approach and it won't work universally for any content, but if you have an open-world location everything will work just fine. Moreover, you can optionally use only diffuse lighting or only specular. For example if you use lightmaps providing maximum diffuse lighting information, the Raymarching Environment Probe will improve the quality of reflections pushing it close to ray tracing in terms of quality.
You can put a probe somewhere in your world like you usually do, or you can attach it as a child to a camera. In Raymarching mode the probe is always rendered dynamically - it has no static pre-baked mode.
This technology combined with the new denoiser is a huge step to a full-scale GI solution.
Spatial Temporal Denoiser
We have replaced our old denoiser with a new one. The old version could not provide the required level of noise reduction when calculating Global Illumination using ray-tracing algorithms.
The new implementation deals much better with noise in reflections and diffuse lighting and at the same time it is smart enough to preserve illumination details. So, now we do not apply denoiser for each post-effect, instead we do it once for the whole resulting indirect specular and indirect diffuse buffers. This approach enables us to effectively remove noise for any GI technique such as SSRTGI, SSR, or even ray tracing.
Water Decals Updated
Water Decals have been improved and now support black albedo color enabling you to create oil spills on water surface.
Water Decals now support the auxiliary buffer, enabling you to imitate local water temperature changes (cooling down or heating up, like in case of burning oil spills) and visualize them in thermal sensors.
Other Rendering Improvements
- Fixed an issue with incorrect colors produced by Auto White Balance correction in case of too bright objects in the viewport.
- Fixed an issue with incorrect haze rendering in environment reflections.
- Added clouds and water to Texture Buffer Screen Color Opacity ensuring visibility of water and clouds behind transparent objects.
- Combined constant buffers for Environment Probe and fixed shader.
Spacers and Deflectors for Particles
For this release we have also made changes to Particle Systems to make them more flexible and convenient. Deflectors, noises, and forces that were bound to a particular Particle System are now separate entities, which makes their setup simpler and much more convenient without having to make the same adjustments multiple times for several Particle Systems.
Particles are now affected by the Physical Force or Noise nodes - just add a Physical Force, adjust its settings, and have it interacting with particles emitted by all Particle Systems having a matching Physical Mask!
A couple of new nodes were also added to replace old deflectors:
Particles Spacer (ParticlesFieldSpacer) - an invisible volumetric field used to cut out particles generated by a Particle System from a certain volume, for example, to avoid rendering of rain or snow inside a car or under a bridge (it is functionally similar to the Spacer Field used for cutting out water or grass). It can have a box, cylinder, capsule, sphere, or ellipse shape and can be arbitrarily positioned or rotated to cover the necessary area. The Particles Spacer completely replaces and extends the functionality of the old clipper-deflector that was merely a flat rectangle. Moreover, the new Spacer enables you to cut out particles from a volume containing the emitter of the Particle System which was not possible, and it works up to 10x faster!
Particles Deflector (ParticlesFieldDeflector) - an invisible rectangular or square surface field that physically interacts with Particle Systems (other objects unaffected) blocking the way for emitted particles and making them bounce off its surface. The new Deflector replaces functions of embedded deflectors, it can be arbitrarily positioned and rotated to cover the necessary area.
Each Spacer and Deflector as a separate node can be used to cut or reflect particles generated by multiple Particle Systems (only one "owner" system was affected before) with interaction controlled via the new Particles Field Mask giving you a lot of flexibility.
- Duplicating PhysicsIntersection/Collision flags were removed from the Interaction group of the Particle System parameters to ensure consistency. Now both, flags and masks for Collision and Physics Intersection are put in one place - surface parameters.
- A new interaction mode is available for Deflector and Spacer enabling you to take into account particle size when detecting collisions and intersections, ensuring correct interaction for Length. particles.
- You can also control minimum and maximum size a single particle can occupy on the screen in the range from 0 (0% of the screen size) to 1 (the whole screen) to fine-tune the effects and make them even more realistic.
Improved Asynchronous Mesh Streaming
We have significantly improved asynchronous geometry streaming by eliminating memory leaks and increasing control over the streaming process.
Meshes can now be loaded to RAM and VRAM separately to make work with geometry faster and more efficient, enabling to eliminate memory leaks that occurred previously. Adjustable memory limits and lifetimes for meshes loaded to RAM and VRAM make it possible to avoid situations where a mesh remains loaded in memory even after it is no longer rendered. Moreover, the new streaming approach allows loading meshes participating in collisions and intersections only to RAM, if they are not currently rendered.
There are 3 modes of mesh streaming to RAM/VRAM:
- Asynchronous mode that provides asynchronous loading of meshes.
- Forced mode for force-loading of meshes required for the current frame at once.
- Mode for loading all meshes available in the project on the application start-up. This mode is good for small projects with a small number of meshes.
The asynchronous loading to RAM and VRAM differs:
- Even if a mesh hasn't been loaded to video memory in time, it doesn't affect the application behavior (you may only notice some lag).
- If a mesh hasn't been loaded to RAM in time, it may lead to incorrect physical behavior of objects in the scene.
So, we developed additional methods that allow getting correct results and eliminating performance spikes caused by physics calculations:
- Using the prefetch system for asynchronous pre-loading of meshes participating in collisions and intersections to memory before they are used.
- Loading to and holding in memory a single mesh participating in physical interactions.
To make the scene appear immediately when the application starts, you can now specify the number of frames for loading right after the first frame.
The time limit for deleting resources was also divided: now you can set it for meshes and textures individually.
All streaming-related settings described above can be adjusted via UnigineEditor or via render_streaming_* console commands and API.
The rendering statistics parameters in the Performance Profiler were grouped by RAM and VRAM.
We have also improved API of mesh-related objects (ObjectMeshStatic, ObjectMeshCluster, ObjectMeshClutter, ObjectGuiMesh and DecalMesh) to make it clear and easy to use:
- Loading of the base static mesh to RAM and VRAM is done separately (both asynchronous and forced modes).
- Your own prefetch system for geometry can be implemented via the new loadAsyncRAM() and loadAsyncVRAM() methods.
- Changing of the base static mesh is now possible only if it is in the procedural mode. A procedural mesh is a mesh created via code, such meshes have a specific streaming mode — they are always kept in memory after creation and never unloaded until the object is destroyed via code or the mesh returns to its normal mode (streaming from a source file).
We got rid of implicit forced loading of geometry to video memory. Now the MeshStatic API provides methods enabling you to control loading, deleting, and reloading meshes to VRAM.
Better Landscape Terrain Streaming
This release also brings improvements of asynchronous streaming performance for Landscape Terrain and reduction of performance spikes:
- Pre-loading of heights data within the CPU cache prefetch radius for correct collisions and intersections calculation.
- Asynchronous loading of compressed Landscape Layer Maps that cannot be modified (unavailable in case of using layer maps without compression).
Immovable, Collision, and Intersection Flags
We've added a pack of optimizations regarding management of nodes with the Immovable, Intersection, and Collision flags to improve performance and make the whole process consistent and transparent.
To ensure consistency the Collision, Intersection, and Immovable flags can only be enabled for objects that actually support these features (by default the Immovable flag is enabled for all created objects).
Before 2.17 you could set the Immovable flag for any node, while the actions with nodes added to the special immovable spatial tree were totally unrestricted. So, you could end up with a performance drop without knowing the reason (such cases are especially hard to track in large-scale projects). We have put some restrictions on cases when nodes can be added to the spatial tree. Now in case of any incorrect action with a node marked as Immovable (any action affecting the spatial tree), you'll get the corresponding warning message (e.g. in case of trying to assign a physical body to an Immovable object).
And the Engine will warn you by default in case of any attempts to move nodes marked as Immovable. You can also completely prohibit such actions or on the contrary allow them and disable these warnings if necessary via the world_moving_immovable_node_mode console command or via API. However, please be aware that there are two cases when you may disable warnings and allow movement of Immovable nodes:
- At run time for procedural generation of levels. This may cause some freezing but won't affect performance much. Upon completion of the generation process you should enable warnings again.
- On world initialization, this will change world loading time but won't affect overall performance.
HighDPI Support (Engine)
Engine's High DPI support configuration settings have been improved (to be implemented in the Editor in the upcoming releases) with various DPI awareness modes added for DPI scaling to facilitate integration into other frameworks (no scaling at all, scaling set by user, scaling of the main monitor in the system, per-monitor DPI setting).
You can now set window and widget size both, in pixels and in units. In case no scaling is applied 1 pixel is equal to 1 unit, otherwise these values will differ, this should be considered in the application logic. If you don't want to implement these changes in your logic, disable the GUI scaling using the auto_dpi_scaling 0 console command.
Currently scaling implies changing the scale of the texture, not uploading a texture with a different resolution. This is going to be implemented in upcoming releases.
Examples of High DPI management via API are shown in the following samples:
Asynchronous GPU-to-CPU Data Transfer
Implementation of Vulkan and DirectX 12 support has changed a lot, and the old-style way of getting GPU-generated data on CPU has become invalid.
Thus, we have removed Texture::getImage/StructuredBuffer::getData() methods and added the following ones instead:
- Render::transferTextureToImage() — getting an image inside a callback-function in the same frame (swap). Calls CPU-GPU synchronization (like it was before).
- Render::asyncTransferTextureToImage() — getting an image inside a callback-function without calling CPU-GPU synchronization. The Engine Loop should cycle again and again to complete this async operation.
- Render::transferStructuredBuffer()/asyncTransferStructuredBuffer() — similar to StructuredBuffer.
All other methods transferring data generated by GPU to CPU (returning the result as an Image) have been replaced with the ones that return their result as a Texture. In order to get this data as Image (the way it was before) you'll have to transfer the obtained data to CPU using a synchronous or asynchronous transferring method of the Render class — transferTextureToImage() or asyncTransferTextureToImage() respectively. This is relevant for methods like Viewport::renderImage*(), Render::renderImage*(), FieldShoreline::createShorelineDistanceField(), WidgetSpriteViewport::renderTexture(), and others. Render::compressImage()/asyncCompressImage() represent the only exception — they cannot output the result to a texture accepting callbacks as arguments.
Other related API changes:
- A new createMipmapsCubeGGX() method has been added to the Image class to enable generation of GGX mipmaps on CPU, of course slower and with lower quality than on GPU but providing the result synchronously (actually this should be the only case, when this method is to be used).
- The ImageConverter class now has a new run() method with a callback making it possible to use GPU, and runCpu() that uses CPU only and is capable of returning the result synchronously.
- Added new Engine::beginOutsideLoopRender()/endOutsideLoopRender() methods for cases when it is required to call Render class methods from outside the Engine Loop.
- Render::transferTextureToImage()/transferStructuredBuffer() callbacks will be called in endOutsideLoopRender(). It is recommended to render inside the Engine Loop whenever possible.
- All Engine and Editor subsystems (brushes, bakers, etc.) were switched to new API as well as related samples like LiDAR, Screenshot, and Offscreen.
For more details and examples please check the API Migration Guide.
UNIGINE and User Plugins (Important)
The plugin files structure has been rearranged to ensure consistent management of all plugins including user-developed ones, the approach to their naming has changed as well.
For more details please check the API Migration Guide. And don't forget to adjust the build paths and plugin names for all plugins in the projects that you've migrated.
Buffered Input for Joysticks and Gamepads
We have significantly improved input handling for joysticks and gamepads making it more convenient and reliable with event buffers added , so you can forget about lost input events. Old ControlsGamePad and ControlsJoystick classes were completely replaced with InputGamepad and InputJoystick respectively with all necessary functions migrated, instances of these classes are managed (created, deleted, and updated) automatically by the Engine, you don't have to do it manually anymore. Numbers of gamepads and joysticks changes dynamically as you connect or disconnect devices (these numbers are not limited by the Engine, while there is an SDL limit of 16 devices). A new set of callbacks has been added to the Input class for both joysticks and gamepads, enabling you to track more events.
For more details on changes as well as instructions on how to migrate your code please refer to the API Migration Guide.
Other Input Changes:
- Added touchpad input support for DualShock/DualSense controllers.
- Renamed Input::DEVICE_TYPE enumeration to Input::DEVICE to avoid conflicts with DEVICE_TYPE enum defined in winioctl.h.
- Added events-related methods of the Input class to UnigineScript API.
Other major changes:
- Added callbacks for every action (resized, focused, minimized, stacked, on mouse enter, etc.).
- Implemented automatic deletion modes.
- Implemented engine style for windows with the possibility to customize the window (window position, size, sizes of window decorations). This approach makes it possible to create a standard set of window settings for different systems and frameworks.
- Implemented adjustment of fixed size, minimum and maximum sizes.
- Size settings for windows, groups and tabs are unified now.
- Group size now takes sizes of tabs into account.
- Added an ability for windows to render into a GUI like all other widgets which can be useful when there is a single system window available, or when switching an application to fullscreen mode.
You can check out all settings in action in the new set of Window Manager samples (source/samples/Api/WindowManager). This set has been extended and now covers almost the whole API for windows (WindowBehaviour, WindowIntersection, WindowModal, WindowOrder, WindowPosition, WindowSize, and WindowVisual). You can create any windows and groups in the WindowSandbox and check out the majority of API functions in use for better understanding.
Other Engine Improvements
- Node data serialization order has been made stable eliminating data rearrangement on saving a world. Spontaneous rearrangement of cluster element positions on saving a world has been eliminated as well.
- Added program database (.pdb) files for Release binaries of the Engine, plugins, and libraries. Now users can send crash reports with a call stack for Release versions as well.
- Added forced streaming for environment textures to ensure proper lighting on loading a world.
- Fixed an issue with deleting selected text in EditText and EditLine widgets.
- Added scrolling and resize functionality for the EditText widgets.
- Fixed an issue with not calling the OnEnable() method for C# components that were disabled at the application startup.
- Fixed an issue with throwing WorldTrigger callbacks for objects with Triggers Interaction disabled.
- Fixed an issue with loading a NodeLayer having a nested NodeLayer with an invalid GUID.
- Added a new String::join() method enabling you to combine multiple strings.
- Added a pack of hidden internal drawing methods for WidgetExternBase were exposed to public API. Check the API Migration Guide for details.
- A pack of missing methods has been added to the FMOD plugin.
- Fixed behavior of Wheel Joints under the terrain's surface (e.g. when a vehicle drives in an underground parking or tunnel). You can set the CanBeUnderTerrain flag when necessary.
- Fixed an issue with Landscape Masks fetching sometimes resulting in disappearing objects that were placed using these masks.
- Fixed reloading of the Landscape Terrain data sometimes causing "blinking" due to several subsequent reloading operations.
- Fixed an issue with importing graph-based materials from a package.
- Fixed an issue with a non-functional Participate in Post-Effects parameter.
- Orthographic mode for cameras and players now work as expected, both in the Editor and runtime. You can switch projection mode to Orthographic and specify desired height via API at runtime as well.
- SDL version was updated to v2.0.18.
- Fixed a crash associated with using the String::format("%s", text) overload. In case you need to specify the variable argument list directly, use the new String::vformat("%s", text) overload.
- Fixed incorrect removal of widgets on the Engine shutdown sometimes resulting in a crash.
- Added an ability to change the current font for WidgetCanvas to enable printing on canvas using multiple different fonts.
- Added a Vertex color visualizer to highlight geometry using selected vertex colors (the feature is also available in the Editor via the Rendering Debug menu).
- Default Vertex Color (used for meshes having no Vertex Color information on importing) has been changed to black with zero alpha (0, 0, 0, 0) instead of (1, 1, 1, 1) used earlier.
- Improved GUID generation algorithm to avoid possible collisions.
- Fixed minor issues with item selection in WidgetTreeBox and WidgetListBox sometimes resulting in selection of wrong items.
- Texture wrapping parameters are now saved correctly to the material file.
- Added a new preRender() method to the Gui class to ensure proper rendering of WidgetSpriteViewport and WidgetSpriteNode widgets during render(). This method is used to make necessary preparations for rendering (e.g. prepare a texture) after the update() and is called automatically for WidgetSpriteViewport and WidgetSpriteNode. In case you implement a custom GUI or widgets using the WidgetExtern class you should put all such rendering preparations to preRender() and call preRender() for GUI manually after update().
- Added a new background update mode to ensure rendering for windows minimized to tray (this can be useful for grabbing frame sequences in background when the application window is minimized). For more information please refer to the API Migration Guide.
- A new reversebits() method that reverses the order of the bits (per component) has been added to the MathLib.
We have optimized UI creation process splitting the whole process into on-demand portions providing a noticeable speedup at startup of the Editor for all projects. Of course the speedup rate will be less perceptible for large scale projects as UI creation takes less time than project content processing. Average startup GUI generation time has reduced by almost 50%.
Better Profiling Tools
Updated Texture Profiler and Visualizers
Big projects with a huge number of assets have to face the optimization stage to improve performance and have acceptable FPS. Performance Profiler just gives an overview, and you need more tools to get details. We have updated one of them, the Texture Profiler, with a visual representation of relative memory consumption, where each texture is represented as a colored rectangle having its size proportional to the fracture of memory it occupies.
Two new visualizers for textures are now available in the Rendering Debug menu simplifying optimization:
- Texture Max Pixel Count - paints surfaces depending on maximum resolution of textures used in materials assigned to them applying colors in accordance with the scale.
- Texture Screen Density - enables you to estimate the relationship between maximum texture resolution of the material to the size of triangles on the screen to which it is applied: blue - indicates insufficient texture resolution, while yellow tells that it is excessive, if the color is green - everything is ok.
The Texture Profiler has become a part of the Content Profiler along with the new profiler for Surfaces that you'll find in 2.17 as well.
New Surface Profiler
No matter where you look in the scene, most likely you'll see surfaces - it is a key rendering unit. Surfaces have a lot of options and parameters that affect rendering and overall performance of your application (LOD visibility distances, number of polygons, lightmaps, collision and shadow settings, etc.). And again you need details for proper optimization. We've added a new Surface Profiler (available for Development builds) to provide these details - information on the number of surfaces, meshes, nodes, and materials visible in the viewport. The diagram in the right part is similar to the one in the
You can choose surface data to be shown in the table (polygon-related details, masks, memory consumption, whatever you need) and sort items as necessary.
More New Advanced Helpers
We keep on extending the arsenal of visual debugging tools, so we added a pack of new helper visualizers to the Helpers menu for various purposes enabling you to selectively highlight and check virtually anything you want, from emissive objects to objects having a certain Intersection mask. The new pack includes:
- Objects with materials having the Emission state enabled.
- Objects using Complex Shadow Shaders.
- Objects having the Immovable option disabled.
- Objects having a Surface Custom Texture assigned, unused, or unavailable.
- Objects having Physics Intersection, Intersection, or Collision flags enabled.
- Objects using graph-based or non-graph-based materials.
- Nodes interacting with triggers, clutters, or grass.
- Nodes having certain masks (Collision, Viewport, Shadow, Material, or any other).
- You can control visibility distance for visualizers to reduce visual noise while keeping necessary information at hand for objects nearby.
To simplify the process of transferring your content, code, and other creations between projects and sharing it with others we continue improving package creation and management in the Editor.
Apart from adding asset files from your project's data directory to a package you may also want to pack C++ code from your project's source directory, your plugin binaries from bin, and maybe something else… Starting from 2.17 you can pack directories and files at the same level as bin and data directories via the Add External Files button.
You can save the current package files hierarchy and export settings into a preset. You can use this preset later to re-create the same package after making changes to it (e.g. upgrading to a new version, migrating to new API, or adding new features). Instead of manually selecting all the files and adjusting settings again, you just open your preset and make related changes to it (add new files, remove the ones no longer needed).
Another thing that has become available for packages downloaded from the Add-On Store is Package History. The Add-On Store Package History window displays information on imported packages and enables you to remove a package with all imported files to upload the updated package version; it also enables you to unlink selected files from the package to exclude them from the management scope of the Package History tool.
The Packages menu tab has been added giving you quick access to package export and import options.
Advanced Filtering in Materials Hierarchy
We have added an advanced filtering for the Materials hierarchy window. Some projects may contain thousands, tens of thousands materials, that's what we have faced in some of our own projects. In order to manage this huge number of materials and have a clear understanding of what each material is, we need a table view (like for a database) with a lot of categories as well as filtering and sorting capabilities.
You can toggle displaying of various material types, show or hide columns in the table view representing various material parameters. For example you can select only materials inherited from the mesh_base material and check which of them are two-sided, which of them use emission, etc.
This tool is essential for refactoring of a large materials library in your projects. Especially if your objective is to transfer materials from mesh_base to graph-based ones.
Filtering by names in Materials and Properties hierarchy windows is now case-insensitive.
Reparenting of materials has also become more convenient now supporting global selection (e.g. some materials for this operation can be selected via the Materials window, while others via Asset Browser).
Cluster Paint Tool Update
We have updated the Cluster Paint Tool with filters enabling you to choose the type of object on which you want to paint, as well as whether to paint on all surfaces or only the ones with the Intersection option enabled, making the tool even more flexible and convenient. Some minor issues were also fixed including the ones related to eraser behavior ensuring correct and stable operation.
Brush radius change for this and all other similar tools has been made non-linear - the standard increment changes depending on the current brush value: 0.01 (from 0.1 to 1.0 range), 0.1 (from 1.0 to 10.0 range), 1.0 (from 10.0 to 100.0 range), etc. You can also control the current step by holding hotkeys while scrolling the mouse wheel: the Shift key increases the step 10 times, while the Ctrl key enables a 10-fold decrease.
When multiple clusters are selected a random seed is generated for each of them to add more variations.
Added an ability to increase Density Multiplier above 1.
Better Focus and Selection
Focus and Huge Bound Boxes
Focusing on nodes by their bounds sometimes can be very inconvenient, particularly in case the selection you focus on contains cameras, lights, or effects with huge or infinite ranges. Focusing on a Node Reference with a meter-sized mesh object and a light source having a range of 1 km before 2.17 would make Editor zoom out to fit both nodes plus 1km range in the viewport, so you won't see the mesh at all. We have changed the default focusing mode (F key) and now it takes into account only positions of selected nodes, previous focusing mode (by bounds) is available via Shift + F.
Focusing on Node References now ignores disabled nodes in their hierarchy. The same is implemented for node previews in the Asset Browser.
When building and setting up your virtual worlds in the Editor it might be useful to select nodes of a certain type in some area (e.g. lights to adjust them all at once or focus selection on physical shapes to adjust colliders). Starting from 2.17 the selection filter is at your disposal - just pick the nodes you want to deal with and use frame selection - no more unwanted objects!
Cleaner is a tool you use to optimize your project and save disk space by removing unnecessary assets. Sometimes it might be necessary to perform cleanup within a certain directory. We have extended Cleaner functionality making it faster, more flexible, and convenient. Now it enables you to display unused and lost assets for the selected directory (dependencies are checked for the whole project of course).
All assets displayed in the lists now have previews for convenience. And cross-tool selection now works as it should for Cleaner, Asset Browser, Materials, and Properties hierarchies.
Asset type detection has been improved, as well as dependency search with better performance, correct validation of dependencies for unused assets, ability to check keys in JSON files and an option to add custom file extensions (Settings -> Editor -> Project Settings).
You can find more details in the updated article.
Improved Dependency Search and Assets Management
We have optimized performance of dependency search (used in Cleaner, Show Assets Using This One, Show Assets Used, and many other Editor subsystems and operations), making it up to 3 times faster which is especially important for large-scale projects using a huge number of assets.
Dependency search for materials called via the Show Assets Using This One context menu item shall now contain Is Parent Material For These Assets column to display the list of derived materials.
Other related improvements include:
- Multi-selection is now available in the following windows: World Nodes Using This Asset, Assets Using This One, and Assets Used.
- You can now find which nodes in the current world use a certain asset, just right-click it and select Show World Nodes Using This Asset from the context menu.
- Replace Asset Links function has become available in Materials and Property hierarchies as well.
- You can now change names of multiple selected nodes to the name of the source asset for each of them (nodes having the same source asset will have index postfixes). This improves consistency and makes it clear that certain nodes are actually similar. Just select nodes, right-click and select Rename to Asset Name from the context menu.
Version Control System Plugin (SVN)
Subversion (or SVN) is one of the most frequently used version control systems for content-heavy UNIGINE-based projects. So, we have implemented SVN Integration for UNIGINE as SVN Plugin utilizing TortoiseSVN functionality.
SVN Plugin does not have an interface and starts automatically after Asset System initialization and importing of all assets. During operation, the plugin remains invisible to you, so your work is practically the same as it was before. You can also delete, add, rename, change, move, and create files and directories, but now SVN Plugin will track and process all your actions, saving your time on commit preparation. Like any other plugin, it can be loaded and unloaded via the Editor Plugins window (Help -> Plugins).
The general workflow is simple:
- Before you start, update (SVN Update), and clean up the repository (SVN Cleanup).
- Then start the Editor and work as usual (add, remove and change files and directories as you always did).
- When finished, save the project, and close the Editor. It is recommended to close the Editor, as an update may be required before the commit, which can break everything.
- Commit your changes to the repository (SVN Commit). If conflicts arise, resolve them the same way you did before, but keep in mind that all changes made outside the Editor (via the Explorer) will not have the correct status.
For more information on using SVN Plugin please refer to this article.
Material Graph Editor Updates
- Added a new Cubic Mip sampler to the Sample Texture node.
- For your convenience you can now scroll and resize the working space of the code editor widget for the Function node.
- Fixed an issue related to the ULON Material widget sometimes resulting in crashes on material changing.
- Fixed incorrect operation of the RotateZ node.
- Fixed an issue with updating Texture Ramp parameters in child material graphs on making changes to the parent graph. Issues causing crashes on an attemt to edit child materials after changing types of parameters in a parent material graph were fixed as well.
- Fixed a crash on using a context menu.
- Fixed an issue with resetting the value of a material parameter after changing the parameter name.
- Fixed issues with updating windows on stacking/unstacking.
- Fixed assertion failure on entering a wrong name to the Subgraph node.
- The following new subgraphs were added:
Animation Old Time
Blinn Brdf Importance Sampling
Other UnigineEditor Improvements
- The Editor now works only with *.world files stored in the project's data directory or any of valid mount points with read-write permissions.
- To add a new child to any node in the World Nodes hierarchy right-click it and select the desired child node type in the Create submenu.
- Added a new Take By Name From Assets Without Creation option for importing materials from FBX assets enabling you to minimize creation of unwanted materials when importing a lot of models. When set the Import System will try to find an existing material by name and assign it to the object, in case no suitable material is found, the default mesh_base shall be assigned.
- Fixed a crash on importing an FBX-asset with an option to generate graph-based materials (Base Materials Mode).
- We have added more flexibility to Drop To Ground and Snap To Surface instruments enabling you to take all surfaces into account or limit the scope only to the ones having the Intersection option enabled.
- Fixed behavior of the Make Parent function (Ctrl+P), now the last selected node will become a parent for the rest of selected nodes.
- Added an ability to disable Windows Defender checks for a certain project. This can be useful for huge projects with a lot of assets, where Antimalware checks slow down UnigineEditor operation. The Editor will automatically detect a slowdown and display a suggestion to fix it. You can control this option via Settings -> Editor -> User Project Settings -> Suggest to Disable Windows Defender.
- Editor viewports and camera configurations for each world are now stored in separate user project settings instead of world meta files. You can also set the exact position and orientation for the Editor camera in the Camera Settings window and save current parameters to the .world.meta file (scene_cameras section) via the Save Editor Camera Parameters to World Metadata button.
- Fixed Track (Crab) for the Editor Camera in orthographic projection mode after focusing on a node.
- Fixed an issue with resetting current node selection on reloading the world (e.g. when stopping physical simulation).
- Fixed an issue with the FPS field in Physics Settings ( World -> Physics -> FPS) resulting in inability to increase FPS value back after decreasing it.
- Added migration for template material graphs stored in editor resources.
- In case of a non-existing Migration Directory path specified (e.g. a disconnected network location) packages will be imported using a default one.
- Fixed a crash on removing bones after loading them for a Ragdoll body assigned to a Skinned Mesh.
- Fixed an issue with lightmaps corruption on reimporting multiple FBX-assets selected.
- Fixed an issue with some hotkeys ignoring hotkey presets switching.
- Fixed an issue with file size calculation for UNG-archived files stored in mount points.
- Fixed an issue with graph-based materials reloading resulting in parameter control widgets sometimes becoming unresponsive.
- The number of selected assets is now displayed separately for different asset types.
- Video memory consumption is now displayed for textures in the Preview panel.
- Fixed a crash on preview generation for a nested NodeReference.
- Fixed a crash on deleting an .mgraph material along with its child.
- Fixed name generation for new materials created via Create Material Graph.
- Fixed a crash of RuntimesGenerator in case the data folder contains assets without meta-files.
- Selected Node Info no longer overlaps the Profiler information.
- Fixed an issue with copying a Node Layer to another world resulting in changing identifiers of nodes it contains.
- Fixed an issue with breaking the hierarchy of nodes contained in multiple NodeReferences edited simultaneously on saving a world.
- Fixed an issue with invalid meta files for texture assets sometimes leading to incorrect handling of such assets by different Editor subsystems. Invalid texture metadata will be now regenerated.
- Fixed an issue with switching to rename mode on reselecting one of multiple nodes selected in the World Nodes hierarchy.
- Updated OpenCASCADE version to 7.7.1, fixing issues with importing .IGES files.
- Fixed an issue with resetting node parameters before saving a world sometimes leading to a crash (e.g., on saving a world with a Node Reference containing a SoundSource being edited).
- Fixed an issue with exporting graph-based materials assigned to nodes exported to FBX.
- Fixed an issue with resetting the current selection in the process of selecting multiple items in the Materials and World Nodes hierarchy windows.
- Fixed an issue with duplicating child objects when creating Mesh Clusters from selected hierarchy of nodes (Create Mesh Clusters From Hierarchy).
- Fixed an issue with displaying incorrect information in the Preview panel for .EXR texture assets having the Unchanged option enabled.
- Fixed an issue with enabling a disabled node after unparenting it from another disabled node.
- Fixed an issue with enabling surfaces that were disabled in source mesh-objects after creating mesh clusters via Create Mesh Clusters from Hierarchy.
- Fixed an issue with detecting intersections with Translation manipulator axes sometimes resulting in misclicks.
- Fixed an issue with wrong application of the Opacity parameter for decals using graph-based materials.
- Fixed controls in the Editor Viewport on Linux with Wayland window system.
- References to bind nodes will be remapped when cloning/loading Skinned Mesh objects to avoid losing links to nodes used to control bones.
- Colored vector widgets are now used everywhere in the Editor.
Sandworm Tool Improvements
- Terrain type is now selected at creating the project and cannot be changed.
- You can now create a new Sandworm project and copy the content of an existing one (this feature enables you, for example, to quickly change the terrain type).
- Masks and heights for roads on the Landscape Terrain can also be configured now (see the documentation for details).
- Copying masks and objects via the right mouse button is now available.
- Minor UI improvements and bug fixes.
Evolution: Asset Store to Add-On Store
Further development of the Store where you can share your creations continues. We renamed it Add-On Store and implemented the ability to publish free assets for all users. We are also putting the finishing touches on the monetization functionality (ability to get money for your assets): it will be available for all publishers soon.
Changes affected not only the publishing process. We improved and simplified the add-ons workflow for users:
- Add-ons available for free are added to the list of the purchased add-ons automatically after clicking the Free button.
- Purchasing paid add-ons is expected to be available soon as well.
- The purchased assets (free and paid ones) are now downloaded as packages (.upackage) from Add-On Store and can be opened and unpacked right in the Editor, bypassing UNIGINE SDK Browser. So, SDK Browser doesn't provide access to add-ons of UNIGINE projects anymore.
We also improved targeting search to help users organize and find the add-ons they need.
The new add-on workflow will be available starting from UNIGINE 2.17. For previous versions, it remains the same as before.
To simplify the process for both publishers and users, the updated version of Add-On Store Documentation is here to help.
Studies confirm the high effectiveness of training in VR for many industries, and aviation is no exception. VR solutions are highly scalable compared to classic simulators. All interior equipment is represented within the virtual environment; trainees need only VR headsets and flight controls. To give you an ability to use features offered by the IG Application Template for building VR-based simulators we have added a new IG+VR Template enabling you to automatically create a project with both VR and IG features. The work on this template has only started, and it only contains basic VR and IG logic at the moment, but we'll continue developing it in upcoming releases.
Weather radar (aka WSR) used to monitor weather ahead of the aircraft (clouds and precipitation) is an integral part of a professional flight simulator enabling pilots to train strategic and tactical planning of a safe flight trajectory. Now it is available out-of-the-box implemented as a MeteoRadar component, a part of the IG Aviation add-on included in SIM SDK edition. As with any other tool, adequate skills of the crew are required in order to use it efficiently: accurately tune this system and interpret the weather radar display correctly. All key parameters of the radar are available for adjustment including display range (to monitor both the short-distance and long-distance weather), gain (for weather severity assessment), as well as tilt angles, FOV, and others. The radar works with 3D volumetric clouds generated by UNIGINE's advanced Clouds System ensuring consistency of radar readouts with the view from the aircraft cabin. Adding a radar for your aircrafts now is just a matter of a couple of clicks.
GPU Particles (Experimental)
We have added GPU particles to the IG Application Template as an experimental option for rendering rain and snow providing more realistic precipitation density and higher performance. There might be some unresolved issues as the system is not well-polished yet, but you can already test new particles, feel the difference, and share your feedback so we can push them to production phase in the upcoming releases.
To check out new GPU particles select precipitation types 3 and 4 declared in the ig_config.xml file (precipitation_type).
Improved CIGI Symbols Support
CIGI Symbols support has been extended with an ability to add user fonts via IG configuration (Text Font ID is now supported), to use text alignment, Left-to-Right and Top-to-Bottom orientation. Font size is now set in terms of the vertical units defined by the symbol surface's 2D coordinate system. The "Hidden" control state is now taken into account. All these improvements enable you to create and manage a wide range of Head-Up Displays (HUD) you need.
Other IG Improvements
Demos and Samples
New API Samples
A pack of new samples has been added to the C++ Samples suite including the following:
- Basics samples showcasing typical use cases.
- Curve Animation. All objects in this sample are animated using Curve2D: moving platforms, rotating coins, etc.
- Node Spawner Grid. A simple node spawner creating nodes and placing them across a grid.
- Node Spawner Timer. A simple node spawner creating nodes at a set spawn frequency.
- Physical Movement. A simple logic moving an object using either force or impulse via physical methods.
- Trajectory Movement. Three types of movement along a predefined path: linear interpolation, spline interpolation, path from a file. The sample contains the PathTrajectorySaver component that illustrates how to create your own path file, which is opened via the WorldTransformPath node.
- Transform Movement. Using different methods to perform the same actions — movement forward and backward and turning to the right and to the left.
- Trigger. Three types of triggers: Intersection Trigger, Math Trigger, and World Trigger.
- Trigger Buttons. Various types of interactable buttons and levers.
- Tracked Vehicle samples.
- Non-Physical Tracks. Imitation of the vehicle tracks using elements without physical bodies and shapes assigned. It illustrates how non-physical tracks interact with various obstacles.
- Physical Tracks. Imitation of the vehicle tracks using elements with physical bodies, shapes, and hinge joints assigned. It illustrates how physical tracks behave on interacting with various obstacles and when rotating depending on the vehicle speed.
- Input samples. C++ version of basic Input samples from the C# Component Samples suite.
- Physical Buoyancy. A new sample in the Water Global sample set implementing water buoyancy for physical bodies to make them float in Global Water.
We have also added the following new Import API samples:
- DirectMemoryImport (samples/Api/Import/DirectMemoryImport) - demonstration of the process of importing files directly to memory without saving files to the disk.
- ImportPlugin (samples/Api/Import/ImportPlugin) - creation of a user plugin implementing import functionality for a custom user file format.
Photon Engine Integration (Network)
Photon is a popular networking engine and multiplayer platform that can handle all requests on their own servers. You can concentrate on implementing your application (gameplay) logic and features in your UNIGINE project, leaving the networking part to Photon, and create a sophisticated multiplayer networking solution. We have added a small sample demonstrating how to integrate the Photon engine into your UNIGINE project.
Actually the Photon Integration sample showcases integration of two Photon products:
- Photon Realtime - arranges interaction of multiple players via network. It can be used for creation of multiplayer shooters, racing games, and other real-time applications.
- Photon Chat - allows users to exchange written messages both publicly and privately.
The sample includes:
- Simplified authorization window. The example only requires you to enter the user nickname, though the window can be used as a basis for a more elaborate authorization window with a password and other credentials.
- Lobby window to create rooms or join created rooms for the multiplayer interaction.
- World containing objects that can be manipulated via network (primitive multiplayer game) and a chat window to exchange messages.
Please take into account that you would need a separate account and a license from the Photon.
Added a new tutorial series on Georeferenced Terrain Generation Using Sandworm:
Added a set of new ultrashort HowTo quick tip videos in English, Chinese, and Russian:
Featured User Content
Featuring a channel of a Canadian enthusiast - @LazyUnigineDude, with a growing number of great and useful videos on various aspects of using UNIGINE: "This channel is created to show the potential of UNIGINE Engine and how to use it. Free tutorials and small tips and tricks to help you make better projects..."(c).
Other Documentation Changes
- Updated the article on Asynchronous Data Streaming and related articles.
- Updated the Cleaner Tool article.
- Updated the article on Brush-Based Placement of Meshes.
- Added a new article on SVN Plugin.
- Added new articles on Particles Spacer and Particles Deflector.
- Added more descriptions to Material Graph Nodes Reference.
- Added examples of code for the following API classes (Xml, Json, WorldTrigger, File, WindowManager EngineWindow, Displays, UserInterface, Widget, WidgetDragArea, WidgetWindow)
- Fixed a number of issues in the docs based on your feedback.
- The complete list of API changes is available in the API Migration Guide.
- The complete list of Console command changes is available in the Console Migration Guide.
- The complete list of instructions on upgrading your content to UNIGINE 2.17 is available in the Content Migration Guide.
Thank you for reading, and don't miss the updates as we keep working to make UNIGINE even greater!
- Your UNIGINE Team