Browse Source

Implemented screen scaling through camera viewport manipulation, done through the helper's LateUpdate.

This also led to some reorganization of variables and event ordering.
Added some bloom to the post-process layer to test the cooperation between FSR2 and other post effects.
mac-autoexp
Nico de Poel 3 years ago
parent
commit
416b501c15
  1. 2
      Assets/Scenes/SampleScenePPV2.unity
  2. 66
      Assets/Scenes/SampleScenePPV2_Profiles/Main Camera Profile.asset
  3. 2
      Assets/Scripts/Fsr2ImageEffect.cs
  4. 98
      Assets/Scripts/Fsr2PostProcessEffect.cs

2
Assets/Scenes/SampleScenePPV2.unity

@ -152,7 +152,7 @@ Light:
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Intensity: 3
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208

66
Assets/Scenes/SampleScenePPV2_Profiles/Main Camera Profile.asset

@ -14,6 +14,54 @@ MonoBehaviour:
m_EditorClassIdentifier:
settings:
- {fileID: 3185594499184808736}
- {fileID: 318921389242660834}
--- !u!114 &318921389242660834
MonoBehaviour:
m_ObjectHideFlags: 3
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 48a79b01ea5641d4aa6daa2e23605641, type: 3}
m_Name: Bloom
m_EditorClassIdentifier:
active: 1
enabled:
overrideState: 1
value: 1
intensity:
overrideState: 1
value: 2
threshold:
overrideState: 1
value: 1
softKnee:
overrideState: 0
value: 0.5
clamp:
overrideState: 0
value: 65472
diffusion:
overrideState: 1
value: 4
anamorphicRatio:
overrideState: 0
value: 0
color:
overrideState: 0
value: {r: 1, g: 1, b: 1, a: 1}
fastMode:
overrideState: 0
value: 0
dirtTexture:
overrideState: 0
value: {fileID: 0}
defaultState: 1
dirtIntensity:
overrideState: 0
value: 0
--- !u!114 &3185594499184808736
MonoBehaviour:
m_ObjectHideFlags: 3
@ -33,6 +81,24 @@ MonoBehaviour:
qualityMode:
overrideState: 0
value: 2
performSharpenPass:
overrideState: 0
value: 1
sharpness:
overrideState: 0
value: 0.8
enableFP16:
overrideState: 0
value: 0
enableAutoExposure:
overrideState: 0
value: 1
preExposure:
overrideState: 0
value: 1
autoGenerateReactiveMask:
overrideState: 0
value: 1
--- !u!114 &4429786910217829299
MonoBehaviour:
m_ObjectHideFlags: 3

2
Assets/Scripts/Fsr2ImageEffect.cs

@ -105,7 +105,7 @@ namespace FidelityFX
_renderCamera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, _opaqueInputCommandBuffer);
}
// Apply a mipmap bias so that textures retain their original sharpness
// Apply a mipmap bias so that textures retain their sharpness
float biasOffset = Fsr2.GetMipmapBiasOffset(_renderSize.x, _displaySize.x);
Fsr2.GlobalCallbacks.ApplyMipmapBias(biasOffset);

98
Assets/Scripts/Fsr2PostProcessEffect.cs

