You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
9.2 KiB
149 lines
9.2 KiB
using System;
|
|
using Unity.Mathematics;
|
|
using UnityEngine.Rendering;
|
|
|
|
#if ENABLE_VR && ENABLE_XR_MODULE
|
|
using UnityEngine.XR;
|
|
#endif
|
|
|
|
namespace UnityEngine.Experimental.Rendering
|
|
{
|
|
internal static class XRMirrorView
|
|
{
|
|
static readonly MaterialPropertyBlock s_MirrorViewMaterialProperty = new MaterialPropertyBlock();
|
|
static readonly ProfilingSampler k_MirrorViewProfilingSampler = new ProfilingSampler("XR Mirror View");
|
|
|
|
static readonly int k_SourceTex = Shader.PropertyToID("_SourceTex");
|
|
static readonly int k_SourceTexArraySlice = Shader.PropertyToID("_SourceTexArraySlice");
|
|
static readonly int k_ScaleBias = Shader.PropertyToID("_ScaleBias");
|
|
static readonly int k_ScaleBiasRt = Shader.PropertyToID("_ScaleBiasRt");
|
|
static readonly int k_SRGBRead = Shader.PropertyToID("_SRGBRead");
|
|
static readonly int k_SRGBWrite = Shader.PropertyToID("_SRGBWrite");
|
|
static readonly int k_MaxNits = Shader.PropertyToID("_MaxNits");
|
|
static readonly int k_SourceMaxNits = Shader.PropertyToID("_SourceMaxNits");
|
|
static readonly int k_SourceHDREncoding = Shader.PropertyToID("_SourceHDREncoding");
|
|
static readonly int k_ColorTransform = Shader.PropertyToID("_ColorTransform");
|
|
|
|
#if ENABLE_VR && ENABLE_XR_MODULE
|
|
internal static void RenderMirrorView(CommandBuffer cmd, Camera camera, Material mat, XRDisplaySubsystem display)
|
|
{
|
|
// XRTODO : remove this check when the Quest plugin is fixed
|
|
if (Application.platform == RuntimePlatform.Android && !XRGraphicsAutomatedTests.running)
|
|
return;
|
|
|
|
if (display == null || !display.running || mat == null)
|
|
return;
|
|
|
|
int mirrorBlitMode = display.GetPreferredMirrorBlitMode();
|
|
if (display.GetMirrorViewBlitDesc(null, out var blitDesc, mirrorBlitMode))
|
|
{
|
|
using (new ProfilingScope(cmd, k_MirrorViewProfilingSampler))
|
|
{
|
|
cmd.SetRenderTarget(camera.targetTexture != null ? camera.targetTexture : new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget));
|
|
|
|
if (blitDesc.nativeBlitAvailable)
|
|
{
|
|
display.AddGraphicsThreadMirrorViewBlit(cmd, blitDesc.nativeBlitInvalidStates, mirrorBlitMode);
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < blitDesc.blitParamsCount; ++i)
|
|
{
|
|
blitDesc.GetBlitParameter(i, out var blitParam);
|
|
|
|
Vector4 scaleBias = new Vector4(blitParam.srcRect.width, blitParam.srcRect.height, blitParam.srcRect.x, blitParam.srcRect.y);
|
|
Vector4 scaleBiasRt = new Vector4(blitParam.destRect.width, blitParam.destRect.height, blitParam.destRect.x, blitParam.destRect.y);
|
|
|
|
// Deal with y-flip
|
|
if (camera.targetTexture != null || camera.cameraType == CameraType.SceneView || camera.cameraType == CameraType.Preview)
|
|
{
|
|
scaleBias.y = -scaleBias.y;
|
|
scaleBias.w += blitParam.srcRect.height;
|
|
}
|
|
|
|
HDROutputSettings mainDisplayHdrSettings = HDROutputSettings.main;
|
|
|
|
// If we are writing to a HDR surface or reading from one we use the conversion shader to handle both
|
|
if (blitParam.srcHdrEncoded || mainDisplayHdrSettings.active)
|
|
{
|
|
ColorGamut mainDisplayColorGamut = mainDisplayHdrSettings.active ? mainDisplayHdrSettings.displayColorGamut
|
|
: ColorGamut.sRGB;
|
|
ColorGamut xrDisplayColorGamut = blitParam.srcHdrEncoded ? blitParam.srcHdrColorGamut
|
|
: ColorGamut.sRGB;
|
|
|
|
ColorPrimaries mainDisplayColorPrimaries = ColorGamutUtility.GetColorPrimaries(mainDisplayColorGamut);
|
|
ColorPrimaries xrDisplayColorPrimaries = ColorGamutUtility.GetColorPrimaries(xrDisplayColorGamut);
|
|
|
|
// Use the material? And use the passes?
|
|
HDROutputUtils.ConfigureHDROutput(s_MirrorViewMaterialProperty, mainDisplayColorGamut);
|
|
HDROutputUtils.ConfigureHDROutput(mat, HDROutputUtils.Operation.ColorConversion | HDROutputUtils.Operation.ColorEncoding);
|
|
int sourceHdrEncoding;
|
|
HDROutputUtils.GetColorEncodingForGamut(xrDisplayColorGamut, out sourceHdrEncoding);
|
|
s_MirrorViewMaterialProperty.SetInteger(k_SourceHDREncoding, sourceHdrEncoding);
|
|
|
|
float3x3 sourceToRec2020 = float3x3.identity;
|
|
if (xrDisplayColorPrimaries == ColorPrimaries.Rec709)
|
|
sourceToRec2020 = ColorSpaceUtils.Rec709ToRec2020Mat;
|
|
else if (xrDisplayColorPrimaries == ColorPrimaries.P3)
|
|
sourceToRec2020 = ColorSpaceUtils.P3D65ToRec2020Mat;
|
|
|
|
float3x3 rec2020ToDest = float3x3.identity;
|
|
if (mainDisplayColorPrimaries == ColorPrimaries.Rec709)
|
|
rec2020ToDest = ColorSpaceUtils.Rec2020ToRec709Mat;
|
|
else if (mainDisplayColorPrimaries == ColorPrimaries.P3)
|
|
rec2020ToDest = ColorSpaceUtils.Rec2020ToP3D65Mat;
|
|
|
|
// Quicker to go straight to a Matrix4x4 and multiply there? Or to store these as Matrix4x4 instead due to Unity missing a 3x3 type?
|
|
float3x3 colorTransform = math.mul(sourceToRec2020, rec2020ToDest);
|
|
Matrix4x4 m = new Matrix4x4((Vector4) new float4(colorTransform.c0, 0.0f),
|
|
(Vector4) new float4(colorTransform.c1, 0.0f), (Vector4) new float4(colorTransform.c2, 0.0f),
|
|
new Vector4(0.0f, 0.0f, 0.0f, 0.0f));
|
|
s_MirrorViewMaterialProperty.SetMatrix(k_ColorTransform, m);
|
|
|
|
s_MirrorViewMaterialProperty.SetFloat(k_MaxNits, mainDisplayHdrSettings.active ? mainDisplayHdrSettings.maxToneMapLuminance : 160.0f);
|
|
s_MirrorViewMaterialProperty.SetFloat(k_SourceMaxNits, blitParam.srcHdrEncoded ? blitParam.srcHdrMaxLuminance : 160.0f);
|
|
}
|
|
|
|
// For 8888 formats we always gamma correct eye textures : use explicit sRGB read in shader only if the source is not using sRGB format.
|
|
bool manualSRGBRead = !blitParam.srcTex.sRGB &&
|
|
(blitParam.srcTex.graphicsFormat == GraphicsFormat.R8G8B8A8_UNorm ||
|
|
blitParam.srcTex.graphicsFormat == GraphicsFormat.B8G8R8A8_UNorm);
|
|
s_MirrorViewMaterialProperty.SetFloat(k_SRGBRead, manualSRGBRead ? 1.0f : 0.0f);
|
|
|
|
// Perform explicit sRGB write in shader if color space is gamma
|
|
s_MirrorViewMaterialProperty.SetFloat(k_SRGBWrite, (QualitySettings.activeColorSpace == ColorSpace.Linear) ? 0.0f : 1.0f);
|
|
|
|
s_MirrorViewMaterialProperty.SetTexture(k_SourceTex, blitParam.srcTex);
|
|
s_MirrorViewMaterialProperty.SetVector(k_ScaleBias, scaleBias);
|
|
s_MirrorViewMaterialProperty.SetVector(k_ScaleBiasRt, scaleBiasRt);
|
|
s_MirrorViewMaterialProperty.SetFloat(k_SourceTexArraySlice, blitParam.srcTexArraySlice);
|
|
|
|
if (XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster) && blitParam.foveatedRenderingInfo != IntPtr.Zero)
|
|
{
|
|
cmd.ConfigureFoveatedRendering(blitParam.foveatedRenderingInfo);
|
|
cmd.EnableShaderKeyword("_FOVEATED_RENDERING_NON_UNIFORM_RASTER");
|
|
}
|
|
|
|
if (blitParam.srcTex.dimension != TextureDimension.Tex2DArray)
|
|
cmd.EnableShaderKeyword("DISABLE_TEXTURE2D_X_ARRAY");
|
|
|
|
cmd.DrawProcedural(Matrix4x4.identity, mat, 0, MeshTopology.Quads, 4, 1, s_MirrorViewMaterialProperty);
|
|
|
|
// Set back the XR texture for regular XR calls
|
|
if (blitParam.srcTex.dimension != TextureDimension.Tex2DArray && TextureXR.useTexArray)
|
|
cmd.DisableShaderKeyword("DISABLE_TEXTURE2D_X_ARRAY");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster))
|
|
{
|
|
cmd.DisableShaderKeyword("_FOVEATED_RENDERING_NON_UNIFORM_RASTER");
|
|
cmd.ConfigureFoveatedRendering(IntPtr.Zero);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
}
|
|
}
|