Skip to content

2021.2/universal/swapbuffer afterpostprocess #5545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Sep 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,8 @@ public void BaseRendererDoesNotCreateRenderTexturesIfStackIsEmpty()
return;

Assert.IsFalse(baseRenderer.createColorTexture);
Assert.AreEqual(RenderTargetHandle.CameraTarget.Identifier(), baseRenderer.cameraColorTarget);

Assert.IsFalse(baseRenderer.createDepthTexture);
Assert.AreEqual(RenderTargetHandle.CameraTarget.Identifier(), baseRenderer.cameraDepthTarget);
}

[Test]
Expand All @@ -70,10 +68,8 @@ public void BaseRendererCreatesRenderTexturesIfStackIsNotEmpty()
Renderer2D baseRenderer = m_BaseCameraData.scriptableRenderer as Renderer2D;

Assert.IsTrue(baseRenderer.createColorTexture);
Assert.AreNotEqual(RenderTargetHandle.CameraTarget.Identifier(), baseRenderer.cameraColorTarget);

Assert.IsTrue(baseRenderer.createDepthTexture);
Assert.AreNotEqual(RenderTargetHandle.CameraTarget.Identifier(), baseRenderer.cameraDepthTarget);
}

[Test]
Expand All @@ -86,10 +82,8 @@ public void BaseRendererUsesDepthAttachmentOfColorTextureIfNoDepthTextureCreated
Renderer2D baseRenderer = m_BaseCameraData.scriptableRenderer as Renderer2D;

Assert.IsTrue(baseRenderer.createColorTexture);
Assert.AreNotEqual(RenderTargetHandle.CameraTarget.Identifier(), baseRenderer.cameraColorTarget);

Assert.IsFalse(baseRenderer.createDepthTexture);
Assert.AreEqual(baseRenderer.cameraColorTarget, baseRenderer.cameraDepthTarget);
}

[Test]
Expand All @@ -101,9 +95,6 @@ public void OverlayRendererUsesRenderTexturesFromBase()

Renderer2D baseRenderer = m_BaseCameraData.scriptableRenderer as Renderer2D;
Renderer2D overlayRenderer = m_OverlayCameraData.scriptableRenderer as Renderer2D;

Assert.AreEqual(baseRenderer.cameraColorTarget, overlayRenderer.cameraColorTarget);
Assert.AreEqual(baseRenderer.cameraDepthTarget, overlayRenderer.cameraDepthTarget);
}

[Test]
Expand Down
1 change: 1 addition & 0 deletions com.unity.render-pipelines.universal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Support undo of URP Global Settings asset assignation (case 1342987).
- Removed unsupported fields from Presets of Light and Camera [case 1335979].
- Fixed graphical artefact when terrain height map is used with rendering layer mask for lighting.
- Fixed an issue where _AfterPostProcessTexture was no longer being assigned in UniversalRenderer.

