Projections with AppProjection Plugin
AppProjection allows you to create multi-projector setups. Edge blending, non-linear image mapping and color correction for each projection are supported. Therefore, AppProjection can project images onto large curved screen displays covering 360 degrees, if necessary. Moreover, each projection can be fully customized to use required view frustums.
- engine.projection functions
To launch the application and render projections:
- Specify an engine plugin library (lib/AppProjection_*) together with the rest of required start-up arguments (such as rendering API, window size, etc.). For example:
You can use 32-bit, 64-bit, debug or release versions of the library. (The engine automatically loads the appropriate version of the library depending on the specified main application.)
bin\main_x86d.exe -extern_plugin AppProjection
- To change the number of displays in a row, specify -width CLI option. For example:
By default, up to 8 projections are supported to be output from one rendering node.
bin\main_x86d.exe -extern_plugin AppProjection -width 2
Setting Up Projections
To set up projections, open the system menu by pressing Esc, go to Plugins tab and click Projection button.
The Projection Configurator window will open. Here, it is possible to:
- Rotate and flip projections
- Control warping for each projection
- Set up edge blending and masks for each projection
- Correct color intensity for each projection
For the last three options, you should first choose a Projection to be adjusted at the top-right corner.
The Warp tab allows you to set up geometry correction for your projections. Areas where geometry correction is required include:
- Advanced off-axis correction where projector placement is awkward and needs an advanced mapping over the keystone function in a projector
- Non-planar screens such a curved screens and hemispherical domes
- Projecting one image from one projector onto more than one surface
- Unusual projection applications onto custom designed screens
The following options are available:
The Color tab allows you to correct color intensity, as well as to adjust color balance for the selected projection.
|Scale||Per-channel color multiplier. It allows to control the intensity of:
Scale for the red channel = 2
|Bias||allows you to adjust the color balance per channel (as well as for all channels at once):
Bias for the red channel = -0.1
Edge Blenging and Masking
The Blend & Mask tab allows you to configure blending along the edges and according to masks, you can also use masks to cut out certain areas for the selected projection.
|Mask||This group allows you to set up masks to be used for blending regions or to cut out certain areas (e.g. top and bottom areas for a curved screen projection).
The list of masks for the current projection is displayed on the left. You can add new masks and remove existing ones using the corresponding buttons.
Visual editor enables you to create and modify masks.
As you select a mask in the list, its parameters are displayed on the panel next to it:
|Border||Controls soft edge blending for each side of the projection (left, right, top or bottom one). Set a non-zero Power value to start setting it up.
Multiple Projections' Viewing Settings
If more than two projections are created with AppProjection, the following viewing settings can be tweaked in the System menu -> Plugins.
|FOV||The field of view for all projections. (Camera tab -> Field of view option is not applicable in this case).
Fov = 60
Fov = 80
|Angle||Allows to adjust the viewing angle between projections. That is, when surfaces to project the images onto are turned at some angle to each other, this angle can be entered as Angle value and the projection will be automatically recalculated to show the right image.
For example, if two surfaces are turned to each other at 40 degrees:
Angle = 40 degrees
|Bezel X||Compensates for horizontal bezel of monitors. Positive values decrease the viewport space; negative ones increase it (for overlapping).|
Saving and Loading Presets
After projection configuration is set up, it can be saved to an preset file (*.proj) to be loaded at any time (e.g. to set up another projection):
- Save button to save a preset file
- Load button to load a preset file
AppProjection can be customized to support custom viewing frustums (symmetric or asymmetric ones) for each projection.
AppProjection has one primary viewport, while all others are rendered as auxiliary ones. By default, the primary display is the Unigine engine viewport used for one-monitor configuration. It uses matrices of the Player used by the engine to view the scene. Other displays are arbitrary cameras with any perspective and facing whatever direction needed. Each display has its own model-view and projection matrices. Both the primary projection and auxiliary ones can be enabled or disabled, if necessary.
- The primary viewport can be set to any projection (for supported configurations it is already set).
- Each viewport has its own model-view and projection matrices.
- By default, only a primary one has a graphical user interface (render system GUI, editor widgets, wireframe, or the profiler). However, separate GUIs can be drawn on all projections.
- All viewports have their own viewport and reflection mask to selectively render nodes and reflections from them.
For default configurations, the primary viewport is set to the following projection:
- For 2 projections, the 1st viewport.
- For 3 projections, the 2nd viewport.
- For 4 projections, the 2nd viewport.
- For 5 projections, the 3rd viewport.
How to Customize Projections
Rendering of AppProjection viewports is controlled by wall.h script (found in <UnigineSDK>/data/core/scripts/system/ folder). There are two possible setups depending on how the primary projection is rendered. It can be drawn by:
- The default engine renderer (the same as when a usual one-monitor application is rendered).
- The AppProjection renderer itself (which is safer if you are going to use asymmetric frustum for the center projection and modify its model-view matrix).
The following example demonstrates how to tweak cameras configuration and choose the renderer for the main projection.
1. Using default engine renderer
The first variant is to render the main (primary) projection by the default engine renderer.
- In case the created configuration is not already supported, set the primary projection via engine.projection.setPrimary():
// Set the first projection as a primary one engine.projection.setPrimary(0,1);
- Enable all non-primary projections via engine.projection.setEnabled(). The main one should be left disabled, as it is drawn by the default engine renderer.
// Enable the 2nd projection in a row // The second argument of the function sets 'enabled' flag engine.projection.setEnabled(1,1);
- Set projection and model-view matrices for an auxiliary projection via engine.projection.setProjection() and engine.projection.setModelview().
// Settings for the 2nd projection engine.projection.setProjection(1,projection_1); engine.projection.setModelview(1,modelview_1);
2. Using AppProjection renderer
Another variant is to render the main projection by the AppProjection renderer. This variant can be used, for example, if you want to set up symmetric frustums for all projections.
- Set the projection to be used as a primary one and enable its rendering by AppProjection.
// Set the first projection as a primary one // The second argument of the function sets 'enabled' flag engine.projection.setPrimary(0,1);
- Disable rendering into the default Unigine viewport via engine.render.setEnabled():
- Enable all AppProjection projections including the primary one. As a result, all viewports will be rendered by AppProjection renderer itself:
// Enable all projections engine.projection.setEnabled(0,1); engine.projection.setEnabled(1,1);
- Set model-view and projection matrices for all projections.
// Settings for the 1st projection engine.projection.setProjection(0,projection_0); engine.projection.setModelview(0,modelview_0); // Settings for the 2nd projection engine.projection.setProjection(1,projection_1); engine.projection.setModelview(1,modelview_1);