PresenZ in Unity

Did you wish for interactivity in PresenZ? Add real-time on top of the PresenZ pre-renders to build your own interface, have networked multiple-users inside PresenZ or gamify your volumetric renders? The PresenZ in Unity plugin allows you to do exactly that.

It is a PresenZ Viewer inside Unity, controlled by the Unity scripts, allowing you to mix the PresenZ pre-renders with Unity real-time graphics in any way you want and to trigger the PresenZ content from your own game logic.

Unity Version & Prerequisites

PresenZ in Unity is confirmed to work in Unity 2021.3 LTS. While not explicitely supported, it may also work with newer and older releases.

The plugin is intended for 64-bit Windows projects using Direct3D 11 with the URP render pipeline and the XR plugin system. If you wish to use the plugin in another configuration please contact us.

PresenZ in Unity requires the latest Microsoft Visual C++ Redistributable for Visual Studio to be installed. It can be downloaded from the Microsoft Support website. This requirement carries over to any projects built with the PresenZ in Unity plugin, so it is recommended to include the MSVC++ Redistributable in your project’s installation process.

The examples make use of Unity’s new input manager and XR plugin system, install the ‘Input Manager’ and ‘XR Plugin Management’ packages from the package manager before importing the PresenZ plugin.

Project Setup

New Project Template

  • Use the ‘3D (URP)’ template for a new project. The current version of the PresenZ plugin only supports the URP pipeline.New Project Template

Project Settings - Player

  • Other Settings - Color Space: This must be set to ‘Linear’ in order for PresenZ to display colors correctly.

  • Other Settings - Auto Graphics API for Windows: PresenZ requires the use of the Direct3D11 graphics API, which is what Unity should pick by default if this option is left enabled. To be 100% certain the right graphics API is used you can manually select Direct3D11 in the list that appears when the ‘Auto Graphics API for Windows’ option is disabled.

Project Settings - Graphics

  • Scriptable Render Pipeline Settings: When viewing the PresenZ examples set this to ‘MyURPAsset’ (import the PresenZ plugin first).

Project Settings - Quality

  • Rendering - Render Pipeline Asset: When viewing the PresenZ examples set this to ‘MyURPAsset’ (import the PresenZ plugin first). This must be set for every quality level.

Build Settings - At this time, PresenZ works only on the ‘Windows’ platform in the ‘PC, Mac and Linux Standalone’ category. - Architecture: This must be set to ‘x86_64’.

Camera

  • Projection - Clipping Planes - Near: When setting up the camera for VR the near clipping plane should be set to 0.1 or even lower as the user may bring their eyes arbitrarily close to objects in the scene.

  • Projection - Clipping Planes - Far: It is recommended to set the far clipping plane to at least 1100 to ensure all parts of a PresenZ image are visible. If necessary it may be possible on interior scenes to use a lower value.

  • Rendering - Anti-aliasing: PresenZ content is rendered under the assumption that FXAA will be applied to the final image. It is strongly recommended to have some form of post-process AA enabled, even on top of MSAA.

  • Attach a ‘Presenz Camera Link’ component to the camera to enable PresenZ rendering.

Universal Render Pipeline Asset - Quality - Anti Aliasing (MSAA): It is recommended to set this to ‘2x’ or higher.

Universal Renderer Data

  • Renderer Features: Add a ‘Presenz Renderer Feature’ to this list.

PresenZ Scripts

A short overview of the Unity scripts used to control PresenZ is given below. More detailed information can be found throughout the scripts themselves in the form of XML documentation comments. Scripts in the ‘Util’ category combine the base scripts to cover specific usage scenarios and may serve as a jumping-off point to implement custom use cases.

PresenZ.cs

Classes that wrap around the functions provided by the plugin DLL. They may be used directly or through the Unity components described below. The static class ‘PZ’ provides access to version information, plugin status and other utility functions.

PresenzRendererFeature.cs

This script is responsible for performing the rendering of PresenZ content and managing the GPU buffers required for this. Consequently this script requires a lot of video memory (>1 GB using default settings) should be used only once.

  • Render pass event opaque: Where to insert the render pass to render opaque PresenZ content. This should generally not be moved from the default (‘After Rendering Opaques’) and must always be earlier than the transparent pass.

  • Render pass event transparent: Where to insert the render pass to render transparent PresenZ content. Usually this should be ‘Before Rendering Transparents’, but depending on your scene ‘After Rendering Transparents’ may give better results. The transparent PresenZ pass must always occur after the opaque pass.

  • Max Pixels: The maximum amount of pixels in a render target the renderer can expect to encounter. Set to ‘0’ to use the default value of 32 MPixel. Try raising this value if no content shows up when using a high resolution HMD or a high multisampling value. This value slightly impacts the video memory required by this script.

  • Max Particles: The maximum amount of particles in a PresenZ image the renderer can expect to encounter. Set to ‘0’ to use the default value of 25 million particles. The default value has been chosen conservatively, and it may be beneficial to lower this to a more appropriate value once the set of PresenZ images that will be used in the scene is known. This value heavily impacts the video memory required by this script.