### Changed
- Change Asset/Create/Shader/Universal Render Pipeline/Lit Shader Graph to Asset/Create/Shader Graph/URP/Lit Shader Graph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, // color
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare); // depth
cmd.Blit(m_Source, cameraTarget, m_BlitMaterial);
cameraData.renderer.ConfigureCameraTarget(cameraTarget, cameraTarget);
}
else
{
Expand All @@ -116,6 +117,7 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData
cmd.SetViewport(cameraData.pixelRect);
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_BlitMaterial);
cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
cameraData.renderer.ConfigureCameraTarget(cameraTarget, cameraTarget);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ public void SetupFinalPass(in RenderTargetHandle source, bool useSwapBuffer = fa
/// <inheritdoc/>
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
overrideCameraTarget = true;

if (m_Destination == RenderTargetHandle.CameraTarget)
return;

Expand Down Expand Up @@ -329,14 +331,31 @@ void Render(CommandBuffer cmd, ref RenderingData renderingData)
{
ref CameraData cameraData = ref renderingData.cameraData;
ref ScriptableRenderer renderer = ref cameraData.renderer;
bool isSceneViewCamera = cameraData.isSceneViewCamera;

//Check amount of swaps we have to do
//We blit back and forth without msaa untill the last blit.
bool useStopNan = cameraData.isStopNaNEnabled && m_Materials.stopNaN != null;
bool useSubPixeMorpAA = cameraData.antialiasing == AntialiasingMode.SubpixelMorphologicalAntiAliasing && SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2;
var dofMaterial = m_DepthOfField.mode.value == DepthOfFieldMode.Gaussian ? m_Materials.gaussianDepthOfField : m_Materials.bokehDepthOfField;
bool useDepthOfField = m_DepthOfField.IsActive() && !isSceneViewCamera && dofMaterial != null;
bool useLensFlare = !LensFlareCommonSRP.Instance.IsEmpty();
bool useMotionBlur = m_MotionBlur.IsActive() && !isSceneViewCamera;
bool usePaniniProjection = m_PaniniProjection.IsActive() && !isSceneViewCamera;

int amountOfPassesRemaining = (useStopNan ? 1 : 0) + (useSubPixeMorpAA ? 1 : 0) + (useDepthOfField ? 1 : 0) + (useLensFlare ? 1 : 0) + (useMotionBlur ? 1 : 0) + (usePaniniProjection ? 1 : 0);

if (m_UseSwapBuffer && amountOfPassesRemaining > 0)
{
renderer.EnableSwapBufferMSAA(false);
}

// Don't use these directly unless you have a good reason to, use GetSource() and
// GetDestination() instead
bool tempTargetUsed = false;
bool tempTarget2Used = false;
RenderTargetIdentifier source = m_UseSwapBuffer ? renderer.cameraColorTarget : m_Source;
RenderTargetIdentifier destination = m_UseSwapBuffer ? renderer.GetCameraColorFrontBuffer(cmd) : -1;
bool isSceneViewCamera = cameraData.isSceneViewCamera;

RenderTargetIdentifier GetSource() => source;

Expand Down Expand Up @@ -365,8 +384,15 @@ RenderTargetIdentifier GetDestination()

void Swap(ref ScriptableRenderer r)
{
--amountOfPassesRemaining;
if (m_UseSwapBuffer)
{
//we want the last blit to be to MSAA
if (amountOfPassesRemaining == 0 && !m_HasFinalPass)
{
r.EnableSwapBufferMSAA(true);
}

r.SwapColorBuffer(cmd);
source = r.cameraColorTarget;
destination = r.GetCameraColorFrontBuffer(cmd);
Expand All @@ -382,7 +408,7 @@ void Swap(ref ScriptableRenderer r)

// Optional NaN killer before post-processing kicks in
// stopNaN may be null on Adreno 3xx. It doesn't support full shader level 3.5, but SystemInfo.graphicsShaderLevel is 35.
if (cameraData.isStopNaNEnabled && m_Materials.stopNaN != null)
if (useStopNan)
{
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.StopNaNs)))
{
Expand All @@ -396,7 +422,7 @@ void Swap(ref ScriptableRenderer r)
}

// Anti-aliasing
if (cameraData.antialiasing == AntialiasingMode.SubpixelMorphologicalAntiAliasing && SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2)
if (useSubPixeMorpAA)
{
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.SMAA)))
{
Expand All @@ -408,8 +434,7 @@ void Swap(ref ScriptableRenderer r)
// Depth of Field
// Adreno 3xx SystemInfo.graphicsShaderLevel is 35, but instancing support is disabled due to buggy drivers.
// DOF shader uses #pragma target 3.5 which adds requirement for instancing support, thus marking the shader unsupported on those devices.
var dofMaterial = m_DepthOfField.mode.value == DepthOfFieldMode.Gaussian ? m_Materials.gaussianDepthOfField : m_Materials.bokehDepthOfField;
if (m_DepthOfField.IsActive() && !isSceneViewCamera && dofMaterial != null)
if (useDepthOfField)
{
var markerName = m_DepthOfField.mode.value == DepthOfFieldMode.Gaussian
? URPProfileId.GaussianDepthOfField
Expand All @@ -423,7 +448,7 @@ void Swap(ref ScriptableRenderer r)
}

// Motion blur
if (m_MotionBlur.IsActive() && !isSceneViewCamera)
if (useMotionBlur)
{
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.MotionBlur)))
{
Expand All @@ -434,7 +459,7 @@ void Swap(ref ScriptableRenderer r)

// Panini projection is done as a fullscreen pass after all depth-based effects are done
// and before bloom kicks in
if (m_PaniniProjection.IsActive() && !isSceneViewCamera)
if (usePaniniProjection)
{
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.PaniniProjection)))
{
Expand All @@ -444,7 +469,7 @@ void Swap(ref ScriptableRenderer r)
}

