Browse Source

- Implemented main FSR2 constants buffer, which now supplies the pre-exposure value to the RCAS shader.

- Converted thread groups calculation from FSR2 code
mac-autoexp
Nico de Poel 3 years ago
parent
commit
79d8aa49b6
  1. 3
      Assets/Resources/Shaders/ffx_fsr2_callbacks_hlsl.h
  2. 89
      Assets/Scripts/FSR2Thing.cs
  3. 3
      Assets/Scripts/SubsampleTest.cs

3
Assets/Resources/Shaders/ffx_fsr2_callbacks_hlsl.h

@ -482,8 +482,7 @@ FfxFloat32 SampleTransparencyAndCompositionMask(FfxFloat32x2 fUV)
FfxFloat32 PreExposure()
{
//return fPreExposure;
return 1.0f;
return fPreExposure;
}
FfxFloat32x3 LoadInputColor(FfxUInt32x2 iPxPos)

89
Assets/Scripts/FSR2Thing.cs

@ -50,7 +50,7 @@ public class FSR2Thing : MonoBehaviour
{
if (_rcasComputeShader == null)
{
// TODO: this is nasty, I don't like this. How do we manage/bind compute shaders best?
// TODO: this is nasty, I don't like this. How do we manage/bind compute shaders best? => make a Callbacks class/interface with overridable implementation
// GPUInstancer used Resources, we modified that to load stuff from asset bundles instead. Maybe provide a custom loader callback interface?
_rcasComputeShader = Resources.Load<ComputeShader>("Shaders/ffx_fsr2_rcas_pass");
}
@ -59,8 +59,11 @@ public class FSR2Thing : MonoBehaviour
}
}
private ComputeBuffer _rcasConstantBuffer;
private RcasConfig[] _rcasConfig = new RcasConfig[1];
private ComputeBuffer _fsr2ConstantsBuffer;
private readonly Fsr2Constants[] _fsr2ConstantsArray = { new Fsr2Constants() };
private ComputeBuffer _rcasConstantsBuffer;
private readonly RcasConstants[] _rcasConstantsArray = new RcasConstants[1];
private void OnEnable()
{
@ -77,16 +80,23 @@ public class FSR2Thing : MonoBehaviour
_exposure.name = "FSR2 Exposure";
_exposure.SetPixel(0, 0, Color.white);
_exposure.Apply();
_rcasConstantBuffer = new ComputeBuffer(1, Marshal.SizeOf<RcasConfig>(), ComputeBufferType.Constant);
_fsr2ConstantsBuffer = new ComputeBuffer(1, Marshal.SizeOf<Fsr2Constants>(), ComputeBufferType.Constant);
_rcasConstantsBuffer = new ComputeBuffer(1, Marshal.SizeOf<RcasConstants>(), ComputeBufferType.Constant);
}
private void OnDisable()
{
if (_rcasConstantBuffer != null)
if (_rcasConstantsBuffer != null)
{
_rcasConstantBuffer.Release();
_rcasConstantBuffer = null;
_rcasConstantsBuffer.Release();
_rcasConstantsBuffer = null;
}
if (_fsr2ConstantsBuffer != null)
{
_fsr2ConstantsBuffer.Release();
_fsr2ConstantsBuffer = null;
}
if (_exposure != null)
@ -122,20 +132,28 @@ public class FSR2Thing : MonoBehaviour
// Do a dumb upscale first
Graphics.Blit(gameCamera.targetTexture, _upscaleRT, TestMaterial);
_fsr2ConstantsArray[0].preExposure = 1.0f;
_fsr2ConstantsBuffer.SetData(_fsr2ConstantsArray);
if (performSharpenPass)
{
int sharpnessIndex = Mathf.RoundToInt(Mathf.Clamp01(sharpness) * (RcasConfigs.Count - 1));
_rcasConfig[0] = RcasConfigs[sharpnessIndex];
_rcasConstantBuffer.SetData(_rcasConfig);
_rcasConstantsArray[0] = RcasConfigs[sharpnessIndex];
_rcasConstantsBuffer.SetData(_rcasConstantsArray);
// Run the RCAS sharpening filter on the upscaled image
int rcasKernel = RCASComputeShader.FindKernel("CS");
// TODO: create constant buffer (cbFSR2) with fPreExposure set to 1.0
RCASComputeShader.SetTexture(rcasKernel, "r_exposure", _exposure);
RCASComputeShader.SetTexture(rcasKernel, "r_rcas_input", _upscaleRT);
RCASComputeShader.SetTexture(rcasKernel, "rw_upscaled_output", _rcasOutput);
RCASComputeShader.SetConstantBuffer("cbRCAS", _rcasConstantBuffer, 0, Marshal.SizeOf<RcasConfig>());
RCASComputeShader.Dispatch(rcasKernel, Screen.width, Screen.height, 1); // TODO: not sure how these thread groups work...
RCASComputeShader.SetConstantBuffer("cbFSR2", _fsr2ConstantsBuffer, 0, Marshal.SizeOf<Fsr2Constants>());
RCASComputeShader.SetConstantBuffer("cbRCAS", _rcasConstantsBuffer, 0, Marshal.SizeOf<RcasConstants>());
const int threadGroupWorkRegionDimRcas = 16;
int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
RCASComputeShader.Dispatch(rcasKernel, threadGroupsX, threadGroupsY, 1);
// Output sharpened image to screen
Graphics.Blit(_rcasOutput, dest);
@ -146,23 +164,50 @@ public class FSR2Thing : MonoBehaviour
}
}
[Serializable]
private struct RcasConfig
[Serializable, StructLayout(LayoutKind.Sequential)]
private struct RcasConstants
{
public RcasConfig(uint sharpness, uint halfSharp)
public RcasConstants(uint sharpness, uint halfSharp)
{
this.sharpness = sharpness;
this.halfSharp = halfSharp;
dummy0 = dummy1 = 0;
}
public uint sharpness;
public uint halfSharp;
public uint dummy0;
public uint dummy1;
public readonly uint sharpness;
public readonly uint halfSharp;
public readonly uint dummy0;
public readonly uint dummy1;
}
private static readonly List<RcasConfig> RcasConfigs = new()
[Serializable, StructLayout(LayoutKind.Sequential)]
private struct Fsr2Constants
{
public Vector2Int renderSize;
public Vector2Int displaySize;
public uint lumaMipDimensionsX, lumaMipDimensionsY;
public uint lumaMipLevelToUse;
public uint frameIndex;
public Vector2 displaySizeRcp;
public Vector2 jitterOffset;
public Vector4 deviceToViewDepth;
public Vector2 depthClipUVScale;
public Vector2 postLockStatusUVScale;
public Vector2 reactiveMaskDimRcp;
public Vector2 motionVectorScale;
public Vector2 downscaleFactor;
public float preExposure;
public float tanHalfFOV;
public Vector2 motionVectorJitterCancellation;
public float jitterPhaseCount;
public float lockInitialLifetime;
public float lockTickDelta;
public float deltaTime;
public float dynamicResChangeFactor;
public float lumaMipRcp;
}
private static readonly List<RcasConstants> RcasConfigs = new()
{
new(1048576000u, 872428544u),
new(1049178080u, 877212745u),

3
Assets/Scripts/SubsampleTest.cs

@ -58,8 +58,9 @@ public class SubsampleTest : MonoBehaviour
gameCamera.targetTexture.name = "FSR2 Source Texture";
gameCamera.targetTexture.Create();
// TODO: adjust texture mipmap LOD bias by log2(renderResolution/displayResolution) - 1.0;
// Adjust texture mipmap LOD bias by log2(renderResolution/displayResolution) - 1.0;
// May need to leave this to the game dev, as we don't know which textures do and don't belong to the 3D scene
// TODO: add to Callbacks class/interface (ApplyMipmapBias)
float biasOffset = GetMipmapBiasOffset();
foreach (var tex in Resources.FindObjectsOfTypeAll<Texture2D>())
{

Loading…
Cancel
Save