A game about forced loneliness, made by TACStudios
at master 149 lines 9.4 kB view raw
1using System; 2using Unity.Mathematics; 3using UnityEngine.Rendering; 4 5#if ENABLE_VR && ENABLE_XR_MODULE 6using UnityEngine.XR; 7#endif 8 9namespace UnityEngine.Experimental.Rendering 10{ 11 internal static class XRMirrorView 12 { 13 static readonly MaterialPropertyBlock s_MirrorViewMaterialProperty = new MaterialPropertyBlock(); 14 static readonly ProfilingSampler k_MirrorViewProfilingSampler = new ProfilingSampler("XR Mirror View"); 15 16 static readonly int k_SourceTex = Shader.PropertyToID("_SourceTex"); 17 static readonly int k_SourceTexArraySlice = Shader.PropertyToID("_SourceTexArraySlice"); 18 static readonly int k_ScaleBias = Shader.PropertyToID("_ScaleBias"); 19 static readonly int k_ScaleBiasRt = Shader.PropertyToID("_ScaleBiasRt"); 20 static readonly int k_SRGBRead = Shader.PropertyToID("_SRGBRead"); 21 static readonly int k_SRGBWrite = Shader.PropertyToID("_SRGBWrite"); 22 static readonly int k_MaxNits = Shader.PropertyToID("_MaxNits"); 23 static readonly int k_SourceMaxNits = Shader.PropertyToID("_SourceMaxNits"); 24 static readonly int k_SourceHDREncoding = Shader.PropertyToID("_SourceHDREncoding"); 25 static readonly int k_ColorTransform = Shader.PropertyToID("_ColorTransform"); 26 27#if ENABLE_VR && ENABLE_XR_MODULE 28 internal static void RenderMirrorView(CommandBuffer cmd, Camera camera, Material mat, XRDisplaySubsystem display) 29 { 30 // XRTODO : remove this check when the Quest plugin is fixed 31 if (Application.platform == RuntimePlatform.Android && !XRGraphicsAutomatedTests.running) 32 return; 33 34 if (display == null || !display.running || mat == null) 35 return; 36 37 int mirrorBlitMode = display.GetPreferredMirrorBlitMode(); 38 if (display.GetMirrorViewBlitDesc(null, out var blitDesc, mirrorBlitMode)) 39 { 40 using (new ProfilingScope(cmd, k_MirrorViewProfilingSampler)) 41 { 42 cmd.SetRenderTarget(camera.targetTexture != null ? camera.targetTexture : new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget)); 43 44 if (blitDesc.nativeBlitAvailable) 45 { 46 display.AddGraphicsThreadMirrorViewBlit(cmd, blitDesc.nativeBlitInvalidStates, mirrorBlitMode); 47 } 48 else 49 { 50 for (int i = 0; i < blitDesc.blitParamsCount; ++i) 51 { 52 blitDesc.GetBlitParameter(i, out var blitParam); 53 54 Vector4 scaleBias = new Vector4(blitParam.srcRect.width, blitParam.srcRect.height, blitParam.srcRect.x, blitParam.srcRect.y); 55 Vector4 scaleBiasRt = new Vector4(blitParam.destRect.width, blitParam.destRect.height, blitParam.destRect.x, blitParam.destRect.y); 56 57 // Deal with y-flip 58 if (camera.targetTexture != null || camera.cameraType == CameraType.SceneView || camera.cameraType == CameraType.Preview) 59 { 60 scaleBias.y = -scaleBias.y; 61 scaleBias.w += blitParam.srcRect.height; 62 } 63 64 HDROutputSettings mainDisplayHdrSettings = HDROutputSettings.main; 65 66 // If we are writing to a HDR surface or reading from one we use the conversion shader to handle both 67 if (blitParam.srcHdrEncoded || mainDisplayHdrSettings.active) 68 { 69 ColorGamut mainDisplayColorGamut = mainDisplayHdrSettings.active ? mainDisplayHdrSettings.displayColorGamut 70 : ColorGamut.sRGB; 71 ColorGamut xrDisplayColorGamut = blitParam.srcHdrEncoded ? blitParam.srcHdrColorGamut 72 : ColorGamut.sRGB; 73 74 ColorPrimaries mainDisplayColorPrimaries = ColorGamutUtility.GetColorPrimaries(mainDisplayColorGamut); 75 ColorPrimaries xrDisplayColorPrimaries = ColorGamutUtility.GetColorPrimaries(xrDisplayColorGamut); 76 77 // Use the material? And use the passes? 78 HDROutputUtils.ConfigureHDROutput(s_MirrorViewMaterialProperty, mainDisplayColorGamut); 79 HDROutputUtils.ConfigureHDROutput(mat, HDROutputUtils.Operation.ColorConversion | HDROutputUtils.Operation.ColorEncoding); 80 int sourceHdrEncoding; 81 HDROutputUtils.GetColorEncodingForGamut(xrDisplayColorGamut, out sourceHdrEncoding); 82 s_MirrorViewMaterialProperty.SetInteger(k_SourceHDREncoding, sourceHdrEncoding); 83 84 float3x3 sourceToRec2020 = float3x3.identity; 85 if (xrDisplayColorPrimaries == ColorPrimaries.Rec709) 86 sourceToRec2020 = ColorSpaceUtils.Rec709ToRec2020Mat; 87 else if (xrDisplayColorPrimaries == ColorPrimaries.P3) 88 sourceToRec2020 = ColorSpaceUtils.P3D65ToRec2020Mat; 89 90 float3x3 rec2020ToDest = float3x3.identity; 91 if (mainDisplayColorPrimaries == ColorPrimaries.Rec709) 92 rec2020ToDest = ColorSpaceUtils.Rec2020ToRec709Mat; 93 else if (mainDisplayColorPrimaries == ColorPrimaries.P3) 94 rec2020ToDest = ColorSpaceUtils.Rec2020ToP3D65Mat; 95 96 // Quicker to go straight to a Matrix4x4 and multiply there? Or to store these as Matrix4x4 instead due to Unity missing a 3x3 type? 97 float3x3 colorTransform = math.mul(sourceToRec2020, rec2020ToDest); 98 Matrix4x4 m = new Matrix4x4((Vector4) new float4(colorTransform.c0, 0.0f), 99 (Vector4) new float4(colorTransform.c1, 0.0f), (Vector4) new float4(colorTransform.c2, 0.0f), 100 new Vector4(0.0f, 0.0f, 0.0f, 0.0f)); 101 s_MirrorViewMaterialProperty.SetMatrix(k_ColorTransform, m); 102 103 s_MirrorViewMaterialProperty.SetFloat(k_MaxNits, mainDisplayHdrSettings.active ? mainDisplayHdrSettings.maxToneMapLuminance : 160.0f); 104 s_MirrorViewMaterialProperty.SetFloat(k_SourceMaxNits, blitParam.srcHdrEncoded ? blitParam.srcHdrMaxLuminance : 160.0f); 105 } 106 107 // For 8888 formats we always gamma correct eye textures : use explicit sRGB read in shader only if the source is not using sRGB format. 108 bool manualSRGBRead = !blitParam.srcTex.sRGB && 109 (blitParam.srcTex.graphicsFormat == GraphicsFormat.R8G8B8A8_UNorm || 110 blitParam.srcTex.graphicsFormat == GraphicsFormat.B8G8R8A8_UNorm); 111 s_MirrorViewMaterialProperty.SetFloat(k_SRGBRead, manualSRGBRead ? 1.0f : 0.0f); 112 113 // Perform explicit sRGB write in shader if color space is gamma 114 s_MirrorViewMaterialProperty.SetFloat(k_SRGBWrite, (QualitySettings.activeColorSpace == ColorSpace.Linear) ? 0.0f : 1.0f); 115 116 s_MirrorViewMaterialProperty.SetTexture(k_SourceTex, blitParam.srcTex); 117 s_MirrorViewMaterialProperty.SetVector(k_ScaleBias, scaleBias); 118 s_MirrorViewMaterialProperty.SetVector(k_ScaleBiasRt, scaleBiasRt); 119 s_MirrorViewMaterialProperty.SetFloat(k_SourceTexArraySlice, blitParam.srcTexArraySlice); 120 121 if (XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster) && blitParam.foveatedRenderingInfo != IntPtr.Zero) 122 { 123 cmd.ConfigureFoveatedRendering(blitParam.foveatedRenderingInfo); 124 cmd.EnableShaderKeyword("_FOVEATED_RENDERING_NON_UNIFORM_RASTER"); 125 } 126 127 if (blitParam.srcTex.dimension != TextureDimension.Tex2DArray) 128 cmd.EnableShaderKeyword("DISABLE_TEXTURE2D_X_ARRAY"); 129 130 cmd.DrawProcedural(Matrix4x4.identity, mat, 0, MeshTopology.Quads, 4, 1, s_MirrorViewMaterialProperty); 131 132 // Set back the XR texture for regular XR calls 133 if (blitParam.srcTex.dimension != TextureDimension.Tex2DArray && TextureXR.useTexArray) 134 cmd.DisableShaderKeyword("DISABLE_TEXTURE2D_X_ARRAY"); 135 } 136 } 137 } 138 } 139 140 if (XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster)) 141 { 142 cmd.DisableShaderKeyword("_FOVEATED_RENDERING_NON_UNIFORM_RASTER"); 143 cmd.ConfigureFoveatedRendering(IntPtr.Zero); 144 } 145 } 146 147#endif 148 } 149}