Everything you need to build, tune and ship Unity applications that run on a Voxel VX2 / VX2-XL volumetric display with the Voxel Unity Plugin (VxU).
Unity is a popular 3D engine for developing applications and games. The Voxel Unity Plugin (VxU) makes it possible for Unity applications to run on the Voxel VLED display, allowing you to leverage all the benefits of the Unity Engine, including the Asset Store and community support resources.
To get started developing VLED apps with Unity, you will need to download both Unity and the Voxel VLED Environment. At the time of writing, the VxU plugin only supports Windows.
We recommend using the latest 2022 Unity version with the Voxel Unity Plugin. Unity Hub makes it easy to manage your Unity installation.
Note: When developing any software with Unity, avoid changing Unity builds mid-project — switching Unity versions can cause compatibility problems and potentially break your project.
The Voxel Unity Plugin is not on the Unity Asset Store. It is an asset package contained within the Voxel VLED Environment, which is obtainable from our website (www.voxon.co).
The Voxel Unity Plugin uses a C# bridge to interact with the VLED environment (ledhost.dll or voxiebox.dll). For this interaction to work, a few files and system settings need to be in place:
C#-Bridge-Interface.dll and C#-Runtime.dll must exist in the Voxel Runtime directory (by default C:\Voxon\System\Runtime).These are set up for you when you install the Voxel VLED Environment.
Make a new Unity project in the Unity Hub, using the Built-In Render Pipeline.
Import the Voxel VxU Unity package through Assets > Import Package > Custom Package. Locate the Voxel .unitypackage file and open it.
By default, make sure all the files are ticked to be imported, and import them into your project. When you are more familiar with the plugin, you can import only the files you need.
Once the plugin has imported successfully, you will notice some new directories in your project and a Voxel menu option in the top menu bar.
Create an empty GameObject and add a VxCamera component. The VxCamera applies a global transformation matrix to map captured scene depth data in Unity to voxel coordinates within the display. With the VxCamera GameObject selected, you can view and adjust the volume parameters in the Inspector.
VXCAM_LOCK_TO_HARDWARE by default. For development it can be useful to set it to VXCAM_Cylinder so you can preview the capture area even without a VX2 connected.4,4,4.8,4,8.Make a Unity camera to act as your capture camera (GameObject > Camera, or reserve the Main Camera for this purpose). The capture camera writes scene depth and colour data to a hidden RenderTexture, which is used to rebuild the captured scene in the VLED display — so it cannot also be used for standard scene rendering. As a side effect of RenderTexture projection, the capture camera appears to behave as a light source and casts a shadow on occluded surfaces.
Set the capture camera up as follows:
| Setting | Value |
|---|---|
| Clear Flags | Solid Color |
| Background | Black |
| Projection | Orthographic (Perspective can work, but may result in a non-ideal render projection) |
| Size | Large enough that the camera bounds fully encapsulate the capture volume |
| Clipping Planes | Small enough to fully encapsulate the capture volume |
| HDR | Off |
| MSAA | Off (paired with HDR off, these settings reduce visual artifacts inside the display) |
Render_Poltex_From_Depth_Data.Any object in your scene needs to use a Voxon/VxLitShader in order to be captured by the capture camera. In this early stage of development, the VxLitShaders only support diffuse texture maps and colour tinting.
Be aware: there can be significant overhead when rendering large numbers of objects using the VxLitShader.
The VxCamera, VxLitRenderer and VxLitShader are the vital elements in the VxU render pipeline. Any object with the VxLitShader calls the VxLitRenderer to capture its depth data within the scene. The VxLitRenderer converts the captured image into a point-cloud array and calculates visual effects like depth occlusion. Lastly, the VxCamera takes the point-cloud data from the VxLitRenderer — relative to its object position, orientation and scale — and transforms it into a space relative to the VLED display device.
| 1 mm | 0.078125 Unity units |
| 1 Unity unit | 12.8 mm |
The VXProcess settings are the global settings for developing for the Voxel environment. You'll find them in the menu bar under Voxel > Process.
VXProcess.Instance.guidelines.VoxieHide and does not already have one. Not required with the VxLitRenderer pipeline.ANIMATION (a chronological series of frames) or a SINGLE_FRAME (one instance).With the capture camera, capture volume and VXProcess set up, you're ready to test.
Important: Always save your project before testing, as Unity / the VxU plugin can crash often. Always press the Esc key to exit the simulator once you have finished testing — do not press the Play triangle button in Unity to end the test, as it may crash your project. In case of Unity crashing, it is possible to recover the scene.
| 10 Unity units | 1 Voxel unit |
| VX2 diameter | 2 Voxel units = 256 mm |
| VX2-XL diameter | 4 Voxel units = 512 mm |
Because Unity runs in headless mode, the standard Unity Input System is unavailable. Voxel's input manager allows input during headless mode and supports keyboard, mouse, SpaceMouse, and up to 4 joypad inputs.
Query input for a defined key or button with the following functions (using Quit as an example string).
Keyboard inputs
Voxon.Input.GetKey("Quit"); // true as long as the key is held
Voxon.Input.GetKeyUp("Quit"); // true on the frame the key is released
Voxon.Input.GetKeyDown("Quit"); // true on the frame the key is pressed
// Alternatively, query specific keys by keycode:
Voxon.VXProcess.Runtime.GetKeyDown(VX_KEYS.KB_F1); // true if F1 is pressed
Joypad inputs
Voxon.Input.GetAxis("Horizontal"); // analogue input value from -1 to 1
Voxon.Input.GetButton("Quit"); // true as long as the button is held
Voxon.Input.GetButtonUp("Quit"); // true on the frame the button is released
Voxon.Input.GetButtonDown("Quit"); // true on the frame the button is pressed
You can change from the default XInput (joyAPIType = 1) to Direct Input (joyAPIType = 0):
VXProcess.Runtime.SetJoyAPI(int joyAPIType);
Input configurations are saved as a .json file within the project directory, and can be transferred between projects using the load button at the bottom right of the input manager panel.
For the most part, building a Unity project for the Voxel VX2 is identical to building a standard Windows build. The Voxel plugin adds the following folders and files to the build, in addition to the standard build files:
C#-bridge-interface.dll, C#-Runtime.dll, LedWin.dllVX.batVX.bat is your launch file for running the application in headless mode. While you can run the application via the .exe, this comes with significant processing overhead and shouldn't be the standard running mode.
The files in BuildDlls are direct copies of the DLLs in your Voxon\System\Runtime folder, and let you distribute specific DLL versions with your application if needed. To use them, drag them into the build directory — the Unity application will prioritise those over the DLLs installed on the user's machine.
It is strongly recommended to configure Project Settings > Player. To maximise compatibility with Voxel Lighthouse, the Product Name should not contain spaces.
A "Volume" can be considered the 3D equivalent of a 2D frame, where scene data is composited and rendered for viewing. In viewing terms, Volumes Per Second (VPS) is roughly analogous to Frames Per Second (FPS), and indicates how smooth and complete motion on the display will appear.
Each volume is made of individual slices that illuminate a single plane within the volume as the LED panel moves through it. The number of slices in a volume is directly proportional to the revolution speed of the VLED display. In most circumstances the VX2 operates at 900 rpm.
You can preview the current VPS draw rate on the secondary screen by turning on Show_Info in the VXProcess window. Bear in mind that VPS is not correlated to the Unity framerate — the display can refresh the volume at a different rate to the frames Unity calculates. VPS is heavily affected by the number of illuminated voxels in the display, in addition to the load of running the Unity application.
Tips to improve your VPS while developing:
If you are an experienced Vx app developer, you may wish to interact with the volume directly. To draw Voxel primitives — such as text and simple shapes like cubes, spheres, cones, lines and dots — from a custom C# script, inherit the IDrawable class from the Voxel namespace and add it to the VXProcess.cs internal IDrawable reference list.
The VxProcess manages a list of references to IDrawable-inherited classes. When rendering a scene, this list is iterated through and each one's Draw() function is called. All VXGameObject references are also maintained in a separate list within the VxProcess. Together these lists maintain most (in most cases, all) of the Unity GameObjects that are rendered on the Voxel display.
using Voxon;
public class YourClass : MonoBehaviour, IDrawable
{
void Start()
{
// Add this instance to the IDrawables list
VXProcess.Drawables.Add(this);
}
// Called by the VXProcess on every update
public void Draw()
{
VXProcess.Runtime.DrawBox();
VXProcess.Runtime.DrawCube();
VXProcess.Runtime.DrawLine();
VXProcess.Runtime.DrawSphere();
}
}
VXProcess.Runtime gives you access directly to the C# bridge, so you can interact with the Voxel Runtime in many ways beyond just drawing graphics. An example of drawing straight to the display can be found in the CanvasToLED pipeline.
The Voxel VLED display supports rendering a low-resolution Unity Canvas within the volume.
How it works: the Canvas object is captured by a dedicated camera and saved to a RenderTexture with the same resolution as the LED panel. The CanvasToLED component then converts the RenderTexture to a 7-colour palette, and each pixel is drawn directly onto the display at a desired angle.
CanvasCamera and the RenderTexture to RenderTexture.Note: FacingOffset is not measured in degrees or radians. Its effect depends on the current rotational speed of the VLED display and the number of image slices produced to render a volume, so user-adjusted values may need an additional modifier to deliver the same experience across different devices.
When working with a pixel-perfect canvas, ensure your graphical elements are set up for a pixel-perfect pipeline — otherwise elements rendered in the CanvasToLED pipeline may appear hazy or jagged.
An overview of how data and interactions travel from Unity to the volumetric display.
breath(), process all graphics and prepare the volumetric image while listening for system and user input. Sends the volumetric frame data to the display through its Runtime.cs class instance.IRuntimePromise. Requires C#-Runtime.dll to work.ledhost.dll or voxiebox.dll) can be accessed.Explore the VX2 and VX2-XL, try the live simulator, or talk to us about your use case.