forked from Unity-Technologies/Graphics
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[URP] [Doc] Add XR SPI full screen blitting example (Unity-Technologi…
…es#5395) * * Initial checkin * Update how-to-do-fullscreen-blitting-under-XR-SPI.md * Fixed image link. * Added c# code block * * Run formatting tool. * * Updated images for 2nd iteration. * Update how-to-do-fullscreen-blitting-under-XR-SPI.md * Replaced depth blit example with color blit example. * Update how-to-do-fullscreen-blitting-under-XR-SPI.md * Fixed broken image link. * Edited the content. * Ran the formatter. Co-authored-by: Oleksandr Kokoshyn <oleksandr.kokoshyn@unity3d.com>
- Loading branch information
1 parent
ddf25af
commit 1ed9187
Showing
10 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
3 changes: 3 additions & 0 deletions
3
...pelines.universal/Documentation~/Images/how-to/blit-xr/add-renderer-feature.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
...nder-pipelines.universal/Documentation~/Images/how-to/blit-xr/example-scene.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
...pelines.universal/Documentation~/Images/how-to/blit-xr/final-play-mode-view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
...es.universal/Documentation~/Images/how-to/blit-xr/final-scene-and-game-view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
...ipelines.universal/Documentation~/Images/how-to/blit-xr/urp-global-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
...-pipelines.universal/Documentation~/Images/how-to/blit-xr/xr-plugin-mockhmd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
...ines.universal/Documentation~/containers/how-to-custom-effect-render-objects.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[!include[](../renderer-features/how-to-custom-effect-render-objects.md)] |
9 changes: 9 additions & 0 deletions
9
com.unity.render-pipelines.universal/Documentation~/how-to.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Practical how-to guides | ||
|
||
This section contains practical how-to guides. | ||
|
||
The section contains the following topics: | ||
|
||
* [How to perform a full screen blit in Single Pass Instanced rendering in XR](renderer-features/how-to-fullscreen-blit-in-xr-spi.md). | ||
|
||
* [How to create a custom rendering effect using the Render Objects Renderer Feature](containers/how-to-custom-effect-render-objects.md) |
223 changes: 223 additions & 0 deletions
223
....universal/Documentation~/renderer-features/how-to-fullscreen-blit-in-xr-spi.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
# How to perform a full screen blit in Single Pass Instanced rendering in XR | ||
|
||
The example on this page describes how to create a custom Renderer Feature that performs a full screen blit in Single Pass Instanced rendering in XR. | ||
|
||
## Example overview | ||
|
||
This example implements the following solution: | ||
|
||
* A [custom Renderer Feature](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@12.0/api/UnityEngine.Rendering.Universal.ScriptableRendererFeature.html) calls a custom [Render Pass](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@12.0/api/UnityEngine.Rendering.Universal.ScriptableRenderPass.html). | ||
|
||
* The [Render Pass](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@12.0/api/UnityEngine.Rendering.Universal.ScriptableRenderPass.html) blits the Opaque Texture to the the [Camera color target](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@7.0/api/UnityEngine.Rendering.Universal.ScriptableRenderer.html#UnityEngine_Rendering_Universal_ScriptableRenderer_cameraColorTarget) for the current renderer. The render pass uses the command buffer to draw a full screen mesh for both eyes. | ||
|
||
The example includes [the shader](#shader) that performs the GPU side of the rendering. The shader samples the color buffer using XR sampler macros. | ||
|
||
## Prerequisites | ||
|
||
This example requires the following: | ||
|
||
* The **Scriptable Render Pipeline Settings** property refers to a URP asset (**Project Settings** > **Graphics** > **Scriptable Render Pipeline Settings**). | ||
|
||
## <a name="example-objects"></a>Create example Scene and GameObjects | ||
|
||
To follow the steps in this example, create a new Scene with the following GameObjects: | ||
|
||
1. Create a Cube. Ensure that the Cube is clearly visible from the main Camera. | ||
|
||
![](../Images/how-to/blit-xr/example-scene.png) | ||
|
||
Now you have the Scene necessary to follow the steps in this example. | ||
|
||
## Example implementation | ||
|
||
This section assumes that you created a Scene as described in section [Create example Scene and GameObjects](#example-objects). | ||
|
||
Follow these steps to create a [custom Renderer Feature](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@12.0/api/UnityEngine.Rendering.Universal.ScriptableRendererFeature.html) with a custom [Render Pass](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@12.0/api/UnityEngine.Rendering.Universal.ScriptableRenderPass.html). | ||
|
||
1. Create a new C# script. Call it `ColorBlitRendererFeature.cs`. This script implements the custom Renderer Feature. | ||
|
||
```C# | ||
using UnityEngine; | ||
using UnityEngine.Rendering; | ||
using UnityEngine.Rendering.Universal; | ||
|
||
internal class ColorBlitRendererFeature : ScriptableRendererFeature | ||
{ | ||
public Shader m_Shader; | ||
public float m_Intensity; | ||
|
||
Material m_Material; | ||
|
||
ColorBlitPass m_RenderPass = null; | ||
|
||
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) | ||
{ | ||
if (renderingData.cameraData.cameraType == CameraType.Game) | ||
{ | ||
//Calling ConfigureInput with the ScriptableRenderPassInput.Color argument ensures that the opaque texture is available to the Render Pass | ||
m_RenderPass.ConfigureInput(ScriptableRenderPassInput.Color); | ||
m_RenderPass.SetTarget(renderer.cameraColorTarget, m_Intensity); | ||
renderer.EnqueuePass(m_RenderPass); | ||
} | ||
} | ||
|
||
public override void Create() | ||
{ | ||
if (m_Shader != null) | ||
m_Material = new Material(m_Shader); | ||
|
||
m_RenderPass = new ColorBlitPass(m_Material); | ||
} | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
CoreUtils.Destroy(m_Material); | ||
} | ||
} | ||
``` | ||
|
||
2. Create a new C# script. Call it `ColorBlitPass.cs`. This script implements the custom Render Pass that performs the custom blit draw call. | ||
|
||
This Render Pass uses the `cmd.DrawMesh` method to draw a full-screen quad and perform the blit operation. | ||
|
||
> **NOTE:** Do not use the `cmd.Blit` method in URP XR projects because that method has compatibility issues with the URP XR integration. Using `cmd.Blit` might implicitly enable or disable XR shader keywords, which breaks XR SPI rendering. | ||
|
||
```C# | ||
using UnityEngine; | ||
using UnityEngine.Rendering; | ||
using UnityEngine.Rendering.Universal; | ||
|
||
internal class ColorBlitPass : ScriptableRenderPass | ||
{ | ||
ProfilingSampler m_ProfilingSampler = new ProfilingSampler("ColorBlit"); | ||
Material m_Material; | ||
RenderTargetIdentifier m_CameraColorTarget; | ||
float m_Intensity; | ||
|
||
public ColorBlitPass(Material material) | ||
{ | ||
m_Material = material; | ||
renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; | ||
} | ||
|
||
public void SetTarget(RenderTargetIdentifier colorHandle, float intensity) | ||
{ | ||
m_CameraColorTarget = colorHandle; | ||
m_Intensity = intensity; | ||
} | ||
|
||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) | ||
{ | ||
var camera = renderingData.cameraData.camera; | ||
if (camera.cameraType != CameraType.Game) | ||
return; | ||
|
||
if (m_Material == null) | ||
return; | ||
|
||
CommandBuffer cmd = CommandBufferPool.Get(); | ||
using (new ProfilingScope(cmd, m_ProfilingSampler)) | ||
{ | ||
m_Material.SetFloat("_Intensity", m_Intensity); | ||
cmd.SetRenderTarget(new RenderTargetIdentifier(m_CameraColorTarget, 0, CubemapFace.Unknown, -1)); | ||
//The RenderingUtils.fullscreenMesh argument specifies that the mesh to draw is a quad. | ||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_Material); | ||
} | ||
context.ExecuteCommandBuffer(cmd); | ||
cmd.Clear(); | ||
|
||
CommandBufferPool.Release(cmd); | ||
} | ||
} | ||
``` | ||
|
||
3. <a name="shader"></a>Create the shader that performs the blit operation. Call the shader file `ColorBlit.shader`. The vertex function outputs the full-screen quad position. The fragment function samples the color buffer and returns the `color * float4(0, _Intensity, 0, 1)` value to the render target. | ||
|
||
```hlsl | ||
Shader "ColorBlit" | ||
{ | ||
SubShader | ||
{ | ||
Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"} | ||
LOD 100 | ||
ZWrite Off Cull Off | ||
Pass | ||
{ | ||
Name "ColorBlitPass" | ||
|
||
HLSLPROGRAM | ||
#pragma vertex vert | ||
#pragma fragment frag | ||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | ||
|
||
struct Attributes | ||
{ | ||
float4 positionHCS : POSITION; | ||
float2 uv : TEXCOORD0; | ||
UNITY_VERTEX_INPUT_INSTANCE_ID | ||
}; | ||
|
||
struct Varyings | ||
{ | ||
float4 positionCS : SV_POSITION; | ||
float2 uv : TEXCOORD0; | ||
UNITY_VERTEX_OUTPUT_STEREO | ||
}; | ||
|
||
Varyings vert(Attributes input) | ||
{ | ||
Varyings output; | ||
UNITY_SETUP_INSTANCE_ID(input); | ||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); | ||
|
||
// Note: The pass is setup with a mesh already in clip | ||
// space, that's why, it's enough to just output vertex | ||
// positions | ||
output.positionCS = float4(input.positionHCS.xyz, 1.0); | ||
|
||
#if UNITY_UV_STARTS_AT_TOP | ||
output.positionCS.y *= -1; | ||
#endif | ||
|
||
output.uv = input.uv; | ||
return output; | ||
} | ||
|
||
TEXTURE2D_X(_CameraOpaqueTexture); | ||
SAMPLER(sampler_CameraOpaqueTexture); | ||
|
||
float _Intensity; | ||
|
||
half4 frag (Varyings input) : SV_Target | ||
{ | ||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); | ||
float4 color = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, input.uv); | ||
return color * float4(0, _Intensity, 0, 1); | ||
} | ||
ENDHLSL | ||
} | ||
} | ||
} | ||
``` | ||
|
||
4. Add the `ColorBlitRendererFeature` to the Universal Renderer asset. | ||
|
||
![Add Renderer Feature](../Images/how-to/blit-xr/add-renderer-feature.png) | ||
|
||
For information on how to add a Renderer Feature, see the page [How to add a Renderer Feature to a Renderer](../urp-renderer-feature-how-to-add.md). | ||
|
||
For this example, set the Intensity property to 1.5. | ||
|
||
5. To visualize the example, configure the project to use XR SDK. [Add the MockHMD XR Plugin to the project](https://docs.unity3d.com/Packages/com.unity.xr.mock-hmd@latest/index.html). Set the **Render Mode** property to **Single Pass Instanced**. | ||
![Configure MockHMD](../Images/how-to/blit-xr/xr-plugin-mockhmd.png) | ||
|
||
Unity shows the following views: | ||
|
||
![Final Scene and Game views](../Images/how-to/blit-xr/final-scene-and-game-view.png) | ||
|
||
6. Enter the Play mode. Unity shows the color buffer. | ||
|
||
![Final Play mode view](../Images/how-to/blit-xr/final-play-mode-view.png) | ||
|
||
The example is complete. |