You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
4.9 KiB
108 lines
4.9 KiB
using System.Runtime.InteropServices;
|
|
using FidelityFX;
|
|
using UnityEngine.Experimental.Rendering;
|
|
|
|
namespace UnityEngine.Rendering.PostProcessing
|
|
{
|
|
internal abstract class SGSR2Upscaler: Upscaler
|
|
{
|
|
public static bool IsSupported => SystemInfo.supportsComputeShaders;
|
|
|
|
protected abstract string VariantName { get; }
|
|
|
|
protected RenderTexture _colorLuma;
|
|
protected RenderTexture _motionDepthAlpha;
|
|
protected RenderTexture _motionDepthClipAlpha;
|
|
protected readonly RenderTexture[] _lumaHistory = new RenderTexture[2];
|
|
protected readonly RenderTexture[] _upscaleHistory = new RenderTexture[2];
|
|
|
|
protected readonly ConstantsBuffer<SGSR2.Params> _paramsBuffer = new();
|
|
|
|
protected uint _frameCount = 0;
|
|
|
|
public override void CreateContext(PostProcessRenderContext context, Upscaling config)
|
|
{
|
|
CreateRenderTexture(ref _colorLuma, "ColorLuma", config.MaxRenderSize, GraphicsFormat.R32_UInt, true);
|
|
CreateRenderTexture(ref _motionDepthAlpha, "MotionDepthAlpha", config.MaxRenderSize, GraphicsFormat.R16G16B16A16_SFloat, true);
|
|
CreateRenderTexture(ref _motionDepthClipAlpha, "MotionDepthClipAlpha", config.MaxRenderSize, GraphicsFormat.R16G16B16A16_SFloat, true);
|
|
CreateRenderTextureArray(_lumaHistory, "LumaHistory", config.MaxRenderSize, GraphicsFormat.R32_UInt, true);
|
|
CreateRenderTextureArray(_upscaleHistory, "History", config.UpscaleSize, context.sourceFormat, true);
|
|
|
|
_paramsBuffer.Init();
|
|
}
|
|
|
|
public override void DestroyContext()
|
|
{
|
|
base.DestroyContext();
|
|
|
|
_paramsBuffer.Destroy();
|
|
|
|
DestroyRenderTextureArray(_upscaleHistory);
|
|
DestroyRenderTextureArray(_lumaHistory);
|
|
DestroyRenderTexture(ref _motionDepthClipAlpha);
|
|
DestroyRenderTexture(ref _motionDepthAlpha);
|
|
DestroyRenderTexture(ref _colorLuma);
|
|
}
|
|
|
|
public override void Render(PostProcessRenderContext context, Upscaling config)
|
|
{
|
|
var cmd = context.command;
|
|
cmd.BeginSample(VariantName);
|
|
|
|
Matrix4x4 clipToPrevClip = Matrix4x4.identity;
|
|
bool isCameraStill = false;
|
|
if (_frameCount > 0 && !config.Reset)
|
|
{
|
|
// We need to use the projection matrix as it is used on the GPU to match what Unity keeps in Camera.previousViewProjectionMatrix
|
|
Matrix4x4 viewProj = GL.GetGPUProjectionMatrix(context.camera.nonJitteredProjectionMatrix, true) * context.camera.worldToCameraMatrix;
|
|
clipToPrevClip = context.camera.previousViewProjectionMatrix * viewProj.inverse;
|
|
isCameraStill = IsCameraStill(viewProj, context.camera.previousViewProjectionMatrix);
|
|
}
|
|
|
|
ref var parms = ref _paramsBuffer.Value;
|
|
parms.renderSize = config.GetScaledRenderSize(context.camera);
|
|
parms.displaySize = config.UpscaleSize;
|
|
parms.renderSizeRcp = new Vector2(1.0f / parms.renderSize.x, 1.0f / parms.renderSize.y);
|
|
parms.displaySizeRcp = new Vector2(1.0f / parms.displaySize.x, 1.0f / parms.displaySize.y);
|
|
parms.jitterOffset = config.JitterOffset;
|
|
parms.clipToPrevClip = clipToPrevClip;
|
|
parms.preExposure = config.preExposure;
|
|
parms.cameraFovAngleHor = Mathf.Tan(context.camera.fieldOfView * Mathf.Deg2Rad * 0.5f) * (float)parms.renderSize.x / parms.renderSize.y;
|
|
parms.cameraNear = context.camera.nearClipPlane;
|
|
parms.minLerpContribution = 0f;
|
|
parms.bSameCamera = isCameraStill ? 1u : 0u;
|
|
parms.reset = config.Reset ? 1u : 0u;
|
|
_paramsBuffer.UpdateBufferData(cmd);
|
|
|
|
if (_frameCount == 0 || config.Reset)
|
|
{
|
|
cmd.SetRenderTarget(_lumaHistory[0]);
|
|
cmd.ClearRenderTarget(false, true, Color.clear);
|
|
cmd.SetRenderTarget(_lumaHistory[1]);
|
|
cmd.ClearRenderTarget(false, true, Color.clear);
|
|
cmd.SetRenderTarget(_upscaleHistory[0]);
|
|
cmd.ClearRenderTarget(false, true, Color.clear);
|
|
cmd.SetRenderTarget(_upscaleHistory[1]);
|
|
cmd.ClearRenderTarget(false, true, Color.clear);
|
|
}
|
|
|
|
DoRender(cmd, context, config);
|
|
|
|
cmd.EndSample(VariantName);
|
|
_frameCount++;
|
|
}
|
|
|
|
protected abstract void DoRender(CommandBuffer cmd, PostProcessRenderContext context, Upscaling config);
|
|
|
|
private static bool IsCameraStill(in Matrix4x4 currViewProj, in Matrix4x4 prevViewProj, float threshold = 1e-5f)
|
|
{
|
|
float vpDiff = 0f;
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
vpDiff += Mathf.Abs(currViewProj[i] - prevViewProj[i]);
|
|
}
|
|
|
|
return vpDiff < threshold;
|
|
}
|
|
}
|
|
}
|