Development log: October 19, 2012

Real-time Global Illumination with Spherical Harmonics

Global Illumination

A new, real-time global illumination based on precomputed spherical harmonics allows to render high-detail diffuse lighting with interreflections and angle-dependent specular highlights. It is fully interactive: soft environment light illuminates both static geometry in the scene and dynamic objects moving around it.

Global Illumination via spherical harmonics

The stunning lightmap-like quality is achieved by using automatically generated LightProbs. With such precomputed lighting approach, you can have full control over general GI settings (via Render -> Parameters -> Global parameters) or fine-tune GI component intensity for each separate location.

Global illumination is available across all APIs and is well scalable performance-wise. Simply generate a necessary number of LightProbs using Tools -> Illumination and specify render_light_prob 1 console command.

As you can see, GI makes a huge difference: it brings a truly photorealistic visual quality to a scene. New samples with sun and local lights can be found under demos/gi/ directory.

Without Global Illumination

With Global Illumination

Render

  • New mesh_wire_base material can be used to create thin objects like wires, ropes, nets, etc. Since a rendered line doesn't get smaller than a pixel wide, it always looks continuous when viewed from a distance.
  • Huge speed-up for skinned meshes with a lot of disabled strafes. Now it is possible to create characters with a large number of equipment combinations without compromising performance.
  • Added video_renderable console command that enables hardware anti-aliasing for:
    • GUI widgets
    • Flash movie clips
    • iOS mobile devices
    To activate this mode of AA, use the following console commands: video_multisample 4 && video_renderable 1 && render_skip_post_materials 1 && video_restart"
  • Procedural textures for custom post-process materials can now be of various formats: RGBA8, R16F, RG16F, RGBA16F, R32F, RG32F, RGBA32F. You can easily choose the required data precision for simulation.
  • It is possible to render custom procedural post-process materials assigned to mesh surfaces via engine.render.renderProcedurals() function. (Post-process materials assigned as Render or Post viewport materials are rendered automatically.)
  • Fixed a crash when an application window is resized to zero height and width.
  • More verbose render_manager_list console command. Now it prints detailed information on textures used in the currently loaded world (information on texture format and used compression, if any, as well as texture dimensions and a file size).
  • Added video_fullscreen 2 mode to render an application window without decorations.
  • TTF fonts are now handled correctly despite of any font atlas texture issues.
  • Fixed a bug with incorrect LightProb lighting calculation.
  • On Mac OS X shadows from all types of light sources are correctly rendered.
  • Fixed a pixel-size contour artifact for surfaces with parallax mapped material assigned (for example, on decals).
  • Fixed a small bug with incorrect DXT1 color and DXT5 alpha compression/decompression.
  • Added full support for ETC2 texture compression (with T, H and planar compression modes supported out of the box). The compression quality of ETC2 algorithm is better than DXT, ATC or PVR ones.
  • Fixed an aspect ratio bug for horizontal and vertical split stereo modes.
  • Added an interlaced lines stereo rendering mode (with custom view frustums support). It is enabled via the following start-up option: main_x* -extern_define STEREO_INTERLACED. Stereo parameters can be tweaked in the main menu -> Stereo tab. In scripts, you can use STEREO_INTERLACED define to wrap mode-related code. (To customize a shader for a specific monitor, you may need to swap color_0 (left eye image) and color_1 (right one) variables in a fragment shader.)

Interlaced stereo is used with interlaced monitors and polarized glasses.

Interlaced stereo mode

And here is new mesh_wire_base material for thin lines and wires.

mesh_wire_base material