@ -42,10 +42,11 @@ namespace FidelityFX
private Fsr2Context _fsrContext;
private Fsr2PostProcessHelper _helper;
private Vector2Int _displaySize;
private Vector2Int _renderSize;
private ref Vector2Int DisplaySize => ref _helper.DisplaySize;
private ref Vector2Int RenderSize => ref _helper.RenderSize;
private Fsr2.QualityMode _prevQualityMode;
private Vector2Int _prevDisplaySize;
public override void Init()
{
@ -77,16 +78,6 @@ namespace FidelityFX
return;
}
// Monitor for any resolution changes and recreate the FSR2 context if necessary
// We can't create an FSR2 context without info from the post-processing context, so delay the initial setup until here
if (_fsrContext == null || context.screenWidth != _displaySize.x || context.screenHeight != _displaySize.y || settings.qualityMode != _prevQualityMode)
{
DestroyFsrContext();
CreateFsrContext(context);
_prevQualityMode = settings.qualityMode;
}
// Ensure that the helper script exists and is enabled
if (_helper == null || !_helper.enabled)
{
@ -99,6 +90,16 @@ namespace FidelityFX
cmd.BlitFullscreenTriangle(context.source, context.destination);
return;
}
// Monitor for any resolution changes and recreate the FSR2 context if necessary
// We can't create an FSR2 context without info from the post-processing context, so delay the initial setup until here
if (_fsrContext == null || DisplaySize.x != _prevDisplaySize.x || DisplaySize.y != _prevDisplaySize.y || settings.qualityMode != _prevQualityMode)
{
DestroyFsrContext();
CreateFsrContext(context);
_prevQualityMode = settings.qualityMode;
}
//Debug.Log("[FSR2] Render, where am I being called from?"); // In OnPreCull... OH
// TODO: executing in OnPreCull means we can do jittering in here, at least. Rect manipulation should still happen before PPV2 entirely.
@ -122,9 +123,10 @@ namespace FidelityFX
private void CreateFsrContext(PostProcessRenderContext context)
{
_displaySize = new Vector2Int(context.screenWidth, context.screenHeight);
Fsr2.GetRenderResolutionFromQualityMode(out var renderWidth, out var renderHeight, _displaySize.x, _displaySize.y, settings.qualityMode);
_renderSize = new Vector2Int(renderWidth, renderHeight);
_prevDisplaySize = DisplaySize;
Fsr2.GetRenderResolutionFromQualityMode(out var renderWidth, out var renderHeight, DisplaySize.x, DisplaySize.y, settings.qualityMode);
RenderSize = new Vector2Int(renderWidth, renderHeight);
Fsr2.InitializationFlags flags = 0;
if (context.camera.allowHDR) flags |= Fsr2.InitializationFlags.EnableHighDynamicRange;
@ -135,7 +137,11 @@ namespace FidelityFX
flags |= Fsr2.InitializationFlags.EnableDebugChecking;
#endif
_fsrContext = Fsr2.CreateContext(_displaySize, _renderSize, flags);
_fsrContext = Fsr2.CreateContext(DisplaySize, RenderSize, flags);
// Apply a mipmap bias so that textures retain their sharpness
float biasOffset = Fsr2.GetMipmapBiasOffset(RenderSize.x, DisplaySize.x);
Fsr2.GlobalCallbacks.ApplyMipmapBias(biasOffset);
}
private void DestroyFsrContext()
@ -144,17 +150,21 @@ namespace FidelityFX
{
_fsrContext.Destroy();
_fsrContext = null;
// Undo the previous mipmap bias adjustment
float biasOffset = Fsr2.GetMipmapBiasOffset(RenderSize.x, _prevDisplaySize.x);
Fsr2.GlobalCallbacks.ApplyMipmapBias(-biasOffset);
}
}
private void ApplyJitter(Camera camera)
{
// 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(RenderSize.x, DisplaySize.x);
Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount);
jitterX = 2.0f * jitterX / _renderSize.x;
jitterY = 2.0f * jitterY / _renderSize.y;
jitterX = 2.0f * jitterX / RenderSize.x;
jitterY = 2.0f * jitterY / RenderSize.y;
var jitterTranslationMatrix = Matrix4x4.Translate(new Vector3(jitterX, jitterY, 0));
camera.nonJitteredProjectionMatrix = camera.projectionMatrix;
@ -166,25 +176,63 @@ namespace FidelityFX
internal class Fsr2PostProcessHelper : MonoBehaviour
{
internal Fsr2PostProcessEffect Settings;
internal Vector2Int DisplaySize;
internal Vector2Int RenderSize;
private Camera _camera;
private Rect _originalRect;
private void Awake()
{
_camera = GetComponent<Camera>();
// TODO: inject opaque-only command buffer & anything else?
DisplaySize.x = _camera.pixelWidth;
DisplaySize.y = _camera.pixelHeight;
RenderSize = DisplaySize;
}
private void OnPreCull() // TODO: may need to do this in LateUpdate instead? So we execute before PPV2's OnPreCull
private void Start()
{
StartCoroutine(CResetCamera());
}
/// <summary>
/// This needs to run before PostProcessLayer's OnPreCull, hence why we place this code in LateUpdate.
/// </summary>
private void LateUpdate()
{
// TODO: check if FSR2 is still enabled; if not: reset PPV2 source texture & disable self
// TODO: fiddle with the camera parameters, rect, jitter, etc
// Debug.Log("[FSR2] OnPreCull");
if (!Settings.enabled)
{
enabled = false;
return;
}
// Relay information about the camera's output size before rescaling
DisplaySize.x = _camera.pixelWidth;
DisplaySize.y = _camera.pixelHeight;
// Render to a smaller portion of the screen by manipulating the camera's viewport rect
_originalRect = _camera.rect;
_camera.aspect = (_camera.pixelWidth * _originalRect.width) / (_camera.pixelHeight * _originalRect.height);
_camera.rect = new Rect(0, 0, _originalRect.width * RenderSize.x / DisplaySize.x, _originalRect.height * RenderSize.y / DisplaySize.y);
}
private void OnPostRender()
// private void OnPreCull() // TODO: may need to do this in LateUpdate instead? So we execute before PPV2's OnPreCull
// {
// // TODO: check if FSR2 is still enabled; if not: reset PPV2 source texture & disable self
// // TODO: fiddle with the camera parameters, rect, jitter, etc
// }
private IEnumerator CResetCamera()
{
_camera.ResetProjectionMatrix();
while (true)
{
yield return new WaitForEndOfFrame();
_camera.rect = _originalRect;
_camera.ResetProjectionMatrix();
}
}
}
}

Loading…
Cancel
Save