NVIDIA 3D Vision Surround Output with App3DSurround Plugin
An App3DSurround plugin is used to render the application across 3 monitors at the maximum frame rate using NVIDIA 3D Vision technology and multiple GPUs (Multi-GPU or SLI setup). 3D Surround requires to run the application in the fullscreen mode. Windowed mode is rendered in the non-stereoscopic mode.
Launching App3DSurround
To run your application in 3D Vision Surround mode, make sure that it is supported by a graphics card. Stereoscopic 3D should be enabled on the driver lever:
- Click on the desktop with the right mouse button.
- Open NVIDIA Control panel.
- Go to Stereoscopic 3D → Set up stereoscopic 3D.
- Click Enable stereoscopic 3D settings and follow the setup wizard.
To use the plugin, specify the extern_plugin command line option and STEREO_3D_SURROUND define on the start-up:
main_x86d -extern_plugin "App3DSurround" -extern_define STEREO_3D_SURROUND
Also you can create a new project with NVIDIA 3DSurround support by checking the NVIDIA 3DSurround 3-monitor stereo 3D option in the New Project tab of the UNIGINE SDK Browser.
Customizing App3DSurround
In the 3D Vision Surround mode, Unigine allows the full control over all cameras that render the application onto three monitors. If necessary, you can create cameras with asymmetric viewing frustums and set any desired field of view for them.
To create custom cameras for 3D Vision Surround stereo mode, you can modify the data/core/scripts/system/stereo.h script. Another possible scenario is to comment stereo.h out from the system script unigine.cpp, wrap your code around with #ifdef HAS_APP_3D_SURROUND ... #endif and implement your own camera configuration in the render() function of the system script.
int render() {
#ifdef HAS_APP_3D_SURROUND
// place an implementation of a
// custom camera configuration here
// ...
#endif
return 1;
}
There are two possible setups depending on how the primary monitor is rendered. It can be drawn by:
- The default engine renderer (the same as when a usual one-window application is rendered).
- The 3D Surround renderer itself (which is safer if you are going to use asymmetric frustum for the primary monitor and modify its modelview matrix). This variant gives the full control over all three cameras used for rendering.
The following example demonstrates how to set up 3 monitors stereo configuration and choose the renderer for the primary monitor.
1. Using default engine renderer
This variant is used in stereo.h script by default. It is used when you want to control two side monitors without modifying the central camera.
- Enable rendering onto two side monitors by the 3D Surround application renderer. The central monitor is rendered by default.
// Enable the left monitor engine.surround.setEnabled(0,1); // Enable the right monitor engine.surround.setEnabled(2,1);
- Set stereo pair projection matrices for each of two side monitors, i.e. one projection matrix for the left stereo image and one for the right stereo image. For the central monitor the default engine renderer will set matrices automatically.
// Set projection matrices (a stereo pair) for the left monitor engine.surround.setLeftProjection(0,left_projection_matrices[0]); engine.surround.setRightProjection(0,left_projection_matrices[1]); // Set projection matrices (a stereo pair) for the right monitor engine.surround.setLeftProjection(2,right_projection_matrices[0]); engine.surround.setRightProjection(2,right_projection_matrices[1]);
- In the same way, set stereo pair modelview matrices for the left and right monitors. Again, for the center monitor the default engine renderer will set matrices automatically.
// Set modelview matrices (a stereo pair) for the left monitor engine.surround.setLeftModelview(0,left_modelview_matrices[0]); engine.surround.setRightModelview(0,left_modelview_matrices[1]); // Set modelview matrices (a stereo pair) for the right monitor engine.surround.setLeftModelview(2,right_modelview_matrices[0]); engine.surround.setRightModelview(2,right_modelview_matrices[1]);
- The stereo pairs for side monitors are ready. But you also need to specify what cameras will render when the application is switched from the stereo mode to the non-stereo one. It is necessary, for example, when 3D Vision Surround application is changed from the full screen mode to the windowed one that does not support stereo rendering.
For such case, you need to specify separate projection and modelview matrices for rendering cameras in mono mode:// Set projection and modelview matrices for the left monitor in mono mode engine.surround.setProjection(0,mono_left_projection_matrix); engine.surround.setModelview(0,mono_left_modelview_matrix); // Set projection and modelview matrices for the right monitor in mono mode engine.surround.setProjection(2,mono_right_projection_matrix); engine.surround.setModelview(2,mono_right_modelview_matrix);
- Set postprocess materials for all three monitors in the update() function of the unigine.cpp system script, including the central monitor, that will allow the corresponding postprocess shader to render viewports in the stereo or mono mode.
// Check if the default engine renderer is in mono or stereo mode if(engine.render.getStereo()) { // Set postprocess material for stereo rendering for the central monitor engine.render.setPostMaterials("post_stereo_separate"); } else { // Set postprocess material for mono rendering for the central monitor engine.render.setPostMaterials("post_stereo_replicate"); } // Check if 3D Surround renderer is in the mono or stereo mode if(engine.stereo.isEnabled()) { // Set postprocess material for stereo rendering for the left and right // monitors engine.surround.setMaterials(0,"post_stereo_separate"); engine.surround.setMaterials(2,"post_stereo_separate"); } else { // Set postprocess material for mono rendering for the left and right // monitors engine.surround.setMaterials(0,"post_stereo_replicate"); engine.surround.setMaterials(2,"post_stereo_replicate"); }
2. Using 3D Surround renderer
This variant allows you to configure all three monitors, including the primary (central) one. This method serves to set custom cameras with asymmetric frustums for all three monitors, including the primary one.
- Disable the default engine renderer (the same renderer as in case of a usual one-window application) via engine.render.setEnabled(). This is a necessary step if you are going to set asymmetric viewing frustum for the central camera (because modifying a modelview matrix of the default renderer directly can be unsafe).
engine.render.setEnabled(0);
- Enable rendering onto all three monitors by the 3D Surround application renderer:
// Enable the left monitor engine.surround.setEnabled(0,1); // Enable the center monitor engine.surround.setEnabled(1,1); // Enable the right monitor engine.surround.setEnabled(2,1);
- Set stereo pair projection matrices for each monitor, i.e. one projection matrix for the left stereo image and one for the right stereo image:
// Set projection matrices (a stereo pair) for each of three monitors engine.surround.setLeftProjection(monitor_number, projection_matrices[0]); engine.surround.setRightProjection(monitor_number, projection_matrices[1]);
- Set stereo pair modelview matrices for each of three monitors:
// Set modelview matrices (a stereo pair) for each of three monitors engine.surround.setLeftModelview(monitor_number, modelview_matrices[0]); engine.surround.setRightModelview(monitor_number, modelview_matrices[1]);
- The stereo pairs for all monitors are ready. But you also need to specify what cameras will render when the application is switched from the stereo mode to the non-stereo one. It is necessary, for example, when 3D Vision Surround application is changed from the full screen mode to the windowed one that does not support stereo rendering.
For such case, you need to specify separate projection and modelview matrices for rendering cameras in mono mode:// Set projection and modelview matrices for each of three monitors in mono mode engine.surround.setProjection(monitor_number, mono_projection_matrices); engine.surround.setModelview(monitor_number, mono_modelview_matrices);
- Set postprocess materials for all three monitors that will allow the corresponding postprocess shader to render viewports in the stereo or mono mode.
if(engine.stereo.isEnabled()) { // Set postprocess material for stereo rendering for each monitor engine.surround.setMaterials(monitor_number,"post_stereo_separate"); } else { // Set postprocess material for mono rendering for each monitor engine.surround.setMaterials(monitor_number,"post_stereo_replicate"); }
After setting 18 matrices for rendering cameras in stereo and mono modes and assigning corresponding postprocess materials, your application is ready for 3D Vision Surround.
In addition, you can also control what nodes and what reflections are rendered into each of three viewports by using
engine.surround.setViewportMask() and engine.surround.setReflectionMask(), respectively.