Files
ApexSurgery/Assets/Oculus/VR/Editor/OVRProjectSetup/Tasks/Implementations/OVRProjectSetupRenderingTasks.cs
T
2025-07-04 20:33:06 +03:00

369 lines
16 KiB
C#

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Linq;
using UnityEditor;
using UnityEditor.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
#if USING_URP
using UnityEngine.Rendering.Universal;
#endif
[InitializeOnLoad]
internal static class OVRProjectSetupRenderingTasks
{
#if USING_XR_SDK_OCULUS
private static Unity.XR.Oculus.OculusSettings OculusSettings
{
get
{
UnityEditor.EditorBuildSettings.TryGetConfigObject<Unity.XR.Oculus.OculusSettings>(
"Unity.XR.Oculus.Settings", out var settings);
return settings;
}
}
#endif
#if USING_URP && UNITY_2022_2_OR_NEWER
// Call action for all UniversalRendererData being used, return true if all the return value of action is true
private static bool ForEachRendererData(Func<UniversalRendererData, bool> action)
{
var ret = true;
var pipelineAssets = new System.Collections.Generic.List<RenderPipelineAsset>();
QualitySettings.GetAllRenderPipelineAssetsForPlatform("Android", ref pipelineAssets);
foreach (var pipelineAsset in pipelineAssets)
{
var urpPipelineAsset = pipelineAsset as UniversalRenderPipelineAsset;
// If using URP pipeline
if (urpPipelineAsset)
{
var path = AssetDatabase.GetAssetPath(urpPipelineAsset);
var dependency = AssetDatabase.GetDependencies(path);
for (int i = 0; i < dependency.Length; i++)
{
// Try to read the dependency as UniversalRendererData
if (AssetDatabase.GetMainAssetTypeAtPath(dependency[i]) != typeof(UniversalRendererData))
continue;
UniversalRendererData renderData =
(UniversalRendererData)AssetDatabase.LoadAssetAtPath(dependency[i],
typeof(UniversalRendererData));
if (renderData)
{
ret = ret && action(renderData);
}
if (!ret)
{
break;
}
}
}
}
return ret;
}
#endif
private static GraphicsDeviceType[] GetGraphicsAPIs(BuildTargetGroup buildTargetGroup)
{
var buildTarget = buildTargetGroup.GetBuildTarget();
if (PlayerSettings.GetUseDefaultGraphicsAPIs(buildTarget))
{
return Array.Empty<GraphicsDeviceType>();
}
// Recommends OpenGL ES 3 or Vulkan
return PlayerSettings.GetGraphicsAPIs(buildTarget);
}
static OVRProjectSetupRenderingTasks()
{
const OVRProjectSetup.TaskGroup targetGroup = OVRProjectSetup.TaskGroup.Rendering;
//[Required] Set the color space to linear
OVRProjectSetup.AddTask(
conditionalLevel: buildTargetGroup =>
OVRProjectSetupUtils.IsPackageInstalled(OVRProjectSetupXRTasks.UnityXRPackage)
? OVRProjectSetup.TaskLevel.Required
: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
isDone: buildTargetGroup => PlayerSettings.colorSpace == ColorSpace.Linear,
message: "Color Space is required to be Linear",
fix: buildTargetGroup => PlayerSettings.colorSpace = ColorSpace.Linear,
fixMessage: "PlayerSettings.colorSpace = ColorSpace.Linear"
);
#if USING_XR_SDK_OCULUS && OCULUS_XR_EYE_TRACKED_FOVEATED_RENDERING && UNITY_2021_3_OR_NEWER
//[Required] Use Vulkan and IL2CPP/ARM64 when using ETFR
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Required,
group: targetGroup,
isDone: buildTargetGroup =>
{
var useIL2CPP = PlayerSettings.GetScriptingBackend(buildTargetGroup) == ScriptingImplementation.IL2CPP;
var useARM64 = PlayerSettings.Android.targetArchitectures == AndroidArchitecture.ARM64;
var useVK = GetGraphicsAPIs(buildTargetGroup).Any(item => item == GraphicsDeviceType.Vulkan);
return useVK && useARM64 && useIL2CPP;
},
message: "Need to use Vulkan for Graphics APIs, IL2CPP for scripting backend, and ARM64 for target architectures when using eye-tracked foveated rendering",
fix: buildTargetGroup =>
{
var buildTarget = buildTargetGroup.GetBuildTarget();
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64;
PlayerSettings.SetScriptingBackend(buildTargetGroup, ScriptingImplementation.IL2CPP);
PlayerSettings.SetGraphicsAPIs(buildTarget, new[] { GraphicsDeviceType.Vulkan });
},
fixMessage: "Set target architectures to ARM64, scripting backend to IL2CPP, and Graphics APIs to Vulkan for this build.",
conditionalValidity: buildTargetGroup => OculusSettings?.FoveatedRenderingMethod == Unity.XR.Oculus.OculusSettings.FoveationMethod.EyeTrackedFoveatedRendering
);
#endif
//[Required] Disable Graphics Jobs
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
isDone: buildTargetGroup => !PlayerSettings.graphicsJobs,
message: "Disable Graphics Jobs",
fix: buildTargetGroup => PlayerSettings.graphicsJobs = false,
fixMessage: "PlayerSettings.graphicsJobs = false"
);
//[Recommended] Set the Graphics API order for Android
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
platform: BuildTargetGroup.Android,
group: targetGroup,
isDone: buildTargetGroup =>
GetGraphicsAPIs(buildTargetGroup).Any(item =>
item == GraphicsDeviceType.OpenGLES3 || item == GraphicsDeviceType.Vulkan),
message: "Manual selection of Graphic API, favoring Vulkan (or OpenGLES3)",
fix: buildTargetGroup =>
{
var buildTarget = buildTargetGroup.GetBuildTarget();
PlayerSettings.SetUseDefaultGraphicsAPIs(buildTarget, false);
PlayerSettings.SetGraphicsAPIs(buildTarget, new[] { GraphicsDeviceType.Vulkan });
},
fixMessage: "Set Graphics APIs for this build target to Vulkan"
);
//[Required] Set the Graphics API order for Windows
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Required,
platform: BuildTargetGroup.Standalone,
group: targetGroup,
isDone: buildTargetGroup =>
GetGraphicsAPIs(buildTargetGroup).Any(item =>
item == GraphicsDeviceType.Direct3D11),
message: "Manual selection of Graphic API, favoring Direct3D11",
fix: buildTargetGroup =>
{
var buildTarget = buildTargetGroup.GetBuildTarget();
PlayerSettings.SetUseDefaultGraphicsAPIs(buildTarget, false);
PlayerSettings.SetGraphicsAPIs(buildTarget, new[] { GraphicsDeviceType.Direct3D11 });
},
fixMessage: "Set Graphics APIs for this build target to Direct3D11"
);
//[Recommended] Enable Multithreaded Rendering
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
isDone: buildTargetGroup => PlayerSettings.MTRendering &&
(buildTargetGroup != BuildTargetGroup.Android
|| PlayerSettings.GetMobileMTRendering(buildTargetGroup)),
message: "Enable Multithreaded Rendering",
fix: buildTargetGroup =>
{
PlayerSettings.MTRendering = true;
if (buildTargetGroup == BuildTargetGroup.Android)
{
PlayerSettings.SetMobileMTRendering(buildTargetGroup, true);
}
},
conditionalFixMessage: buildTargetGroup =>
buildTargetGroup == BuildTargetGroup.Android
? "PlayerSettings.MTRendering = true and PlayerSettings.SetMobileMTRendering(buildTargetGroup, true)"
: "PlayerSettings.MTRendering = true"
);
#if USING_XR_SDK_OCULUS
//[Recommended] Select Low Overhead Mode
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
conditionalValidity: buildTargetGroup =>
GetGraphicsAPIs(buildTargetGroup).Contains(GraphicsDeviceType.OpenGLES3),
group: targetGroup,
platform: BuildTargetGroup.Android,
isDone: buildTargetGroup => OculusSettings?.LowOverheadMode ?? true,
message: "Use Low Overhead Mode",
fix: buildTargetGroup =>
{
var setting = OculusSettings;
if (setting != null)
{
setting.LowOverheadMode = true;
EditorUtility.SetDirty(setting);
}
},
fixMessage: "OculusSettings.LowOverheadMode = true"
);
//[Recommended] Enable Dash Support
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
platform: BuildTargetGroup.Standalone,
isDone: buildTargetGroup => OculusSettings?.DashSupport ?? true,
message: "Enable Dash Support",
fix: buildTargetGroup =>
{
var setting = OculusSettings;
if (setting != null)
{
setting.DashSupport = true;
EditorUtility.SetDirty(setting);
}
},
fixMessage: "OculusSettings.DashSupport = true"
);
#endif
//[Recommended] Set the Display Buffer Format to 32 bit
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
isDone: buildTargetGroup =>
PlayerSettings.use32BitDisplayBuffer,
message: "Use 32Bit Display Buffer",
fix: buildTargetGroup => PlayerSettings.use32BitDisplayBuffer = true,
fixMessage: "PlayerSettings.use32BitDisplayBuffer = true"
);
//[Recommended] Set the Rendering Path to Forward
// TODO : Support Scripted Rendering Pipeline?
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
isDone: buildTargetGroup =>
EditorGraphicsSettings.GetTierSettings(buildTargetGroup, Graphics.activeTier).renderingPath ==
RenderingPath.Forward,
message: "Use Forward Rendering Path",
fix: buildTargetGroup =>
{
var renderingTier = EditorGraphicsSettings.GetTierSettings(buildTargetGroup, Graphics.activeTier);
renderingTier.renderingPath =
RenderingPath.Forward;
EditorGraphicsSettings.SetTierSettings(buildTargetGroup, Graphics.activeTier, renderingTier);
},
fixMessage: "renderingTier.renderingPath = RenderingPath.Forward"
);
//[Recommended] Set the Stereo Rendering to Instancing
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
isDone: buildTargetGroup =>
PlayerSettings.stereoRenderingPath == StereoRenderingPath.Instancing,
message: "Use Stereo Rendering Instancing",
fix: buildTargetGroup => PlayerSettings.stereoRenderingPath = StereoRenderingPath.Instancing,
fixMessage: "PlayerSettings.stereoRenderingPath = StereoRenderingPath.Instancing"
);
#if USING_URP && UNITY_2022_2_OR_NEWER
//[Recommended] When using URP, set Intermediate texture to "Auto"
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
isDone: buildTargetGroup =>
ForEachRendererData(rd => { return rd.intermediateTextureMode == IntermediateTextureMode.Auto; }),
message: "Setting the intermate texture mode to \"Always\" might have a performance impact, it is recommended to use \"Auto\"",
fix: buildTargetGroup =>
ForEachRendererData(rd => { rd.intermediateTextureMode = IntermediateTextureMode.Auto; return true; }),
fixMessage: "Set Intermediate texture to \"Auto\""
);
//[Recommended] When using URP, disable SSAO
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Recommended,
group: targetGroup,
isDone: buildTargetGroup =>
ForEachRendererData(rd =>
{
return rd.rendererFeatures.Count == 0
|| !rd.rendererFeatures.Any(
feature => feature != null && (feature.isActive && feature.GetType().Name == "ScreenSpaceAmbientOcclusion"));
}),
message: "SSAO will have some performace impact, it is recommended to disable SSAO",
fix: buildTargetGroup =>
ForEachRendererData(rd =>
{
rd.rendererFeatures.ForEach(feature =>
{
if (feature != null && feature.GetType().Name == "ScreenSpaceAmbientOcclusion")
feature.SetActive(false);
}
);
return true;
}),
fixMessage: "Disable SSAO"
);
#endif
//[Optional] Use Non-Directional Lightmaps
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Optional,
group: targetGroup,
isDone: buildTargetGroup =>
{
return LightmapSettings.lightmaps.Length == 0 ||
LightmapSettings.lightmapsMode == LightmapsMode.NonDirectional;
},
message: "Use Non-Directional lightmaps",
fix: buildTargetGroup => LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional,
fixMessage: "LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional"
);
//[Optional] Disable Realtime GI
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Optional,
group: targetGroup,
isDone: buildTargetGroup => !Lightmapping.realtimeGI,
message: "Disable Realtime Global Illumination",
fix: buildTargetGroup => Lightmapping.realtimeGI = false,
fixMessage: "Lightmapping.realtimeGI = false"
);
//[Optional] GPU Skinning
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Optional,
platform: BuildTargetGroup.Android,
group: targetGroup,
isDone: buildTargetGroup => PlayerSettings.gpuSkinning,
message: "Consider using GPU Skinning if your application is CPU bound",
fix: buildTargetGroup => PlayerSettings.gpuSkinning = true,
fixMessage: "PlayerSettings.gpuSkinning = true"
);
}
}