PresenzImageLoader.cs

This script loads a PresenZ image and places it into video memory. The video memory required is proportional to the size of the image that is loaded. The image will be placed in the world at the location of the object this script is attached to.

Call the ‘LoadImage’, ‘LoadImageAsync’ and ‘Unload’ functions from another script to manage the loaded image. The ‘Load’ function may briefly stall the application, it is recommended to fade the screen to black when calling this function in the middle of a VR experience. The ‘LoadImageAsync’ function will not stall the application, but may not provide a PresenZ image for a few frames instead.

Using multiple PresenzImageLoaders and another script to dynamically switch the ‘Frame Source’ property of a PresenzCameraLink to the closest loader allows you to seamlessly stitch multiple PresenZ images together (shown in ‘MultiExample’).

  • Asynchronous Loading Limits → Decode Memory: The amount of extra system memory to allocate for decoding, in KB. Because this memory is shared between loaders more or less memory may be actually allocated, up to the highest value given to any loader in the scene. Set to ‘0’ to use the default value of 256 MB.

  • Asynchronous Loading Limits → Upload Per Frame: The amount of data to transfer to the video card per frame, in KB. Only one loader will be actively transferring data during a frame. Set to ‘0’ to use the default value of 16 MB.

PresenzMovieLoader.cs

This script loads PresenZ movies and manages all memory for them. Unlike the image loader it uses a fixed amount of video memory, roughly 2.5 GB using default settings. The amount of system memory is about the same amount plus any movie frames that are preloaded when opening a movie (either specified by the movie itself or all frames if requested by the ‘LoadMovie’ function).

Movie loading is always an asynchronous operation.

Scenes where multiple PresenZ images are stitched together are handled by the PresenzMovieLoader itself and do not require multiple loaders.

For smooth movie playback the ‘Tick’ function should be called every frame, and the ‘GetEvent’ function multiple times per frame until it returns ‘False’.

  • Max PRZ Size MB: The size of the largest movie frame the loader can expect to encounter, in MB. Set to ‘0’ to use the default value of 128 MB.

  • Max Particles: The maximum amount of particles in a movie frame the loader can expect to encounter. Set to ‘0’ to use the default value of 25 million particles.

Util/PresenzDoubleImageLoader.cs

The PresenzDoubleImageLoader component uses two PresenzImageLoader components to perform double-buffered loading of PresenZ images for a seamless transition between two images, at the cost of requiring more memory.

Use the ‘LoadImage’ function to load a new PresenZ image, which will replace the previous image as soon as it is ready.

Util/PresenzMultiZovLoader.cs

The PresenzMultiZovLoader component uses the classes from PresenZ.cs directly to manage image loading in large multi-image scenes. For the best user experience, disable the ‘Crop To ZOV’ option on the PresenzRenderer component.

Use the ‘AddZOV’ function to describe the layout of PresenZ images in your scene. The loader will show the image nearest to the viewer and keep several more on standby. ‘SysMemGB’ and ‘VideoMemGB’ give an estimation of how much system and video memory the component is currently using, in GB.

  • Viewer Position: Location of the viewer, used to decide which image to show and which images to load into memory. Normally this will be the location of the active camera.

  • GPU Images: The maximum amount of PresenZ images to hold in video memory.

  • CPU Images: The maximum amount of PresenZ images to hold in system memory.

  • Position Margin → GPU Margin: To avoid excessive loading to and unloading from video memory near transition points, an image must be at least this distance closer to the viewer to evict another image from video memory.

  • Position Margin → CPU Margin: Analog to GPU Margin, for system memory.

  • Asynchronous Loading Limits → Decode Memory: Same as for PresenzImageLoader.

  • Asynchronous Loading Limits → Upload Per Frame: Same as for PresenzImageLoader.

License & Watermark

