您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
216 行
7.9 KiB
216 行
7.9 KiB
using System;
|
|
|
|
namespace UnityEngine.Rendering
|
|
{
|
|
// This must return a float in the range [0.0f...1.0f]. It is a lerp factor between min screen fraction and max screen fraction.
|
|
public delegate float PerformDynamicRes();
|
|
|
|
public enum DynamicResScalePolicyType
|
|
{
|
|
// If this is the chosen option, then the HDDynamicResolutionHandler expects the m_DynamicResMethod to return a screen percentage to.
|
|
// The value set will be clamped between the min and max percentage set on the HDRP Asset.
|
|
ReturnsPercentage,
|
|
// If this is the chosen option, then the HDDynamicResolutionHandler expects the m_DynamicResMethod to return a lerp factor t such as
|
|
// current_screen_percentage = lerp(min percentage, max percentage, t).
|
|
ReturnsMinMaxLerpFactor
|
|
}
|
|
|
|
|
|
public class DynamicResolutionHandler
|
|
{
|
|
private bool m_Enabled = false;
|
|
private float m_MinScreenFraction = 1.0f;
|
|
private float m_MaxScreenFraction = 1.0f;
|
|
private float m_CurrentFraction = 1.0f;
|
|
private float m_PrevFraction = -1.0f;
|
|
private bool m_ForcingRes = false;
|
|
private bool m_CurrentCameraRequest = true;
|
|
private bool m_ForceSoftwareFallback = false;
|
|
|
|
private float m_PrevHWScaleWidth = 1.0f;
|
|
private float m_PrevHWScaleHeight = 1.0f;
|
|
private Vector2Int m_LastScaledSize = new Vector2Int(0, 0);
|
|
|
|
private DynamicResScalePolicyType m_ScalerType = DynamicResScalePolicyType.ReturnsMinMaxLerpFactor;
|
|
|
|
// Debug
|
|
public Vector2Int cachedOriginalSize { get; private set; }
|
|
public bool hasSwitchedResolution { get; private set; }
|
|
|
|
public DynamicResUpscaleFilter filter { get; set; }
|
|
|
|
|
|
private DynamicResolutionType type;
|
|
|
|
private PerformDynamicRes m_DynamicResMethod = null;
|
|
private static DynamicResolutionHandler s_Instance = new DynamicResolutionHandler();
|
|
public static DynamicResolutionHandler instance { get { return s_Instance; } }
|
|
|
|
|
|
private DynamicResolutionHandler()
|
|
{
|
|
m_DynamicResMethod = DefaultDynamicResMethod;
|
|
filter = DynamicResUpscaleFilter.Bilinear;
|
|
|
|
}
|
|
|
|
// TODO: Eventually we will need to provide a good default implementation for this.
|
|
static public float DefaultDynamicResMethod()
|
|
{
|
|
return 1.0f;
|
|
}
|
|
|
|
private void ProcessSettings(GlobalDynamicResolutionSettings settings)
|
|
{
|
|
m_Enabled = settings.enabled;
|
|
if (!m_Enabled)
|
|
{
|
|
m_CurrentFraction = 1.0f;
|
|
}
|
|
else
|
|
{
|
|
type = settings.dynResType;
|
|
float minScreenFrac = Mathf.Clamp(settings.minPercentage / 100.0f, 0.1f, 1.0f);
|
|
m_MinScreenFraction = minScreenFrac;
|
|
float maxScreenFrac = Mathf.Clamp(settings.maxPercentage / 100.0f, m_MinScreenFraction, 3.0f);
|
|
m_MaxScreenFraction = maxScreenFrac;
|
|
|
|
filter = settings.upsampleFilter;
|
|
m_ForcingRes = settings.forceResolution;
|
|
|
|
if (m_ForcingRes)
|
|
{
|
|
float fraction = Mathf.Clamp(settings.forcedPercentage / 100.0f, 0.1f, 1.5f);
|
|
m_CurrentFraction = fraction;
|
|
}
|
|
}
|
|
}
|
|
|
|
static public void SetDynamicResScaler(PerformDynamicRes scaler, DynamicResScalePolicyType scalerType = DynamicResScalePolicyType.ReturnsMinMaxLerpFactor)
|
|
{
|
|
s_Instance.m_ScalerType = scalerType;
|
|
s_Instance.m_DynamicResMethod = scaler;
|
|
}
|
|
|
|
public void SetCurrentCameraRequest(bool cameraRequest)
|
|
{
|
|
m_CurrentCameraRequest = cameraRequest;
|
|
}
|
|
|
|
public void Update(GlobalDynamicResolutionSettings settings, Action OnResolutionChange = null)
|
|
{
|
|
ProcessSettings(settings);
|
|
|
|
if (!m_Enabled) return;
|
|
|
|
if (!m_ForcingRes)
|
|
{
|
|
if(m_ScalerType == DynamicResScalePolicyType.ReturnsMinMaxLerpFactor)
|
|
{
|
|
float currLerp = m_DynamicResMethod();
|
|
float lerpFactor = Mathf.Clamp(currLerp, 0.0f, 1.0f);
|
|
m_CurrentFraction = Mathf.Lerp(m_MinScreenFraction, m_MaxScreenFraction, lerpFactor);
|
|
}
|
|
else if(m_ScalerType == DynamicResScalePolicyType.ReturnsPercentage)
|
|
{
|
|
float percentageRequested = Mathf.Max(m_DynamicResMethod(), 5.0f);
|
|
m_CurrentFraction = Mathf.Clamp(percentageRequested / 100.0f, m_MinScreenFraction, m_MaxScreenFraction);
|
|
}
|
|
}
|
|
|
|
if (m_CurrentFraction != m_PrevFraction)
|
|
{
|
|
m_PrevFraction = m_CurrentFraction;
|
|
hasSwitchedResolution = true;
|
|
|
|
if (!m_ForceSoftwareFallback && type == DynamicResolutionType.Hardware)
|
|
{
|
|
ScalableBufferManager.ResizeBuffers(m_CurrentFraction, m_CurrentFraction);
|
|
}
|
|
|
|
OnResolutionChange();
|
|
}
|
|
else
|
|
{
|
|
// Unity can change the scale factor by itself so we need to trigger the Action if that happens as well.
|
|
if (!m_ForceSoftwareFallback && type == DynamicResolutionType.Hardware)
|
|
{
|
|
if(ScalableBufferManager.widthScaleFactor != m_PrevHWScaleWidth ||
|
|
ScalableBufferManager.heightScaleFactor != m_PrevHWScaleHeight)
|
|
{
|
|
OnResolutionChange();
|
|
}
|
|
}
|
|
hasSwitchedResolution = false;
|
|
}
|
|
|
|
m_PrevHWScaleWidth = ScalableBufferManager.widthScaleFactor;
|
|
m_PrevHWScaleHeight = ScalableBufferManager.heightScaleFactor;
|
|
}
|
|
|
|
public bool SoftwareDynamicResIsEnabled()
|
|
{
|
|
return m_CurrentCameraRequest && m_Enabled && m_CurrentFraction != 1.0f && (m_ForceSoftwareFallback || type == DynamicResolutionType.Software);
|
|
}
|
|
public bool HardwareDynamicResIsEnabled()
|
|
{
|
|
return !m_ForceSoftwareFallback && m_CurrentCameraRequest && m_Enabled && type == DynamicResolutionType.Hardware;
|
|
}
|
|
|
|
public bool RequestsHardwareDynamicResolution()
|
|
{
|
|
if (m_ForceSoftwareFallback)
|
|
return false;
|
|
|
|
return type == DynamicResolutionType.Hardware;
|
|
}
|
|
|
|
public bool DynamicResolutionEnabled()
|
|
{
|
|
return m_CurrentCameraRequest && m_Enabled && m_CurrentFraction != 1.0f;
|
|
}
|
|
|
|
public void ForceSoftwareFallback()
|
|
{
|
|
m_ForceSoftwareFallback = true;
|
|
}
|
|
|
|
public Vector2Int GetRTHandleScale(Vector2Int size)
|
|
{
|
|
cachedOriginalSize = size;
|
|
|
|
if (!m_Enabled || !m_CurrentCameraRequest)
|
|
{
|
|
return size;
|
|
}
|
|
|
|
float scaleFractionX = m_CurrentFraction;
|
|
float scaleFractionY = m_CurrentFraction;
|
|
if (!m_ForceSoftwareFallback && type == DynamicResolutionType.Hardware)
|
|
{
|
|
scaleFractionX = ScalableBufferManager.widthScaleFactor;
|
|
scaleFractionY = ScalableBufferManager.heightScaleFactor;
|
|
}
|
|
|
|
Vector2Int scaledSize = new Vector2Int(Mathf.CeilToInt(size.x * scaleFractionX), Mathf.CeilToInt(size.y * scaleFractionY));
|
|
if (m_ForceSoftwareFallback || type != DynamicResolutionType.Hardware)
|
|
{
|
|
scaledSize.x += (1 & scaledSize.x);
|
|
scaledSize.y += (1 & scaledSize.y);
|
|
}
|
|
m_LastScaledSize = scaledSize;
|
|
|
|
return scaledSize;
|
|
}
|
|
|
|
public float GetCurrentScale()
|
|
{
|
|
return (m_Enabled && m_CurrentCameraRequest) ? m_CurrentFraction : 1.0f;
|
|
}
|
|
|
|
public Vector2Int GetLastScaledSize()
|
|
{
|
|
return m_LastScaledSize;
|
|
}
|
|
}
|
|
}
|