Browse Source

Color, depth and motion vectors are now provided as regular texture inputs to the compute shaders, by blitting them from the game camera ahead of time.

mac-autoexp
Nico de Poel 3 years ago
parent
commit
834c396321
  1. 34
      Assets/Resources/Shaders/FSR2CopyDepth.shader
  2. 10
      Assets/Resources/Shaders/FSR2CopyDepth.shader.meta
  3. 34
      Assets/Resources/Shaders/FSR2CopyMotionVectors.shader
  4. 10
      Assets/Resources/Shaders/FSR2CopyMotionVectors.shader.meta
  5. 9
      Assets/Scripts/Fsr2.cs
  6. 8
      Assets/Scripts/Fsr2Context.cs
  7. 81
      Assets/Scripts/Fsr2Controller.cs
  8. 10
      Assets/Scripts/Fsr2Pipeline.cs
  9. 7
      Assets/Scripts/SubsampleTest.cs

34
Assets/Resources/Shaders/FSR2CopyDepth.shader

@ -0,0 +1,34 @@
Shader "FSR2/FSR2CopyDepth"
{
Properties
{
_MainTex ("Texture", 2D) = "" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
HLSLPROGRAM
#include "UnityCG.cginc"
struct v2f {
float4 vertex : SV_POSITION;
float2 texCoord : TEXCOORD0;
};
#pragma vertex vert_img
#pragma fragment frag
sampler2D _CameraDepthTexture;
fixed4 frag(v2f i) : COLOR
{
return tex2D(_CameraDepthTexture, i.texCoord);
}
ENDHLSL
}
}
Fallback Off
}

10
Assets/Resources/Shaders/FSR2CopyDepth.shader.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f9861a441b68ea4409f6d6828d4ef5b2
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

34
Assets/Resources/Shaders/FSR2CopyMotionVectors.shader

@ -0,0 +1,34 @@
Shader "FSR2/CopyMotionVectors"
{
Properties
{
_MainTex ("Texture", 2D) = "" {}
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
HLSLPROGRAM
#include "UnityCG.cginc"
struct v2f {
float4 vertex : SV_POSITION;
float2 texCoord : TEXCOORD0;
};
#pragma vertex vert_img
#pragma fragment frag
sampler2D_half _CameraMotionVectorsTexture;
fixed4 frag(v2f i) : COLOR
{
return tex2D(_CameraMotionVectorsTexture, i.texCoord);
}
ENDHLSL
}
}
Fallback Off
}

10
Assets/Resources/Shaders/FSR2CopyMotionVectors.shader.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ea3aa42789e56b84db6c1326db8b6c37
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

9
Assets/Scripts/Fsr2.cs

@ -131,11 +131,10 @@ namespace FidelityFX
public class DispatchDescription public class DispatchDescription
{ {
// Texture2D Color, Depth, MotionVectors; // Will be passed using ComputeShader.SetTextureFromGlobal
public Texture2D Exposure;
public Texture2D Reactive;
public Texture2D TransparencyAndComposition;
public RenderTexture Input;
public Texture Color, Depth, MotionVectors;
public Texture Exposure;
public Texture Reactive;
public Texture TransparencyAndComposition;
public RenderTexture Output; public RenderTexture Output;
public Vector2 JitterOffset; public Vector2 JitterOffset;
public Vector2 MotionVectorScale; public Vector2 MotionVectorScale;

8
Assets/Scripts/Fsr2Context.cs

@ -230,7 +230,7 @@ namespace FidelityFX
} }
else else
{ {
_commandBuffer.Blit(dispatchParams.Input, dispatchParams.Output);
_commandBuffer.Blit(dispatchParams.Color, dispatchParams.Output);
} }
_resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames; _resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames;
@ -246,10 +246,10 @@ namespace FidelityFX
constants.jitterOffset = dispatchParams.JitterOffset; constants.jitterOffset = dispatchParams.JitterOffset;
constants.renderSize = new Vector2Int( constants.renderSize = new Vector2Int(
dispatchParams.RenderSize.x > 0 ? dispatchParams.RenderSize.x : dispatchParams.Input.width,
dispatchParams.RenderSize.y > 0 ? dispatchParams.RenderSize.y : dispatchParams.Input.height);
dispatchParams.RenderSize.x > 0 ? dispatchParams.RenderSize.x : dispatchParams.Color.width,
dispatchParams.RenderSize.y > 0 ? dispatchParams.RenderSize.y : dispatchParams.Color.height);
constants.maxRenderSize = _contextDescription.MaxRenderSize; constants.maxRenderSize = _contextDescription.MaxRenderSize;
constants.inputColorResourceDimensions = new Vector2Int(dispatchParams.Input.width, dispatchParams.Input.height);
constants.inputColorResourceDimensions = new Vector2Int(dispatchParams.Color.width, dispatchParams.Color.height);
// Compute the horizontal FOV for the shader from the vertical one // Compute the horizontal FOV for the shader from the vertical one
float aspectRatio = (float)dispatchParams.RenderSize.x / dispatchParams.RenderSize.y; float aspectRatio = (float)dispatchParams.RenderSize.x / dispatchParams.RenderSize.y;