All files in this package are covered by the End User License Agreement (EULA), unless noted otherwise below. Using these files means you agree to all terms and conditions described in the EULA. If you do not or can not agree to the terms and conditions in the EULA, do not use any of the files to which the EULA applies. The EULA can be found in ‘EULA.txt’.

The Unity assets in this package are provided to you under the CC-BY 4.0 license. The term ‘Unity assets’ is understood to mean the following files contained within ‘PresenZ.unitypackage’:

  • C# scripts (file extension ‘.cs’)

  • Unity scenes (file extension ‘.unity’)

  • Unity materials (file extension ‘.mat’)

  • Unity shaders (file exntension ‘.shader’)

  • Unity Post process profiles (file extension ‘.asset’)

The CC-BY 4.0 license can be found in ‘CC-BY 4.0.txt’ and at the Creative Commons website. If you are seeing the watermark on on your PresenZ images (blue lines moving through the scene) and wish to remove it you must obtain a license file. Contact Parallaxter for more information (note that a PresenZ in Unity license file is different from the generic PresenZ player license available on the website).

To remove the watermark the license file (file extension ‘.lic’) must be placed in the same directory as the executable that is using it. While working on the project this will be the Unity editor which is located at <Unity Installation Dir>/<Unity Version>/Editor. For a released project it will be the project executable which is placed directly in the build directory.

Example Scenes

MovieExample

A comprehensive example that shows how to use the PresenzMovieLoader, how to handle the events generated during movie playback, and how to set up post processing for PresenZ.

This example also shows how to use a second camera to mask out parts of the image that should not be visble when outside of the zone of view.

Click the buttons or touch them with your motion controller to control the player. Use WASDQE to move around. The demonstration movie will automatically pause during playback to show how to handle a movie-triggered pause event. When this happens simply activate the play button to continue.

The movie example requires extra PresenZ images that can be downloaded from our website. Download the ‘Animation Demo’ from the ‘Demo Content’ category and place the ‘movie’ folder inside ‘Assets/StreamingAssets/PresenzImages’ in your Unity project.

SingleExample

This scene demonstrates a basic PresenZ setup with a single PresenzImageLoader. A fade to black has been added to hide the image transitions. Press spacebar to advance to the next image and use the arrow keys and the mouse buttons to move around.

DoubleExample

The same scene as SingleExample, but instead of a single PresenzImageLoader a PresenzDoubleImageLoader is used. There is no fade to black because the application does not hang while loading the new image. On a fast drive the loading delay can be short enough that the user may not even notice it.

MultiExample

The MultiExample scene demonstrates how to stitch multiple PresenZ images together to achieve a much larger Zone-of-View. The scene also shows how to get the size of the ZOV of a PresenZ image before it is loaded. Use the arrow keys and the mouse buttons to move around.

On a small enough scene like this example it is possible to load all images when launching the scene, however for a larger scene it is recommended to use PresenzMultiZovLoader.

F.A.Q.

Where can I get more PresenZ images?

PresenZ images are created with the PresenZ Authoring Tools, which can be downloaded from our website. On the website you will also find a demo pack containing more images.

Can I use PresenZ without a virtual reality headset?

Yes, PresenZ works just as well on a standard display as it does in a virtual reality headset. This makes it easy to design and test your project in the standard Unity Editor interface.

What are these blue lines in the PresenZ image?

This is the watermark. For more information, read License & Watermark.

Why are the colors too dark?

The Unity color space must be set to ‘Linear’ in order for PresenZ to display colors correctly. You can change this in Project Settings → Player → Other Settings.

Why does nothing show up in VR?

PresenZ needs to keep some information about every pixel on the screen. By default the plugin allocates 12 MPixel worth of buffer space for this, but with a high-resolution VR headset or a high multisampling count this can be exceeded.

This limit can be raised manually by changing a property on the PresenzRenderer component in your scene (Memory Limits → Max Pixels). If this does not help, please don’t hesitate to contact support.

Why are there pinprick holes in the image?

PresenZ content is rendered under the assumption that FXAA will be applied to the final image. Without this post-processing effect some pinprick holes may appear in the image. PresenZ images created with older versions of the PresenZ Authoring tools are more susceptible to this, so the issue may be more apparent in some of the demo images available from our website than in a newly created PresenZ image.

An easy way to add FXAA to your project is to install the official Unity post-processing package (via Window → Package Manager) and then add a post-processing layer to the camera object.

If adding FXAA to your project is not an option, an alternative solution is to make sure that the PresenZ image is shown on a dark background.

My question is not on this list.

You can ask us directly, we’ll be glad to help!