Skip to content

Commit

Permalink
Fix SSAO inverse projection
Browse files Browse the repository at this point in the history
  • Loading branch information
Delt06 committed Oct 14, 2023
1 parent f340875 commit fa1cffa
Show file tree
Hide file tree
Showing 14 changed files with 82 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ MonoBehaviour:
- {fileID: 11400000, guid: 91c04dff8aa908e4e951dac087bdf2ad, type: 2}
- {fileID: 11400000, guid: 30041836c268b614db8f6cfc9f36024b, type: 2}
- {fileID: 11400000, guid: f0489e92ff979c443be4e14bcf3021bb, type: 2}
- {fileID: 11400000, guid: 1646ef03c10aee74d9d024dabb976ff3, type: 2}
PostProcessing:
Enabled: 1
Passes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ public struct ToonCameraOverride
private readonly Camera _camera;
private bool _overriden;
private readonly ToonAdditionalCameraData _additionalCameraData;
private readonly bool _setInverse;

public ToonCameraOverride(Camera camera, ToonAdditionalCameraData additionalCameraData)
public ToonCameraOverride(Camera camera, ToonAdditionalCameraData additionalCameraData, bool setInverse = false)
{
_camera = camera;
_additionalCameraData = additionalCameraData;
Expand All @@ -21,6 +22,7 @@ public ToonCameraOverride(Camera camera, ToonAdditionalCameraData additionalCame
_zNear = camera.nearClipPlane;
_zFar = camera.farClipPlane;
_overriden = false;
_setInverse = setInverse;
}

public void OverrideIfEnabled(CommandBuffer cmd, in ToonCameraOverrideSettings settings)
Expand All @@ -42,22 +44,26 @@ public void OverrideIfEnabled(CommandBuffer cmd, in ToonCameraOverrideSettings s
_zNear,
_zFar
);
Matrix4x4 projectionMatrix = ToonRpUtils.GetGPUProjectionMatrix(matrix, _camera);
ToonRpUtils.SetViewAndProjectionMatrices(cmd, _camera.worldToCameraMatrix, projectionMatrix, false);
Matrix4x4 projectionMatrix = ToonRpUtils.GetGPUProjectionMatrixForCamera(matrix, _camera);
ToonRpUtils.SetViewAndProjectionMatrices(cmd, _camera.worldToCameraMatrix, projectionMatrix, JitterMatrix,
_setInverse
);
_overriden = true;
}

public void RestoreIfEnabled(CommandBuffer cmd)
public void Restore(ref ScriptableRenderContext context)
{
if (!_overriden)
{
return;
}

ToonRpUtils.SetViewAndProjectionMatrices(cmd, _camera.worldToCameraMatrix,
_additionalCameraData.MotionVectorsPersistentData.LastPrimaryProjectionMatrix, false
ToonRpUtils.SetupCameraProperties(ref context, _camera,
_additionalCameraData.JitteredProjectionMatrix
);
_overriden = false;
}

private Matrix4x4 JitterMatrix => _additionalCameraData.MotionVectorsPersistentData.JitterMatrix;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public override void Render()
);

cmd.SetGlobalDepthBias(0, 0);
cameraOverride.RestoreIfEnabled(cmd);
cameraOverride.Restore(ref _context);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public override void Render()
_settings.Overrides.Material
);

cameraOverride.RestoreIfEnabled(cmd);
cameraOverride.Restore(ref _context);
}

_context.ExecuteCommandBufferAndClear(cmd);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,26 @@ public class ToonSsao : ToonRenderingExtensionBase
private static readonly int SamplesId = Shader.PropertyToID("_ToonRP_SSAO_Samples");
private static readonly int BlurDirectionId = Shader.PropertyToID("_ToonRP_SSAO_Blur_Direction");
private static readonly int BlurSourceId = Shader.PropertyToID("_ToonRP_SSAO_Blur_SourceTex");
private static readonly int InvPId = Shader.PropertyToID("_ToonRP_SSAO_InvP");

private readonly Vector4[] _samples;
private readonly GlobalKeyword _ssaoKeyword;
private readonly GlobalKeyword _ssaoPatternKeyword;
private readonly Vector4[] _samples = GenerateRandomSamples(MaxSamplesCount);
private readonly GlobalKeyword _ssaoKeyword = GlobalKeyword.Create(SsaoKeywordName);
private readonly GlobalKeyword _ssaoPatternKeyword = GlobalKeyword.Create(SsaoPatternKeywordName);
private ToonAdditionalCameraData _additionalCameraData;
private ScriptableRenderContext _context;
private int _height;
private Material _material;
private Texture _noiseTexture;
private ToonSsaoSettings _settings;
private int _width;

