Browse Source

Implemented dynamic scaling through a custom scale factor. No ScalableBufferManager involved. Doesn't work nicely with MSVO AO, but otherwise does the job.

fsr2
Nico de Poel 3 years ago
parent
commit
4707ce8364
  1. 8
      Assets/Scripts/DebugDumper.cs
  2. 47
      Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/SuperResolution.cs

8
Assets/Scripts/DebugDumper.cs

@ -46,6 +46,7 @@ public class DebugDumper : MonoBehaviour
Debug.Log(sb);
_layer = GetComponent<PostProcessLayer>();
_layer.superResolution.dynamicScale = _scaleFactor;
}
void Update()
@ -84,11 +85,12 @@ public class DebugDumper : MonoBehaviour
}
float vertical = Input.GetAxis("Vertical");
if (vertical is < -0.3f or > 0.3f && Time.realtimeSinceStartup > _lastScaleTime + 0.5f)
if (vertical is < -0.3f or > 0.3f && Time.realtimeSinceStartup > _lastScaleTime + 0.3f)
{
_scaleFactor += 0.1f * Math.Sign(vertical);
_scaleFactor += 0.05f * Math.Sign(vertical);
_scaleFactor = Mathf.Clamp(_scaleFactor, 0.1f, 1.0f);
_layer.superResolution.dynamicScale = _scaleFactor;
_lastScaleTime = Time.realtimeSinceStartup;
}
}
@ -107,7 +109,7 @@ public class DebugDumper : MonoBehaviour
GUILayout.Label($"FSR2: {(_layer.antialiasingMode == PostProcessLayer.Antialiasing.SuperResolution ? "Enabled" : "Disabled")}");
GUILayout.Label($"Quality: {_layer.superResolution.qualityMode}");
GUILayout.Label($"Auto-exposure: {(_layer.superResolution.exposureSource)}");
GUILayout.Label($"Scale: {_scaleFactor:0.00}");
GUILayout.Label($"Scale: {_layer.superResolution.dynamicScale:0.00}");
if (Input.GetButton("Jump"))
{
GUILayout.Label("Reset");

47
Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/SuperResolution.cs

@ -99,13 +99,14 @@ namespace UnityEngine.Rendering.PostProcessing
[Range(0, 1)] public float autoReactiveMax = 0.9f;
}
public float dynamicScale { get; set; } = 1.0f;
public Vector2 jitter { get; private set; }
public Vector2Int renderSize => _renderSize;
public Vector2Int renderSize => GetScaledRenderSize();
public Vector2Int displaySize => _displaySize;
public RenderTargetIdentifier colorOpaqueOnly { get; set; }
private Fsr2Context _fsrContext;
private Vector2Int _renderSize;
private Vector2Int _maxRenderSize;
private Vector2Int _displaySize;
private bool _resetHistory;
@ -153,12 +154,13 @@ namespace UnityEngine.Rendering.PostProcessing
// Determine the desired rendering and display resolutions
_displaySize = new Vector2Int(camera.pixelWidth, camera.pixelHeight);
Fsr2.GetRenderResolutionFromQualityMode(out int renderWidth, out int renderHeight, _displaySize.x, _displaySize.y, qualityMode);
_renderSize = new Vector2Int(renderWidth, renderHeight);
Fsr2.GetRenderResolutionFromQualityMode(out int maxRenderWidth, out int maxRenderHeight, _displaySize.x, _displaySize.y, qualityMode);
_maxRenderSize = new Vector2Int(maxRenderWidth, maxRenderHeight);
// Render to a smaller portion of the screen by manipulating the camera's viewport rect
var scaledRenderSize = GetScaledRenderSize();
camera.aspect = (_displaySize.x * _originalRect.width) / (_displaySize.y * _originalRect.height);
camera.rect = new Rect(0, 0, _originalRect.width * _renderSize.x / _displaySize.x, _originalRect.height * _renderSize.y / _displaySize.y);
camera.rect = new Rect(0, 0, _originalRect.width * scaledRenderSize.x / _displaySize.x, _originalRect.height * scaledRenderSize.y / _displaySize.y);
}
public void ResetCameraViewport(PostProcessRenderContext context)
@ -189,7 +191,8 @@ namespace UnityEngine.Rendering.PostProcessing
{
SetupAutoReactiveDescription(context);
cmd.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, _renderSize.x, _renderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true);
var scaledRenderSize = _genReactiveDescription.RenderSize;
cmd.GetTemporaryRT(Fsr2ShaderIDs.UavAutoReactive, scaledRenderSize.x, scaledRenderSize.y, 0, default, GraphicsFormat.R8_UNorm, 1, true);
_fsrContext.GenerateReactiveMask(_genReactiveDescription, cmd);
_dispatchDescription.Reactive = Fsr2ShaderIDs.UavAutoReactive;
}
@ -214,10 +217,10 @@ namespace UnityEngine.Rendering.PostProcessing
if (exposureSource == ExposureSource.Auto) flags |= Fsr2.InitializationFlags.EnableAutoExposure;
_callbacks = callbacksFactory(context);
_fsrContext = Fsr2.CreateContext(_displaySize, _renderSize, _callbacks, flags);
_fsrContext = Fsr2.CreateContext(_displaySize, _maxRenderSize, _callbacks, flags);
// Apply a mipmap bias so that textures retain their sharpness
float biasOffset = Fsr2.GetMipmapBiasOffset(_renderSize.x, _displaySize.x);
float biasOffset = Fsr2.GetMipmapBiasOffset(_maxRenderSize.x, _displaySize.x);
if (!float.IsNaN(biasOffset) && !float.IsInfinity(biasOffset))
{
_callbacks.ApplyMipmapBias(biasOffset);
@ -247,14 +250,16 @@ namespace UnityEngine.Rendering.PostProcessing
private void ApplyJitter(Camera camera)
{
var scaledRenderSize = GetScaledRenderSize();
// Perform custom jittering of the camera's projection matrix according to FSR2's recipe
int jitterPhaseCount = Fsr2.GetJitterPhaseCount(_renderSize.x, _displaySize.x);
int jitterPhaseCount = Fsr2.GetJitterPhaseCount(scaledRenderSize.x, _displaySize.x);
Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount);
_dispatchDescription.JitterOffset = new Vector2(jitterX, jitterY);
jitterX = 2.0f * jitterX / _renderSize.x;
jitterY = 2.0f * jitterY / _renderSize.y;
jitterX = 2.0f * jitterX / scaledRenderSize.x;
jitterY = 2.0f * jitterY / scaledRenderSize.y;
var jitterTranslationMatrix = Matrix4x4.Translate(new Vector3(jitterX, jitterY, 0));
camera.nonJitteredProjectionMatrix = camera.projectionMatrix;
@ -282,14 +287,16 @@ namespace UnityEngine.Rendering.PostProcessing
if (reactiveMask != null) _dispatchDescription.Reactive = reactiveMask;
if (transparencyAndCompositionMask != null) _dispatchDescription.TransparencyAndComposition = transparencyAndCompositionMask;
var scaledRenderSize = GetScaledRenderSize();
_dispatchDescription.Output = context.destination;
_dispatchDescription.PreExposure = preExposure;
_dispatchDescription.EnableSharpening = performSharpenPass;
_dispatchDescription.Sharpness = sharpness;
_dispatchDescription.MotionVectorScale.x = -_renderSize.x;
_dispatchDescription.MotionVectorScale.y = -_renderSize.y;
_dispatchDescription.RenderSize = _renderSize;
_dispatchDescription.InputResourceSize = _renderSize; // TODO: this may need to be maxRenderSize to support dynamic resolution
_dispatchDescription.MotionVectorScale.x = -scaledRenderSize.x;
_dispatchDescription.MotionVectorScale.y = -scaledRenderSize.y;
_dispatchDescription.RenderSize = scaledRenderSize;
_dispatchDescription.InputResourceSize = scaledRenderSize;
_dispatchDescription.FrameTimeDelta = Time.unscaledDeltaTime;
_dispatchDescription.CameraNear = camera.nearClipPlane;
_dispatchDescription.CameraFar = camera.farClipPlane;
@ -321,13 +328,21 @@ namespace UnityEngine.Rendering.PostProcessing
_genReactiveDescription.ColorOpaqueOnly = colorOpaqueOnly;
_genReactiveDescription.ColorPreUpscale = null;
_genReactiveDescription.OutReactive = null;
_genReactiveDescription.RenderSize = _renderSize;
_genReactiveDescription.RenderSize = GetScaledRenderSize();
_genReactiveDescription.Scale = generateReactiveParameters.scale;
_genReactiveDescription.CutoffThreshold = generateReactiveParameters.cutoffThreshold;
_genReactiveDescription.BinaryValue = generateReactiveParameters.binaryValue;
_genReactiveDescription.Flags = generateReactiveParameters.flags;
}
private Vector2Int GetScaledRenderSize()
{
if (Mathf.Approximately(dynamicScale, 1.0f))
return _maxRenderSize;
return new Vector2Int(Mathf.CeilToInt(_maxRenderSize.x * dynamicScale), Mathf.CeilToInt(_maxRenderSize.y * dynamicScale));
}
private class Callbacks : Fsr2CallbacksBase
{
private readonly PostProcessResources _resources;

Loading…
Cancel
Save