81
Assets/Scripts/Fsr2Controller.cs

@ -36,22 +36,37 @@ public class Fsr2Controller : MonoBehaviour
private Fsr2Context _context; private Fsr2Context _context;
private readonly Fsr2.DispatchDescription _dispatchDescription = new Fsr2.DispatchDescription(); private readonly Fsr2.DispatchDescription _dispatchDescription = new Fsr2.DispatchDescription();
private RenderTexture _upscaleRT;
private RenderTexture _colorRT, _depthRT, _motionVectorsRT;
private RenderTexture _outputRT; private RenderTexture _outputRT;
private Texture2D _exposure; private Texture2D _exposure;
private Material _testMaterial;
private Material TestMaterial
private Material _copyDepthMat;
private Material CopyDepthMaterial
{
get
{
if (_copyDepthMat == null)
{
var copyDepthShader = Fsr2.GlobalCallbacks.LoadShader("Shaders/FSR2CopyDepth");
_copyDepthMat = new Material(copyDepthShader);
}
return _copyDepthMat;
}
}
private Material _copyMotionMat;
private Material CopyMotionVectorsMaterial
{ {
get get
{ {
if (_testMaterial == null)
if (_copyMotionMat == null)
{ {
var testShader = Fsr2.GlobalCallbacks.LoadShader("Shaders/FSRTest");
_testMaterial = new Material(testShader);
var copyMotionShader = Fsr2.GlobalCallbacks.LoadShader("Shaders/FSR2CopyMotionVectors");
_copyMotionMat = new Material(copyMotionShader);
} }
return _testMaterial;
return _copyMotionMat;
} }
} }
@ -70,17 +85,23 @@ public class Fsr2Controller : MonoBehaviour
RenderPipelineManager.endContextRendering += OnEndContextRendering; RenderPipelineManager.endContextRendering += OnEndContextRendering;
// TODO: destroy and recreate context on screen resolution and/or quality mode change // TODO: destroy and recreate context on screen resolution and/or quality mode change
// TODO: enable motion vector jitter cancellation or not?
_context = Fsr2.CreateContext(DisplaySize, RenderSize); _context = Fsr2.CreateContext(DisplaySize, RenderSize);
_upscaleRT = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGBHalf);
_upscaleRT.Create();
// TODO: could make these temporary RTs
_colorRT = new RenderTexture(RenderSize.x, RenderSize.y, 0, RenderTextureFormat.ARGBHalf) { name = "FSR2 Color Input" };
_colorRT.Create();
_depthRT = new RenderTexture(RenderSize.x, RenderSize.y, 0, RenderTextureFormat.RFloat) { name = "FSR2 Depth Input" };
_depthRT.Create();
_outputRT = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGBHalf);
_outputRT.enableRandomWrite = true;
_motionVectorsRT = new RenderTexture(RenderSize.x, RenderSize.y, 0, RenderTextureFormat.RGHalf) { name = "FSR2 Motion Vectors Input" };
_motionVectorsRT.Create();
_outputRT = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGBHalf) { enableRandomWrite = true }; // TODO: does this need to be a UAV?
_outputRT.Create(); _outputRT.Create();
_exposure = new Texture2D(1, 1);
_exposure.name = "FSR2 Exposure";
_exposure = new Texture2D(1, 1) { name = "FSR2 Exposure" };
_exposure.SetPixel(0, 0, Color.white); _exposure.SetPixel(0, 0, Color.white);
_exposure.Apply(); _exposure.Apply();
} }
@ -99,10 +120,22 @@ public class Fsr2Controller : MonoBehaviour
_outputRT = null; _outputRT = null;
} }
if (_upscaleRT != null)
if (_motionVectorsRT != null)
{
_motionVectorsRT.Release();
_motionVectorsRT = null;
}
if (_depthRT != null)
{ {
_upscaleRT.Release();
_upscaleRT = null;
_depthRT.Release();
_depthRT = null;
}
if (_colorRT != null)
{
_colorRT.Release();
_colorRT = null;
} }
if (_context != null) if (_context != null)
@ -114,6 +147,13 @@ public class Fsr2Controller : MonoBehaviour
RenderPipelineManager.endContextRendering -= OnEndContextRendering; RenderPipelineManager.endContextRendering -= OnEndContextRendering;
} }
public void UpdateInputResources(RenderTexture src)
{
Graphics.Blit(src, _colorRT);
Graphics.Blit(src, _depthRT, CopyDepthMaterial);
Graphics.Blit(src, _motionVectorsRT, CopyMotionVectorsMaterial);
}
// For scriptable rendering pipeline // For scriptable rendering pipeline
private void OnEndContextRendering(ScriptableRenderContext context, List<Camera> cameras) private void OnEndContextRendering(ScriptableRenderContext context, List<Camera> cameras)
{ {
@ -123,10 +163,9 @@ public class Fsr2Controller : MonoBehaviour
// For legacy built-in render pipeline // For legacy built-in render pipeline
private void OnRenderImage(RenderTexture src, RenderTexture dest) private void OnRenderImage(RenderTexture src, RenderTexture dest)
{ {
// Do a dumb upscale first
Graphics.Blit(gameCamera.targetTexture, _upscaleRT, TestMaterial);
_dispatchDescription.Input = _upscaleRT;
_dispatchDescription.Color = _colorRT;
_dispatchDescription.Depth = _depthRT;
_dispatchDescription.MotionVectors = _motionVectorsRT;
_dispatchDescription.Output = _outputRT; _dispatchDescription.Output = _outputRT;
_dispatchDescription.Exposure = _exposure; _dispatchDescription.Exposure = _exposure;
_dispatchDescription.PreExposure = 1.0f; _dispatchDescription.PreExposure = 1.0f;

10
Assets/Scripts/Fsr2Pipeline.cs

@ -151,7 +151,7 @@ namespace FidelityFX
// - How do we clear the resources that need to be cleared at dispatch? (SetBufferData) // - How do we clear the resources that need to be cleared at dispatch? (SetBufferData)
// - Shouldn't we use a ComputeBuffer for resources that are one-dimensional and clearly not image data? e.g. SPD atomic counter & Lanczos LUT data // - Shouldn't we use a ComputeBuffer for resources that are one-dimensional and clearly not image data? e.g. SPD atomic counter & Lanczos LUT data
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, new RenderTargetIdentifier(BuiltinRenderTextureType.CurrentActive));
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.Color);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavAutoExposure, _autoExposure); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavAutoExposure, _autoExposure);
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbSpd, _spdConstants, 0, Marshal.SizeOf<Fsr2.SpdConstants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbSpd, _spdConstants, 0, Marshal.SizeOf<Fsr2.SpdConstants>());
@ -174,9 +174,9 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
{ {
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, new RenderTargetIdentifier(BuiltinRenderTextureType.MotionVectors));
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputDepth, new RenderTargetIdentifier(BuiltinRenderTextureType.Depth));
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, new RenderTargetIdentifier(BuiltinRenderTextureType.CurrentActive));
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.Color);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputDepth, dispatchParams.Depth);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavDilatedMotionVectors, _dilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavDilatedMotionVectors, _dilatedMotionVectors[frameIndex]);
@ -251,7 +251,7 @@ namespace FidelityFX
{ {
// Run the RCAS sharpening filter on the upscaled image // Run the RCAS sharpening filter on the upscaled image
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvRcasInput, dispatchParams.Input);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvRcasInput, dispatchParams.Color); // TODO: should be output from accumulate pass
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output);
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>());

7
Assets/Scripts/SubsampleTest.cs

@ -113,7 +113,12 @@ public class SubsampleTest : MonoBehaviour
gameCamera.projectionMatrix = jitterTranslationMatrix * gameCamera.nonJitteredProjectionMatrix; gameCamera.projectionMatrix = jitterTranslationMatrix * gameCamera.nonJitteredProjectionMatrix;
} }
} }
private void OnRenderImage(RenderTexture src, RenderTexture dest)
{
_fsr2Controller.UpdateInputResources(src);
}
private void OnPostRender() private void OnPostRender()
{ {
gameCamera.rect = tempRect; gameCamera.rect = tempRect;

Loading…
Cancel
Save