using UnityEngine.Rendering; namespace UnityEngine.AdaptivePerformance { /// /// A scaler used by to adjust the resolution of all render targets that allow dynamic resolution. /// If a device or graphics API doesn't support a dynamic resolution, it will use the rendering pipeline's render scale multiplier as a fallback. /// public class AdaptiveResolution : AdaptivePerformanceScaler { static int instanceCount = 0; /// /// Ensures settings are applied during startup. /// protected override void Awake() { base.Awake(); if (m_Settings == null) return; ApplyDefaultSetting(m_Settings.scalerSettings.AdaptiveResolution); } /// /// Callback when scaler gets disabled and removed from indexer /// protected override void OnDisabled() { OnDestroy(); } /// /// Callback when scaler gets enabled and added to the indexer /// protected override void OnEnabled() {} void OnValidate() { if (MaxLevel < 1) MaxLevel = 1; MaxBound = Mathf.Clamp(MaxBound, 0.25f, 1.0f); MinBound = Mathf.Clamp(MinBound, 0.25f, MaxBound); } // TODO: expose dynamicResolution capability through SystemInfo private bool IsDynamicResolutionSupported() { #if UNITY_XBOXONE || UNITY_PS4 || UNITY_SWITCH || UNITY_IOS || UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN return true; #elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_TVOS // metal only return SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal; #elif UNITY_ANDROID return SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan; #elif UNITY_WSA return SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12; #else return false; #endif } private void Start() { ++instanceCount; if (instanceCount > 1) Debug.LogWarning("Multiple Adaptive Resolution scalers created. They will interfere with each other."); if (!IsDynamicResolutionSupported()) Debug.Log(string.Format("Dynamic resolution is not supported. Will be using fallback to Render Scale Multiplier.")); } private void OnDestroy() { --instanceCount; if (Scale == 1.0f) return; APLog.Debug("Restoring dynamic resolution scale factor to 1.0"); if (IsDynamicResolutionSupported()) ScalableBufferManager.ResizeBuffers(1.0f, 1.0f); else AdaptivePerformanceRenderSettings.RenderScaleMultiplier = 1.0f; } /// /// Callback for any level change /// protected override void OnLevel() { var scaleChange = ScaleChanged(); // if Gfx API does not support Dynamic resolution, currentCamera.allowDynamicResolution will be false if (IsDynamicResolutionSupported()) { if (scaleChange) ScalableBufferManager.ResizeBuffers(Scale, Scale); int rezWidth = (int)Mathf.Ceil(ScalableBufferManager.widthScaleFactor * Screen.currentResolution.width); int rezHeight = (int)Mathf.Ceil(ScalableBufferManager.heightScaleFactor * Screen.currentResolution.height); APLog.Debug( $"Adaptive Resolution Scale: {Scale:F3} Resolution: {rezWidth}x{rezHeight} ScaleFactor: {ScalableBufferManager.widthScaleFactor:F3}x{ScalableBufferManager.heightScaleFactor:F3} Level:{CurrentLevel}/{MaxLevel}"); } else { AdaptivePerformanceRenderSettings.RenderScaleMultiplier = Scale; APLog.Debug($"Dynamic resolution is not supported. Using fallback to Render Scale Multiplier : {Scale:F3}"); // TODO: warn if unsupported render pipeline is used //Debug.Log("You might not use a supported Render Pipeline. Currently only Universal Render Pipeline and Built-in are supported by Adaptive Resolution."); } } } }