Panorama180 Render : Tips : Send panorama image to OBS Studio

Developer : ft-lab (Yutaka Yoshisaka).
03/04/2022 - 03/04/2022.

Back

Summary

Send Panorama180 Render panorama renderings to OBS Studio( https://obsproject.com/ ).
Confirmed to work with Unity 2021.2.1 + URP.
"UnityCapture"( https://github.com/schellingb/UnityCapture ) is used to work with OBS Studio.

Install

The installation includes the following

Installing OBS Studio

Install OBS Studio beforehand.
https://obsproject.com/

Installing UnityCapture

Download UnityCapture ( https://github.com/schellingb/UnityCapture).

Unzip the zip file.
As a precaution, do not delete the set of folders when unzipped, even after the UnityCapture installation process.
Double-click "UnityCapture-master/Install/Install.bat" in Explorer to run it.

This operation adds a "Unity Video Capture" device to the OBS.

Specify/prepare "Unity Video Capture" in OBS

Run OBS, press the "+" button in Sources and select "Video Capture Device".

In the "Create/Select Source" window, I changed the name to "Unity Capture Device". This name can be anything.

The Properties window will appear, select "Unity Video Device" under "Device".

Select "Custom" for "Resolution/FPS Type" and "1920x1080" for "Resolution".
The resolution at this time must be the same as the RenderTexture size output on the Unity side.
Press OK button to close.

The OBS side is now ready.
The rest will stand by.

Passing RenderTexture to OBS in Unity

Prepare the Unity Editor to pass the Panorama180 Render rendering to OBS.

Add necessary files to the project

Add the "Panorama180 Render" asset to your project.

Add "UnityCapture-master/UnityCaptureSample/Assets" from "UnityCapture" to the project. Renamed the folder "UnityCapture".

This includes the dll to access the OBS.

Add Component to Camera

Sample scene from URP are used.

Select MainCamera and add "Panorama180 Render" in the Inspector window.
You can search for the target component name by clicking the "Add Component" button at the bottom of the Inspector.


When executed in this state, Panorama180 Render's Panorama 180-3D will be displayed.
Not yet linked to OBS.

Describe Script

Script the process of rendering from the Panorama180 Render and pass the rendering to OBS as a RenderTexture.
This is based on the Panorama180 Render sample "Demo/Scripts/Runtime/Sample_Capture.cs".

[SampleCaptureToOBS.cs]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Panorama180RenderSample {
    using Panorama180Render = Panorama180Render.Panorama180Render;
    using UnityCapture = UnityCapture;

    public class SampleCaptureToOBS : MonoBehaviour {
        private Panorama180Render m_panorama180Render = null;
        private UnityCapture.Interface m_captureInterface = null;

        void Start () {
            // Get Panorama180Render component from MainCamera.
            if (Camera.main != null) {
                GameObject g = Camera.main.gameObject;
                if (g != null) {
                    m_panorama180Render = g.GetComponent();
                }
            }
            if (m_panorama180Render == null) {
                Debug.Log("The Panorama180Render component is not assigned to MainCamera.");
                return;
            }

            //------------------------------------------------.
            // Set the parameters of Panorama180 Render.
            //------------------------------------------------.
            // Set GameViewMode (Default view).
            m_panorama180Render.SetGameViewMode(Panorama180Render.GameViewMode.Default);

            // Set IPD(Interpupillary distance. unit m).
            m_panorama180Render.SetIPD(0.064f);

            // Set texture size as Cubemap (512/1024/2048/4096/8192).
            m_panorama180Render.SetRenderTextureSize(1024);

            // Post Processing On / Off.
            m_panorama180Render.SetPostProcessing(true);

            // Set Panorama180.
            m_panorama180Render.SetPanoramaMode(Panorama180Render.PanoramaMode.Panorama180);

            // Set Stereo.
            m_panorama180Render.SetEyesType(Panorama180Render.EyesType.Stereo);

            // Output resolution at Panorama180.
            m_panorama180Render.SetOutputTextureSizeType(Panorama180Render.OutputTextureSizeType._1024);

            // Begin capture.
            m_panorama180Render.BeginCapture();

            //------------------------------------------------.
            // Create UnityCapture.
            //------------------------------------------------.
            m_captureInterface = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice1);
        }

        void OnDestroy () {
            if (m_captureInterface != null) m_captureInterface.Close();
            if (m_panorama180Render != null) m_panorama180Render.EndCapture();
        }

        void Update () {
            if (m_captureInterface != null) {
                // Get RenderTexture.
                RenderTexture rt = m_panorama180Render.GetRenderTexture();

                // Resize to fit OBS texture size.
                int rWidth  = 1920;
                int rHeight = 1080;
                RenderTexture tmpRT = RenderTexture.GetTemporary(rWidth, rHeight, 0, RenderTextureFormat.ARGB32);
                Graphics.Blit(rt, tmpRT);

                // Send RenderTexture to OBS.
                UnityCapture.ECaptureSendResult result = m_captureInterface.SendTexture(tmpRT);

                RenderTexture.ReleaseTemporary(tmpRT);
            }
        }
    }
}
Download : SampleCaptureToOBS.cs

Each code is explained below.
Allows access to each Class in the current scope.
using Panorama180Render = Panorama180Render.Panorama180Render;
using UnityCapture = UnityCapture;

Processing at start : Get MainCamera and the component "Panorama180Render" in it.
if (Camera.main != null) {
    GameObject g = Camera.main.gameObject;
    if (g != null) {
        m_panorama180Render = g.GetComponent();
    }
}

Processing at start : Assign parameters for Panorama180 Render.
// Set GameViewMode (Default view).
m_panorama180Render.SetGameViewMode(Panorama180Render.GameViewMode.Default);

// Set IPD(Interpupillary distance. unit m).
m_panorama180Render.SetIPD(0.064f);

// Set texture size as Cubemap (512/1024/2048/4096/8192).
m_panorama180Render.SetRenderTextureSize(1024);

// Post Processing On / Off.
m_panorama180Render.SetPostProcessing(true);

// Set Panorama180.
m_panorama180Render.SetPanoramaMode(Panorama180Render.PanoramaMode.Panorama180);

// Set Stereo.
m_panorama180Render.SetEyesType(Panorama180Render.EyesType.Stereo);

// Output resolution at Panorama180.
m_panorama180Render.SetOutputTextureSizeType(Panorama180Render.OutputTextureSizeType._1024);
The designation will create a panoramic 180-3D 2048 x 1024 pixel image.

Processing at start : Starts the capture process of Panorama180 Render.
// Begin capture.
m_panorama180Render.BeginCapture();

Processing at start : Create the UnityCapture interface.
m_captureInterface = new UnityCapture.Interface(UnityCapture.ECaptureDevice.CaptureDevice1);

Processing at update : Gets the RenderTexture of the result of rendering Panorama180 Render.
RenderTexture rt = m_panorama180Render.GetRenderTexture();

Processing at update : Resize RenderTexture.
int rWidth  = 1920;
int rHeight = 1080;
RenderTexture tmpRT = RenderTexture.GetTemporary(rWidth, rHeight, 0, RenderTextureFormat.ARGB32);
Graphics.Blit(rt, tmpRT);
The size of the RenderTexture after resizing should be the same as the Resolution specified in OBS.
This process stores the resized RenderTexture in tmpRT.

Processing at update : Send RenderTexture to UnityCapture.
UnityCapture.ECaptureSendResult result = m_captureInterface.SendTexture(tmpRT);
Please refer to the UnityCapture sample and documentation for the return error code.

Processing at update : Discard the working RenderTexture.
RenderTexture.ReleaseTemporary(tmpRT);

Discard process at the end of the process.
if (m_captureInterface != null) m_captureInterface.Close();
if (m_panorama180Render != null) m_panorama180Render.EndCapture();

Create an empty GameObject and assign a script to it

Create an empty GameObject.
To this, add the aforementioned "SampleCaptureToOBS.cs" as a component.


This completes the implementation.

Execution

Press the Play button to execute.
Once executed, the Unity Editor side will render normally from the camera.
On the OBS side, the panorama 180-3D rendering results are displayed.


To turn off the message in the upper left corner of the Unity Editor,
uncheck the "Show Info" checkbox for the parameter of the Panorama180 Render component assigned to MainCamera.

Back