// Lens Flare
if (!LensFlareCommonSRP.Instance.IsEmpty())
if (useLensFlare)
{
bool usePanini;
float paniniDistance;
Expand Down Expand Up @@ -565,6 +590,7 @@ void Swap(ref ScriptableRenderer r)
#endif
{
cmd.SetRenderTarget(cameraTarget, colorLoadAction, RenderBufferStoreAction.Store, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare);
cameraData.renderer.ConfigureCameraTarget(cameraTarget, cameraTarget);
cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);

if ((m_Destination == RenderTargetHandle.CameraTarget && !m_UseSwapBuffer) || m_ResolveToScreen)
Expand Down Expand Up @@ -600,6 +626,8 @@ void Swap(ref ScriptableRenderer r)

if (tempTarget2Used)
cmd.ReleaseTemporaryRT(ShaderConstants._TempTarget2);

cmd.ReleaseTemporaryRT(m_InternalLut.id);
}
}

Expand Down Expand Up @@ -1401,6 +1429,7 @@ void RenderFinalPass(CommandBuffer cmd, ref RenderingData renderingData)
cmd.SetViewport(cameraData.pixelRect);
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, material);
cmd.SetViewProjectionMatrices(cameraData.camera.worldToCameraMatrix, cameraData.camera.projectionMatrix);
cameraData.renderer.ConfigureCameraTarget(cameraTarget, cameraTarget);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,68 +10,115 @@ namespace UnityEngine.Rendering.Universal.Internal
//NOTE: This class is meant to be removed when RTHandles get implemented in urp
internal sealed class RenderTargetBufferSystem
{
RenderTargetHandle RTA;
RenderTargetHandle RTB;
bool m_FirstIsBackBuffer = true;
RenderTextureDescriptor m_Desc;
FilterMode m_FilterMode;

int m_NameA;
int m_NameB;
struct SwapBuffer
{
public RenderTargetHandle rt;
public int name;
public int msaa;
}
SwapBuffer m_A, m_B;
static bool m_AisBackBuffer = true;

static RenderTextureDescriptor m_Desc;
FilterMode m_FilterMode;
bool m_AllowMSAA = true;
bool m_RTisAllocated = false;

SwapBuffer backBuffer { get { return m_AisBackBuffer ? m_A : m_B; } }
SwapBuffer frontBuffer { get { return m_AisBackBuffer ? m_B : m_A; } }

public RenderTargetBufferSystem(string name)
{
m_NameA = Shader.PropertyToID(name + "A");
m_NameB = Shader.PropertyToID(name + "B");
RTA.Init(name + "A");
RTB.Init(name + "B");
m_A.name = Shader.PropertyToID(name + "A");
m_B.name = Shader.PropertyToID(name + "B");
m_A.rt.Init(name + "A");
m_B.rt.Init(name + "B");
}

public RenderTargetHandle GetBackBuffer()
{
return m_FirstIsBackBuffer ? RTA : RTB;
return backBuffer.rt;
}

public RenderTargetHandle GetBackBuffer(CommandBuffer cmd)
{
if (!m_RTisAllocated)
Initialize(cmd);
return m_FirstIsBackBuffer ? RTA : RTB;
return backBuffer.rt;
}

public RenderTargetHandle GetFrontBuffer(CommandBuffer cmd)
{
if (!m_RTisAllocated)
Initialize(cmd);
return m_FirstIsBackBuffer ? RTB : RTA;

int pipelineMSAA = m_Desc.msaaSamples;
int bufferMSAA = frontBuffer.msaa;

if (m_AllowMSAA && bufferMSAA != pipelineMSAA)
{
//We don't want a depth buffer on B buffer
var desc = m_Desc;
if (m_AisBackBuffer)
desc.depthBufferBits = 0;

cmd.ReleaseTemporaryRT(frontBuffer.name);
cmd.GetTemporaryRT(frontBuffer.name, desc, m_FilterMode);

if (m_AisBackBuffer)
m_B.msaa = desc.msaaSamples;
else m_A.msaa = desc.msaaSamples;
}
else if (!m_AllowMSAA && bufferMSAA > 1)
{
//We don't want a depth buffer on B buffer
var desc = m_Desc;
desc.msaaSamples = 1;
if (m_AisBackBuffer)
desc.depthBufferBits = 0;

cmd.ReleaseTemporaryRT(frontBuffer.name);
cmd.GetTemporaryRT(frontBuffer.name, desc, m_FilterMode);

if (m_AisBackBuffer)
m_B.msaa = desc.msaaSamples;
else m_A.msaa = desc.msaaSamples;
}

return frontBuffer.rt;
}

public void Swap()
{
m_FirstIsBackBuffer = !m_FirstIsBackBuffer;
m_AisBackBuffer = !m_AisBackBuffer;
}

void Initialize(CommandBuffer cmd)
{
cmd.GetTemporaryRT(m_NameA, m_Desc, m_FilterMode);
m_A.msaa = m_Desc.msaaSamples;
m_B.msaa = m_Desc.msaaSamples;

cmd.GetTemporaryRT(m_A.name, m_Desc, m_FilterMode);
var descB = m_Desc;
descB.depthBufferBits = 0;
cmd.GetTemporaryRT(m_NameB, m_Desc, m_FilterMode);
//descB.depthBufferBits = 0;
cmd.GetTemporaryRT(m_B.name, descB, m_FilterMode);

m_RTisAllocated = true;
}

public void Clear(CommandBuffer cmd)
{
cmd.ReleaseTemporaryRT(m_NameA);
cmd.ReleaseTemporaryRT(m_NameB);
cmd.ReleaseTemporaryRT(m_A.name);
cmd.ReleaseTemporaryRT(m_B.name);

m_FirstIsBackBuffer = true;
m_AisBackBuffer = true;
m_AllowMSAA = true;
}

public void SetCameraSettings(CommandBuffer cmd, RenderTextureDescriptor desc, FilterMode filterMode)
{
Clear(cmd); //SetCameraSettings is called when new stack starts rendering. Make sure the targets are updated to use the new descriptor.

m_Desc = desc;
m_FilterMode = filterMode;

Expand All @@ -80,7 +127,12 @@ public void SetCameraSettings(CommandBuffer cmd, RenderTextureDescriptor desc, F

public RenderTargetHandle GetBufferA()
{
return RTA;
return m_A.rt;
}

public void EnableMSAA(bool enable)
{
m_AllowMSAA = enable;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,7 @@ static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorAtt
}

internal virtual void SwapColorBuffer(CommandBuffer cmd) { }
internal virtual void EnableSwapBufferMSAA(bool enable) { }

[Conditional("UNITY_EDITOR")]
void DrawGizmos(ScriptableRenderContext context, Camera camera, GizmoSubset gizmoSubset)
Expand Down
Loading