Nodes

  • Added WorldExpression::setPostUpdate() function. It indicates that WorldExpression is updated after all other nodes. For example, this flag is useful to draw nodes strictly in front of the camera (since this way WorldExpression always receives the updated Player's transformations). Check new samples/worlds/expression_04 sample.
  • Fixed a bug on incorrect cloning of NavigationMesh. Now NodeReference with NavigationMesh can be safely loaded.
  • Added add/removeExcludeNavigation() and add/removeExcludeObstacle() functions into PathRoute class, not to take the specified navigation areas and obstacles into account when finding a path.
  • NodeDummy is smart enough to calculate its bounding box (that is comprised of all its children BBs) each call.
  • Per-node properties are now stored in the node file.

Objects

  • Added a coarse mask texture for ObjectTerrain. This option allows to boost terrain rendering performance by using only 3 coarse textures: a diffuse texture, a normal map and a mask. With a coarse mask only, up to four detail materials are supported for the whole terrain. (You can additionally assign a per-surface mask to use another set of detail materials in a given location.)
  • Added Cast shadow option for terrain surfaces. It enables shadows from all light sources on selected surfaces.
  • Fixed a float precision issue when a terrain object is saved/loaded (this bug sometimes caused cracks between surfaces).
  • Added Route type for particles. Route particles can be used to create tracks from moving objects (for example, foam after a ship). They are similar to the previous implementation of Flat particles.

Dynamic Meshes

  • Improved internal render buffers usage for ObjectMeshDynamic. You can set dynamic flag in the constructor if a mesh is going to be changed every frame. Now you can even create a particle system based on it, and it will still be very fast.
  • In addition to triangles, ObjectMeshDynanic can now be used to render lines and points. The rendering mode is specified on the per-surface level via setSurfaceMode(). Check it with new samples/objects/dynamic_03 and dynamic_04 samples.
  • Added ObjectMeshDynamic::addLineStrip() method to create a sequence of connected line segments.
  • Per-surface collisions with ObjectMeshDynamic are now always correctly calculated (be careful, since they are expensive). There is no collision detection for point and line modes.
  • ObjectMeshDynamic methods getSurfaceBegin() and getSurfaceEnd() now return an index number of the element (a triangle, point or line) instead of a triangle number.
  • Added samples/shaders/particles_00 example based on ObjectMeshDynanic. There, particles are created using ObjectMeshDynanic points and are converted into polygons using a geometry shader at a very high speed.
  • Added samples/shaders/particles_01 for extremely efficient GPU particle simulation.

More than 65500 of animated particles simulated on GPU using dynamic meshes:

GPU particle simulation

UnigineScript

  • Now call() can be used for calling virtual user class functions.
  • A call stack size is increased to 1024 calls. Assertions on stack overflow are added.
  • Added set_extern() function to inherit a custom user class from an arbitrary C++ base class.
  • Fixed a bug when accessing private variables from derived classes.
  • All queued console commands can be executed immediately via new engine.console.flush() function. Be careful, since forced execution of some console commands (world_load, world_quit or state_restore that reload a currently executed script) can lead to a crash.
  • A function that sets GUI callbacks can now be safely called from a different Unigine script (for example, a system script function called from a world script).
  • engine.filesystem.loadPackage()/removePackage() can be used to load/unload UNG and ZIP archives on demand. These archives can be located outside data directory if an absolute path is specified.
  • Fixed a bug with mouse cursor flickering in MOUSE_SOFT mode: a system script doesn't handle the mouse when the editor is loaded.
  • A node state can now be safely saved/restored via save/restoreNode() in run-time using the same object instance identifier for the restored node.
  • Script exceptions are now properly handled on Android and PlayStation3.

High-Level Systems

  • Added tracks to control materials and properties for each node instance in Tracker (node -> object -> material/property).
  • If complex track tracks with a huge number of parameters inside are used, they can be optimized by setting Discrete mode. With this mode enabled, a track is applied to a scene only if its parameters change (that is, calculations are performed only in case track-controlled parameters need to be reset). A Continuous mode is the same default mode as was used by the engine before.
  • Syncker server can now be run on Mac OS X machines.

C++ API

  • Added support of point and line per-surface rendering modes into Unigine::ObjectMeshDynamic class.
  • When initializing the engine instance, application path and home path can be specified. application path specifies a directory where all engine resources are stored, while home path is added to project path (home/project) to store rewritable cache files, log and configuration files.
  • Fixed a bug with incorrect display of UTF-8 encoded window titles under Linux.

C++ plugins

  • EyeFinity plugin is renamed into AppSurround. Now it can render Unigine application across three monitors both on AMD and NVIDIA graphics cards.
  • Interface plugin windows, when their location is restored on application start-up, always appear within available screen space.
  • Interface windows can now have correct UTF-8 encoded titles under Linux.
  • Fixed a hang-up of Interface windows when they are closed via a system button on a titlebar.
  • Interface plugin no longer causes a crash when a null rendering API (not to render the application, for example, for servers) is set.
  • FileServer prints "Socket is closed" when the connection to a client is lost.
  • Main menu settings of AppWall and stereo plugins (such as Separation, Angle, etc.) are now saved into the configuration file to be automatically used on the next engine start-ip.
  • Source files of all App* plugins were moved into source/plugins/App directory.
  • Now the full source code of App3DVision and App3DSurround stereo plugins is available in source SDK, since NVIDIA granted public access to 3DVision-specific NVApi functions.

Mobile Platforms

  • Added full support for iPhone 5.
  • Added support for the retina resolution for iPad 3.
  • It is possible to get a native screen resolution of an iOS device (for example, for device type identification) via engine.tablet.getWidth() and engine.tablet.getHeight(). These functions take an aspect ratio into account to return correct screen dimensions.
  • Java functions on Android can be called directly from Unigine script via engine.tablet.call("com/unigine/crypt/class_name","function_name") (where com.unigine.crypt is a package that contains a class class_name with a method function_name). No arguments can be passed for a called Java function and it should not return any value.
  • And vice versa, functions a from a system script can be safely called from Java via runFunction("system_script_func").
  • Home path on iOS devices is now set correctly by default. Resources and cache are now saved into it without any problems.
  • Fixed a bug with an upside-down screen orientation on the first run of the application on iOS devices.
  • A Simple water shader for mobile devices does not take into the account water node orientation when rendering waves.
  • Fixed precision problems for a water object on iOS devices when it is far from the origin of coordinates.
  • An external screen for iOS devices can be enabled by setting EXTERNAL_SCREEN define in GLESAppTablet.mm.
  • New Xcode with iOS 6.0 SDK is now required to create iOS builds.

Flash

  • Added full support of custom ActionScript classes (class inheritance is also supported). With this option it is easy to create a custom set of Flash widgets for your projects. Check this feature on samples/widgets/flash_06 sample.
  • Great performance speed-up of the ActionScript virtual machine. A value of the variable is now accessed at run-time extremely fast.
  • Big amount of data can now be passed from ActionScript side to UnigineScript as Array. setArray(), getArray() and isArray() functions are now available for WidgetFlash. Check it on samples/widgets/flash_05 sample.
  • Frame rate of Flash movies is automatically decreased if FPS of the scene is lower than it.
  • gotoFrame() function correctly stops a movie clip in all cases.
  • WidgetFlash can now load fonts without predefined glyphs.
  • Fixed a bug with incorrect wrapping of scaled text.
  • Fixed a bug with incorrect atlas texture wrapping.
  • Added support for getDepth() and swapDepths() methods of MovieClip to manage movie clip depths. Check it on samples/widgets/flash_03 sample.
  • Added support for Number object and its methods valueOf() and toString() (both implementations, with and without arguments).
  • Strings are now automatically converted into String objects, numbers into Number ones.
  • No more memory leaking issues on shutdown, the engine deletes all allocated resources.

A custom set of reusable buttons can be created with ActionScript classes support.

Custom Flash buttons

GUI

  • Fixed a bug when WidgetSprite is loaded from UI file (Z-axis offset was incorrectly added to the widget).
  • Fixed a fast navigation option (via Tab/Shift+Tab) between the fields for WidgetEditLine in external interfaces.

ResourceEditor

Collada import is improved with the following features:

  • Speed-up of DAE files loading.
  • Normals are now automatically calculated for imported models, if necessary.
  • Skinned models are converted into static geometry with the correct pose transformation.

And there is more to come: Collada plugin will soon support import of materials, node hierarchy and animation.

Tools

  • Added multi-selection for surfaces of terrain object. Now you can easily remove or enable/disable options for all surfaces at once.
  • Added support of PlayerSpectator and PlayerActor into the editor.
  • Decals are saved as additional surfaces when a mesh they are projected onto is exported in the editor.
  • Fixed printing of invalid Validator errors when meshes are used only in ObjectMeshCluster or ObjectMeshClutter objects.
  • Textures automatically compressed by the editor are now updated when a file is modified at once, without the engine restart.
  • Editor pathfinding icons are disabled if a world is not loaded.
  • Fixed a bug with incorrect location of NodeReference editing panel after the main application window is resized.
  • Filesystem modifiers are correctly handled when using editor automatic texture compression feature.
  • ImageView console tool now shows alpha channel on the black background.

Sound

  • Added support for XAudio2 sound system. It is available both for Windows and WinRT out of the box.
  • All sound settings can be applied immediately via engine.sound.renderWorld() with force argument set to 1. A sound system has its own fixed frame rate (30 fps), while a script update rate can be much higher, which sometimes cause commands being skipped, unless a forced update is used. As another example, this function can be called to pause the sound from a system script callback when the app is minimized on Android devices.

PlayStation 3

  • Added full support for triplanar, terrain and grass materials.
  • Fixed a bug with incorrect bounding frustum culling.
  • Fixed threads hang-ups.
  • Tracker and LUT-generation tools are not available in the editor mode due to strict memory limitations.
  • System mouse option is not functional on PlayStation3.

Other

  • Engine configuration file can be saved/loaded at any time via config_save and config_load console commands.
  • Added noscreenshot argument for state_save console command that prevents the screenshot creation when a world state is saved. To use it, type in the console: state_save my_save_name noscreenshot.
  • Small memory allocations no longer cause memory corruption errors.
  • Fixed a bug with incorrect normalization of very small vectors.
  • Debug builds for WinRT are not supported due to compiler issues; only asserts and world/system/editor_analyze console commands are available for debugging.

PS: This update is surely rich on new features. So many changes in just a single month!