Home Integration Usage API FAQ URP14 # Integration Next Gen Recorder is capable of recording any 2d texture which basically means that you can record anything, whole screen, part of the screen or something that is not even seen on the screen. You can integrate Next Gen Recorder either automatically (Metal only) or manually. With automatic integration the whole screen will be recorded. To have full control what to record you must integrate manually. NOTE: <a href="urp14.html">URP 14 requires a custom integration!</a> ## Important - **All the recording sessions and exported videos are automatically removed when the application is closed.** If you are not sharing the exported video through the sharing API and you want to keep the file, please copy or move it to your preferred location. - **Next Gen Recorder automatically pauses the recording when application enters background or focus is lost.** So don't implement your own pause/resume logic when entering/returning from the background or when the focus is changed. - **Always set Application.targetFrameRate and Next Gen Recorder's TargetFrameRate.** Otherwise you might get weirdly keyframed video. ## Automatic integration (Metal only) Automatic integration is available on Metal only and it will record the whole screen, including the UI. Automatic integration is executed when you call `StartRecording` or `PrepareRecording` for the first time and you have not integrated manually. ## Manual integration There are multiple ways to integrate Next Gen Recorder. Use Metal Screen Recorder (or automatic integration) if you are only going to support only Metal renderer and you want to record the whole screen with the UI. It is the easiest and most performant way to integrate. If you need to support both, OpenGL and Metal you need to integrate manually. #### Renderer support | | Automatic/Manual Integration<br />MetalScreenRecorder | Manual Integration<br />VirtualScreen | Manual Integration<br />ImageEffectRecorder | Manual Integration<br />MetalCameraRecorder | Custom Integration | |--------|:-------------:|:-------------------:|:-------------------:|:-------------------:|:------------------:| | Metal | x | x, deprecated | x, legacy | x | up to you | | OpenGL | | x, deprecated | x, legacy | | up to you | #### Render Pipeline support | | Automatic/Manual Integration<br />MetalScreenRecorder | Manual Integration<br />VirtualScreen | Manual Integration<br />ImageEffectRecorder | Manual Integration<br />MetalCameraRecorder | Custom Integration | |----------------------------|:-------------:|:-------------------:|:-------------------:|:-------------------:|:------------------:| | Built-In Render Pipeline | x | x, deprecated | x, legacy | x | up to you | | Scriptable Render Pipeline | x | | | | up to you | #### UI recording | | Automatic/Manual Integration<br />MetalScreenRecorder | Manual Integration<br />VirtualScreen | Manual Integration<br />ImageEffectRecorder | Manual Integration<br />MetalCameraRecorder | Custom Integration | |-----------------------|:-------------:|:-------------------:|:-------------------:|:------------------:|:------------------:| | Records UI by default | x | | | | up to you | ### Integration using the Metal Screen Recorder Metal Screen Recorder allows you to record everything seen on the screen and it also supports Scriptable Render Pipeline (SRP). To use the Metal Screen Recorder, just drop it on top of any game object in your scene. ![Metal Screen Recorder](img/metal_screen_recorder.png "pmjo's Next Gen Recorder") NOTE: Metal Screen Recorder does not work with URP 14 but does work with URP 12 and older. ### Integration using the Virtual Screen (DEPRECATED, VirtualScreen will be removed in next release) If you have only one camera it can be recorded by simply adding `Virtual Screen` component on it and making sure both `Blit to Recorder` and `Blit to Screen` are checked. Virtual Screen does not support SRP. For SRP you should either do a custom integration or use the Metal Screen Recorder. ![Virtual Screen](img/virtualscreen.png "pmjo's Next Gen Recorder") If you have multiple cameras, add `Virtual Screen` to all the cameras that are rendering to the SCREEN and check `Blit to Recorder` and `Blit to Screen` on the LAST camera ONLY. Last camera is the camera that has the greatest `Depth`. `Depth` defines the camera rendering order. Last Camera | Other Cameras ------------ | ------------- ![Virtual Screen](img/virtualscreen.png "pmjo's Next Gen Recorder") | ![Virtual Screen](img/virtualscreen_unchecked.png "pmjo's Next Gen Recorder") ### Recording the UI (DEPRECATED, VirtualScreen will be removed in next release) By default the Unity UI is rendered on a separate layer after the camera and that why it is not captured to the video. There are multiple ways to resolve this. In case you are using image effects and you don't want to apply those effects to the UI you will need a secondary camera. If you are not using image effects you don't need any additional cameras. #### Including the UI when using a single camera only (DEPRECATED, VirtualScreen will be removed in next release) To render the UI with a camera instead of as a separate layer you must set the canvas `Render Mode` from `Screen Space - Overlay` to `Screen Space - Camera`. You must also set the canvas `Render Camera` to your `Main Camera` and `Plane Distance` to `1`. After these changes the recording will also contain the UI. If not, make sure that your camera `Culling Mask` includes the `UI` layer. ![Virtual Screen](img/canvas_camera.png "pmjo's Next Gen Recorder") #### Including the UI by using a separate UI camera (DEPRECATED, VirtualScreen will be removed in next release) Another option to include the the UI is to create a separate camera for the UI, set it's `Culling Mask` to `UI`, `Depth` to greater than your 3d camera's `Depth` and `Clear Flags` to `Depth Only`. After that set your canvas `Render mode` to `Screen Space - Camera` and `Render Camera` to the camera that you just created. Lastly add `Virtual Screen` to your 2d camera and check both `Blit to Recorder` and `Blit to Screen` on it and make sure they both are unchecked for the 3d camera. Also make sure your 3d camera does not contain the `UI` in `Culling Mask`. 2d/UI Camera | Main Camera | 2d Canvas ------------- | ------------- | ------------- ![Virtual Screen](img/virtualscreen_2dcamera.png "pmjo's Next Gen Recorder") | ![Virtual Screen](img/virtualscreen_maincamera.png "pmjo's Next Gen Recorder") | ![Virtual Screen](img/canvas.png "pmjo's Next Gen Recorder") #### Recording something else (DEPRECATED, VirtualScreen will be removed in next release) Sometimes you might want to record something that is not visible on the screen at all, for example a goalie camera for a football game or a 3rd person observer camera for a 1st person game. In these cases you just add `Virtual Screen` component to all the cameras you want to record with `Blit to Screen` unchecked and `Blit to Recorder` checked on the LAST camera. Last Camera | Other Cameras ------------ | ------------- ![Virtual Screen](img/virtualscreen_recorder_only.png "pmjo's Next Gen Recorder") | ![Virtual Screen](img/virtualscreen_unchecked.png "pmjo's Next Gen Recorder") ### Integration using the Image Effect Recorder In some special cases you might want to record a camera after or before some certain Image Effect. For this you can use a component called Image Effect Recorder. Just drag it onto your camera. It's good to remember that the order of the components matter. If you want to record all the image effects you must make sure that Image Effect Recorder is the last component on the component list. Image Effect Recorder does not support SRP. For SRP you should either do a custom integration or use the Metal Screen Recorder. ![Image Effect Recorder](img/image_effect_recorder.png "pmjo's Next Gen Recorder") ### Integration using the Metal Camera Recorder Metal Camera Recorder allows you to record everything that a camera renders when using Metal renderer and Built-In Render Pipeline. It does not support Scriptable Render Pipeline (SRP). To record a camera, drop the Metal Camera Recorder component on top of it. ### Custom integration If none of the above integration methods works for your project you can create your own recording pipeline by inheriting from VideoRecorderBase. ``` public class MyRecorder : Recorder.VideoRecorderBase { ... // Set the texture to be recorded if (RecordingTexture != myTextureToRecord) { RecordingTexture = myTextureToRecord; } ... // Blit the actual recording texture to the current encoder target, executed in graphics thread // Be sure that the recording texture is available and is not yet discarded, caution with temporary textures BlitRecordingTexture(); ... // Or if you use command buffers void Awake() { CommandBuffer myCommandBuffer = new CommandBuffer(); CommandBufferBlitRecordingTexture(myCommandBuffer) // Will add custom blit to the command buffer } // Or if you want to capture current render target (Metal only) CaptureMetalRenderTarget(); // Or if you use command buffers CommandBufferCaptureMetalRenderTarget(myCommandBuffer); ... } ``` - **IMPORTANT: When you set the RecordingTexture in a custom integration be sure the texture still exists (and it is not released or discarded) when the actual blit happens.** Setting the RecordingTexture only sets the recording source for the next blit and the actual blit happens in rendering thread. At the moment using temporary textures as Next Gen Recorder source (RenderTexture.GetTemporary) is not recommended but if you use them please release (RenderTexture.ReleaseTemporary) them after everything is rendered. Same applies for discarding render textures. Otherwise you might just get black screen in your recording. ### Example - Custom size off-screen camera recording Version 0.9.10.1 or greater and required. This example is for the Built-In Render Pipeline. ``` using UnityEngine; using UnityEngine.Rendering; using pmjo.NextGenRecorder; [RequireComponent(typeof(Camera))] public class OffScreenCameraRecorder : Recorder.VideoRecorderBase { public int videoWidth = 640; public int videoHeight = 480; private RenderTexture m_RenderTexture; private Camera m_Camera; private CommandBuffer m_CommandBuffer; void Awake() { m_RenderTexture = new RenderTexture(videoWidth, videoHeight, 24, RenderTextureFormat.Default); m_RenderTexture.Create(); m_Camera = GetComponent<Camera>(); m_Camera.targetTexture = m_RenderTexture; if (!Recorder.IsSupported) { Debug.LogWarning("Next Gen Recorder not supported on this platform"); return; } RecordingTexture = m_RenderTexture; m_CommandBuffer = new CommandBuffer(); CommandBufferBlitRecordingTexture(m_CommandBuffer); m_Camera.AddCommandBuffer(CameraEvent.AfterEverything, m_CommandBuffer); } } ``` ### Example - Recording Universal Render Pipeline (URP <=12) without the UI and custom SRP Version 0.9.10.1 or greater required. This example is for URP 7.3.1. You should add the CustomRenderPass to your forward renderer and UrpRecorder to any object in your scene. This example is for single camera setup. For stacked camera setup, please check the example below. ``` using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class RecordingPass : ScriptableRendererFeature { class CustomRenderPass : ScriptableRenderPass { private CommandBuffer m_CommandBuffer; public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { m_CommandBuffer = new CommandBuffer(); if (UrpRecorder.Instance != null) { UrpRecorder.Instance.Configure(m_CommandBuffer); } } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { context.ExecuteCommandBuffer(m_CommandBuffer); } public override void FrameCleanup(CommandBuffer cmd) { } } CustomRenderPass m_ScriptablePass; public override void Create() { m_ScriptablePass = new CustomRenderPass(); m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRendering; } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { renderer.EnqueuePass(m_ScriptablePass); } } ``` ``` using UnityEngine; using UnityEngine.Rendering; using pmjo.NextGenRecorder; [RequireComponent(typeof(Camera))] public class UrpRecorder : Recorder.VideoRecorderBase { public static UrpRecorder Instance; void Awake() { Instance = this; Recorder.VerticalFlip = false; #if UNITY_EDITOR || UNITY_STANDALONE_OSX Recorder.ColorSpace = ColorSpace.Linear; #endif } public void Configure(CommandBuffer commandBuffer) { if (Application.isPlaying) { CommandBufferCaptureMetalRenderTarget(commandBuffer); } } } ``` ### Example - Recording Universal Render Pipeline (URP <=12) without the UI when using stacked cameras Version 0.9.10.1 or greater required. This example is for URP 7.3.1. You should add the CustomRenderPass to your forward renderer and UrpRecorder to any object in your scene. You should also set the camera that you want to record the UrpRecorder component. ``` using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class RecordingPass : ScriptableRendererFeature { class CustomRenderPass : ScriptableRenderPass { private CommandBuffer m_CommandBuffer; public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (UrpRecorder.Instance != null && UrpRecorder.Instance.recordedCamera == renderingData.cameraData.camera) { if (m_CommandBuffer == null) { m_CommandBuffer = new CommandBuffer(); UrpRecorder.Instance.Configure(m_CommandBuffer); } context.ExecuteCommandBuffer(m_CommandBuffer); } } public override void FrameCleanup(CommandBuffer cmd) { } } CustomRenderPass m_ScriptablePass; public override void Create() { m_ScriptablePass = new CustomRenderPass(); m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRendering; } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { renderer.EnqueuePass(m_ScriptablePass); } } ``` ``` using UnityEngine; using UnityEngine.Rendering; using pmjo.NextGenRecorder; [RequireComponent(typeof(Camera))] public class UrpRecorder : Recorder.VideoRecorderBase { public static UrpRecorder Instance; public Camera recordedCamera; void Awake() { Instance = this; Recorder.VerticalFlip = false; #if UNITY_EDITOR || UNITY_STANDALONE_OSX Recorder.ColorSpace = ColorSpace.Linear; #endif } public void Configure(CommandBuffer commandBuffer) { if (Application.isPlaying) { CommandBufferCaptureMetalRenderTarget(commandBuffer); } } } ```