public ToonSsao()
{
_samples = GenerateRandomSamples(MaxSamplesCount);
_ssaoKeyword = GlobalKeyword.Create(SsaoKeywordName);
_ssaoPatternKeyword = GlobalKeyword.Create(SsaoPatternKeywordName);
}

public override void Setup(in ToonRenderingExtensionContext context,
IToonRenderingExtensionSettingsStorage settingsStorage)
{
_context = context.ScriptableRenderContext;
_settings = settingsStorage.GetSettings<ToonSsaoSettings>(this);
_additionalCameraData = context.AdditionalCameraData;

_width = context.CameraRenderTarget.Width;
_height = context.CameraRenderTarget.Height;

Expand Down Expand Up @@ -88,6 +85,12 @@ public override void Render()
{
const string sampleName = "SSAO (Trace)";
cmd.BeginSample(sampleName);

Matrix4x4 gpuP =
ToonRpUtils.GetGPUProjectionMatrixForOffscreen(_additionalCameraData.JitteredProjectionMatrix);
var gpuInvP = Matrix4x4.Inverse(gpuP);
cmd.SetGlobalMatrix(InvPId, gpuInvP);

cmd.SetRenderTarget(RtId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
RenderMainPass(cmd);
cmd.EndSample(sampleName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ private void Reset()
{
Settings = new ToonTemporalAASettings
{
JitterScale = 1.0f,
JitterScale = 0.25f,
ModulationFactor = 0.8f,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ namespace DELTation.ToonRP.PostProcessing.BuiltIn
{
public static class ToonTemporalAAUtils
{
public static Matrix4x4 CalculateJitterMatrix(in ToonPostProcessingSettings postProcessingSettings,
public static Matrix4x4 CalculateJitterMatrix(
in ToonPostProcessingSettings postProcessingSettings,
Camera camera,
ToonCameraRenderTarget renderTarget)
{
Matrix4x4 jitterMatrix = Matrix4x4.identity;

if (camera.cameraType != CameraType.Game)
{
return jitterMatrix;
}

if (!postProcessingSettings.Enabled)
{
return jitterMatrix;
Expand All @@ -22,7 +29,6 @@ public static Matrix4x4 CalculateJitterMatrix(in ToonPostProcessingSettings post

int taaFrameIndex = Time.frameCount;

// TODO: check whether we should use camera or RT size
float actualWidth = renderTarget.Width;
float actualHeight = renderTarget.Height;
float jitterScale = taaSettings.JitterScale;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ namespace DELTation.ToonRP
[RequireComponent(typeof(Camera))]
public sealed class ToonAdditionalCameraData : MonoBehaviour, IAdditionalData
{
public Matrix4x4 BaseProjectionMatrix { get; set; }
public Matrix4x4 JitteredProjectionMatrix { get; set; }

public ToonMotionVectorsPersistentData MotionVectorsPersistentData { get; } = new();
public ToonTemporalAAPersistentData TemporalAAPersistentData { get; } = new();

Expand Down
4 changes: 1 addition & 3 deletions Packages/com.deltation.toon-rp/Runtime/ToonCameraData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ public readonly struct ToonCameraData
public readonly float AspectRatio;
public readonly Matrix4x4 ViewMatrix;
public readonly Matrix4x4 ProjectionMatrix;
public readonly Matrix4x4 JitterMatrix;

public ToonCameraData(Camera camera, Matrix4x4 jitterMatrix)
public ToonCameraData(Camera camera)
{
Camera = camera;
AspectRatio = camera.aspect;
ViewMatrix = camera.worldToCameraMatrix;
ProjectionMatrix = camera.projectionMatrix;
JitterMatrix = jitterMatrix;
}
}
}
27 changes: 8 additions & 19 deletions Packages/com.deltation.toon-rp/Runtime/ToonCameraRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,15 @@ private void Setup(CommandBuffer cmd, in ToonRampSettings globalRampSettings,

RTHandles.SetReferenceSize(rtWidth, rtHeight);

Matrix4x4 jitterMatrix = ToonTemporalAAUtils.CalculateJitterMatrix(postProcessingSettings, _renderTarget);
_cameraData = new ToonCameraData(_camera, jitterMatrix);
Matrix4x4 jitterMatrix =
ToonTemporalAAUtils.CalculateJitterMatrix(postProcessingSettings, _camera, _renderTarget);
_cameraData = new ToonCameraData(_camera);

_context.SetupCameraProperties(_camera);
UpdateProjectionMatrices(cmd);
_context.ExecuteCommandBufferAndClear(cmd);
_camera.ResetProjectionMatrix();
_additionalCameraData.MotionVectorsPersistentData.JitterMatrix = jitterMatrix;
_additionalCameraData.BaseProjectionMatrix = _camera.nonJitteredProjectionMatrix;
_additionalCameraData.JitteredProjectionMatrix = jitterMatrix * _additionalCameraData.BaseProjectionMatrix;
ToonRpUtils.SetupCameraProperties(ref _context, _camera, _additionalCameraData.JitteredProjectionMatrix);

if (_prePassMode.Includes(PrePassMode.MotionVectors))
{
Expand All @@ -354,15 +357,6 @@ private void Setup(CommandBuffer cmd, in ToonRampSettings globalRampSettings,
_tiledLighting.Setup(_context, _extensionContext);
}

private void UpdateProjectionMatrices(CommandBuffer cmd)
{
Matrix4x4 gpuProjectionMatrix =
ToonRpUtils.GetGPUProjectionMatrix(_cameraData.JitterMatrix * _cameraData.ProjectionMatrix, _camera);
ToonRpUtils.SetViewAndProjectionMatrices(cmd, _camera.worldToCameraMatrix, gpuProjectionMatrix, true);
_additionalCameraData.MotionVectorsPersistentData.LastPrimaryProjectionMatrix = gpuProjectionMatrix;
_context.SetupCameraProperties(_camera);
}

private bool RequireStencil(in ToonRenderingExtensionSettings extensionSettings)
{
if (_settings.Stencil)
Expand Down Expand Up @@ -526,9 +520,6 @@ private void DrawVisibleGeometry(CommandBuffer cmd)
{
_tiledLighting.PrepareForOpaqueGeometry(cmd);

// UpdateProjectionMatrices(cmd, false);
_context.ExecuteCommandBufferAndClear(cmd);

_extensionsCollection.RenderEvent(ToonRenderingEvent.BeforeOpaque);

using (new ProfilingScope(cmd, NamedProfilingSampler.Get(ToonRpPassId.OpaqueGeometry)))
Expand All @@ -549,10 +540,8 @@ private void DrawVisibleGeometry(CommandBuffer cmd)
{
_tiledLighting.PrepareForTransparentGeometry(cmd);

// UpdateProjectionMatrices(cmd, false);
_extensionsCollection.RenderEvent(ToonRenderingEvent.BeforeTransparent);


using (new ProfilingScope(cmd, NamedProfilingSampler.Get(ToonRpPassId.TransparentGeometry)))
{
_context.ExecuteCommandBufferAndClear(cmd);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public sealed class ToonMotionVectorsPersistentData

internal Matrix4x4 PreviousViewProjection { get; private set; } = Matrix4x4.identity;

public Matrix4x4 LastPrimaryProjectionMatrix { get; set; }
public Matrix4x4 JitterMatrix { get; set; }

public void Update(in ToonCameraData cameraData)
{
Expand Down
36 changes: 29 additions & 7 deletions Packages/com.deltation.toon-rp/Runtime/ToonRpUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,52 @@ public static void ExecuteCommandBufferAndClear(ref this ScriptableRenderContext
}

public static void SetViewAndProjectionMatrices(CommandBuffer cmd, Matrix4x4 viewMatrix,
Matrix4x4 gpuProjectionMatrix, bool setInverseMatrices)
Matrix4x4 gpuProjectionMatrix,
Matrix4x4 jitterMatrix,
bool setInverseMatrices)
{
Matrix4x4 viewAndProjectionMatrix = gpuProjectionMatrix * viewMatrix;
cmd.SetGlobalMatrix(ShaderPropertyId.ViewMatrix, viewMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.ProjectionMatrix, gpuProjectionMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.ViewAndProjectionMatrix, viewAndProjectionMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.ProjectionMatrix, jitterMatrix * gpuProjectionMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.ViewAndProjectionMatrix, jitterMatrix * viewAndProjectionMatrix);

if (!setInverseMatrices)
{
return;
}

SetInverseViewAndProjectionMatrices(cmd, viewMatrix, gpuProjectionMatrix, jitterMatrix);
}

public static void SetupCameraProperties(ref ScriptableRenderContext context, Camera camera,
Matrix4x4 jitteredProjectionMatrix)
{
camera.projectionMatrix = jitteredProjectionMatrix;
context.SetupCameraProperties(camera);
}

private static void SetInverseViewAndProjectionMatrices(CommandBuffer cmd, Matrix4x4 viewMatrix,
Matrix4x4 gpuProjectionMatrix, Matrix4x4 jitterMatrix)
{
var inverseViewMatrix = Matrix4x4.Inverse(viewMatrix);
var inverseProjectionMatrix = Matrix4x4.Inverse(gpuProjectionMatrix);
var inverseJitterMatrix = Matrix4x4.Inverse(jitterMatrix);
Matrix4x4 inverseViewProjection = inverseViewMatrix * inverseProjectionMatrix;
cmd.SetGlobalMatrix(ShaderPropertyId.InverseViewMatrix, inverseViewMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.InverseProjectionMatrix, inverseProjectionMatrix);
cmd.SetGlobalMatrix(ShaderPropertyId.InverseViewAndProjectionMatrix, inverseViewProjection);
cmd.SetGlobalMatrix(ShaderPropertyId.InverseProjectionMatrix, inverseProjectionMatrix * inverseJitterMatrix
);
cmd.SetGlobalMatrix(ShaderPropertyId.InverseViewAndProjectionMatrix,
inverseViewProjection * inverseJitterMatrix
);
}

public static Matrix4x4 GetGPUProjectionMatrix(Matrix4x4 projectionMatrix,
public static Matrix4x4 GetGPUProjectionMatrixForCamera(Matrix4x4 projectionMatrix,
Camera camera) =>
GL.GetGPUProjectionMatrix(projectionMatrix, IsCameraProjectionMatrixFlipped(camera));

public static Matrix4x4 GetGPUProjectionMatrixForOffscreen(Matrix4x4 projectionMatrix) =>
GL.GetGPUProjectionMatrix(projectionMatrix, SystemInfo.graphicsUVStartsAtTop);

private static bool IsCameraProjectionMatrixFlipped(Camera camera)
{
if (!SystemInfo.graphicsUVStartsAtTop)
Expand All @@ -87,7 +109,7 @@ public static Vector4 BuildRampVectorFromSmoothness(float a, float smoothness)
return new Vector4(invBMinusA, -a * invBMinusA);
}

private static class ShaderPropertyId
public static class ShaderPropertyId
{
public static readonly int ViewMatrix = Shader.PropertyToID("unity_MatrixV");
public static readonly int ProjectionMatrix = Shader.PropertyToID("glstate_matrix_projection");
Expand Down
11 changes: 0 additions & 11 deletions Packages/com.deltation.toon-rp/ShaderLibrary/UnityInput.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,6 @@ CBUFFER_START(UnityPerDraw)
float4 unity_MotionVectorsParams;
CBUFFER_END

// CBUFFER_START(UnityVelocityPass)
// float4x4 unity_MatrixNonJitteredVP;
// float4x4 unity_MatrixPreviousVP;
// float4x4 unity_MatrixPreviousM;
// float4x4 unity_MatrixPreviousMI;
// //X : Use last frame positions (right now skinned meshes are the only objects that use this
// //Y : Force No Motion
// //Z : Z bias value
// float4 unity_MotionVectorsParams;
// CBUFFER_END

float4x4 unity_MatrixVP;
float4x4 unity_MatrixV;
float4x4 unity_MatrixInvV;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#define DEPTH_BIAS 0.01

CBUFFER_START(ToonRpSsao)
float4x4 _ToonRP_SSAO_InvP;
float2 _ToonRP_SSAO_NoiseScale;
int _ToonRP_SSAO_KernelSize;
float4 _ToonRP_SSAO_Samples[MAX_SAMPLES_COUNT];
Expand Down Expand Up @@ -108,7 +109,7 @@
}

const float3 positionNdc = ScreenSpaceUvToNdc(uv, zNdc);
const float4 positionVs = RestorePositionVs(positionNdc, UNITY_MATRIX_I_P);
const float4 positionVs = RestorePositionVs(positionNdc, _ToonRP_SSAO_InvP);
const float3 positionWs = mul(UNITY_MATRIX_I_V, positionVs).xyz + normalWs * NORMAL_BIAS;

const float3 randomVector = float3(SAMPLE_TEXTURE2D_LOD(_NoiseTexture, sampler_NoiseTexture, uv * _ToonRP_SSAO_NoiseScale, 0).xy, 0);
Expand Down Expand Up @@ -142,7 +143,7 @@

const float sampleDepthZNdc = SampleDepthTexture(sampleScreenSpaceUv);
const float3 sampleDepthPositionNdc = float3(samplePositionCs.xy, sampleDepthZNdc);
float3 sampleDepthPositionVs = RestorePositionVs(sampleDepthPositionNdc, UNITY_MATRIX_I_P).xyz;
float3 sampleDepthPositionVs = RestorePositionVs(sampleDepthPositionNdc, _ToonRP_SSAO_InvP).xyz;

float3 samplePositionVs = TransformWorldToView(samplePositionWs);

Expand Down

0 comments on commit fa1cffa

Please sign in to comment.