您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
343 行
15 KiB
343 行
15 KiB
using UnityEngine.Rendering;
|
|
using System;
|
|
|
|
namespace UnityEngine.Experimental.Rendering.HDPipeline
|
|
{
|
|
public class SharedRTManager
|
|
{
|
|
// The render target used when we do not support MSAA
|
|
RTHandleSystem.RTHandle m_NormalRT = null;
|
|
RTHandleSystem.RTHandle m_VelocityRT = null;
|
|
RTHandleSystem.RTHandle m_CameraDepthStencilBuffer = null;
|
|
RTHandleSystem.RTHandle m_CameraDepthBufferMipChain;
|
|
RTHandleSystem.RTHandle m_CameraStencilBufferCopy;
|
|
HDUtils.PackedMipChainInfo m_CameraDepthBufferMipChainInfo; // This is metadata
|
|
|
|
// The two render targets that should be used when we render in MSAA
|
|
RTHandleSystem.RTHandle m_NormalMSAART = null;
|
|
RTHandleSystem.RTHandle m_VelocityMSAART = null;
|
|
// This texture must be used because reading directly from an MSAA Depth buffer is way to expensive. The solution that we went for is writing the depth in an additional color buffer (10x cheaper to solve on ps4)
|
|
RTHandleSystem.RTHandle m_DepthAsColorMSAART = null;
|
|
RTHandleSystem.RTHandle m_CameraDepthStencilMSAABuffer;
|
|
// This texture stores a set of depth values that are required for evaluating a bunch of effects in MSAA mode (R = Samples Max Depth, G = Samples Min Depth, G = Samples Average Depth)
|
|
RTHandleSystem.RTHandle m_CameraDepthValuesBuffer = null;
|
|
|
|
// MSAA resolve materials
|
|
Material m_DepthResolveMaterial = null;
|
|
Material m_ColorResolveMaterial = null;
|
|
|
|
// Flags that defines if we are using a local texture or external
|
|
bool m_ReuseGBufferMemory = false;
|
|
bool m_VelocitySupport = false;
|
|
bool m_MSAASupported = false;
|
|
MSAASamples m_MSAASamples = MSAASamples.None;
|
|
|
|
// Arrays of RTIDs that are used to set render targets (when MSAA and when not MSAA)
|
|
protected RenderTargetIdentifier[] m_RTIDs1 = new RenderTargetIdentifier[1];
|
|
protected RenderTargetIdentifier[] m_RTIDs2 = new RenderTargetIdentifier[2];
|
|
protected RenderTargetIdentifier[] m_RTIDs3 = new RenderTargetIdentifier[3];
|
|
|
|
// Property block used for the resolves
|
|
MaterialPropertyBlock m_PropertyBlock = new MaterialPropertyBlock();
|
|
|
|
public SharedRTManager()
|
|
{
|
|
}
|
|
|
|
public void InitSharedBuffers(GBufferManager gbufferManager, RenderPipelineSettings settings, RenderPipelineResources resources)
|
|
{
|
|
// Set the flags
|
|
m_MSAASupported = settings.supportMSAA;
|
|
m_MSAASamples = m_MSAASupported ? settings.msaaSampleCount : MSAASamples.None;
|
|
m_VelocitySupport = settings.supportMotionVectors;
|
|
m_ReuseGBufferMemory = !settings.supportOnlyForward;
|
|
|
|
// Create the depth/stencil buffer
|
|
m_CameraDepthStencilBuffer = RTHandles.Alloc(Vector2.one, depthBufferBits: DepthBits.Depth32, colorFormat: RenderTextureFormat.Depth, filterMode: FilterMode.Point, name: "CameraDepthStencil");
|
|
|
|
// Create the mip chain buffer
|
|
m_CameraDepthBufferMipChainInfo = new HDUtils.PackedMipChainInfo();
|
|
m_CameraDepthBufferMipChainInfo.Allocate();
|
|
m_CameraDepthBufferMipChain = RTHandles.Alloc(ComputeDepthBufferMipChainSize, colorFormat: RenderTextureFormat.RFloat, filterMode: FilterMode.Point, sRGB: false, enableRandomWrite: true, name: "CameraDepthBufferMipChain");
|
|
|
|
// Technically we won't need this buffer in some cases, but nothing that we can determine at init time.
|
|
m_CameraStencilBufferCopy = RTHandles.Alloc(Vector2.one, depthBufferBits: DepthBits.None, colorFormat: RenderTextureFormat.R8, sRGB: false, filterMode: FilterMode.Point, name: "CameraStencilCopy"); // DXGI_FORMAT_R8_UINT is not supported by Unity
|
|
|
|
if (m_VelocitySupport)
|
|
{
|
|
m_VelocityRT = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: Builtin.GetVelocityBufferFormat(), sRGB: Builtin.GetVelocityBufferSRGBFlag(), name: "Velocity");
|
|
if (m_MSAASupported)
|
|
{
|
|
m_VelocityMSAART = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: Builtin.GetVelocityBufferFormat(), sRGB: Builtin.GetVelocityBufferSRGBFlag(), enableMSAA: true, bindTextureMS: true, name: "VelocityMSAA");
|
|
}
|
|
}
|
|
|
|
// Allocate the additional textures only if MSAA is supported
|
|
if (m_MSAASupported)
|
|
{
|
|
// Let's create the MSAA textures
|
|
m_CameraDepthStencilMSAABuffer = RTHandles.Alloc(Vector2.one, depthBufferBits: DepthBits.Depth24, colorFormat: RenderTextureFormat.Depth, filterMode: FilterMode.Point, bindTextureMS: true, enableMSAA: true, name: "CameraDepthStencilMSAA");
|
|
m_CameraDepthValuesBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGBFloat, sRGB: false, name: "DepthValuesBuffer");
|
|
|
|
// Create the required resolve materials
|
|
m_DepthResolveMaterial = CoreUtils.CreateEngineMaterial(resources.shaders.depthValuesPS);
|
|
m_ColorResolveMaterial = CoreUtils.CreateEngineMaterial(resources.shaders.colorResolvePS);
|
|
}
|
|
|
|
// If we are in the forward only mode
|
|
if (!m_ReuseGBufferMemory)
|
|
{
|
|
// In case of full forward we must allocate the render target for normal buffer (or reuse one already existing)
|
|
// TODO: Provide a way to reuse a render target
|
|
m_NormalRT = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGB32, sRGB: false, enableRandomWrite: true, name: "NormalBuffer");
|
|
|
|
// Is MSAA supported?
|
|
if (m_MSAASupported)
|
|
{
|
|
// Allocate the two render textures we need in the MSAA case
|
|
m_NormalMSAART = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGB32, sRGB: false, enableMSAA: true, bindTextureMS: true, name: "NormalBufferMSAA");
|
|
m_DepthAsColorMSAART = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.RFloat, sRGB: false, bindTextureMS: true, enableMSAA: true, name: "DepthAsColorMSAA");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// When not forward only we should are using the normal buffer of the gbuffer
|
|
// In case of deferred, we must be in sync with NormalBuffer.hlsl and lit.hlsl files and setup the correct buffers
|
|
m_NormalRT = gbufferManager.GetNormalBuffer(0); // Normal + Roughness
|
|
}
|
|
}
|
|
|
|
public bool IsConsolePlatform()
|
|
{
|
|
return SystemInfo.graphicsDeviceType == GraphicsDeviceType.PlayStation4 ||
|
|
SystemInfo.graphicsDeviceType == GraphicsDeviceType.XboxOne ||
|
|
SystemInfo.graphicsDeviceType == GraphicsDeviceType.XboxOneD3D12;
|
|
}
|
|
|
|
// Function that will return the set of buffers required for the prepass (depending on if msaa is enabled or not)
|
|
public RenderTargetIdentifier[] GetPrepassBuffersRTI(FrameSettings frameSettings)
|
|
{
|
|
if (frameSettings.enableMSAA)
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
m_RTIDs2[0] = m_NormalMSAART.nameID;
|
|
m_RTIDs2[1] = m_DepthAsColorMSAART.nameID;
|
|
return m_RTIDs2;
|
|
}
|
|
else
|
|
{
|
|
m_RTIDs1[0] = m_NormalRT.nameID;
|
|
return m_RTIDs1;
|
|
}
|
|
}
|
|
|
|
// Function that will return the set of buffers required for the motion vector pass
|
|
public RenderTargetIdentifier[] GetVelocityPassBuffersRTI(FrameSettings frameSettings)
|
|
{
|
|
Debug.Assert(m_VelocitySupport);
|
|
if (frameSettings.enableMSAA)
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
m_RTIDs3[0] = m_VelocityMSAART.nameID;
|
|
m_RTIDs3[1] = m_NormalMSAART.nameID;
|
|
m_RTIDs3[2] = m_DepthAsColorMSAART.nameID;
|
|
return m_RTIDs3;
|
|
}
|
|
else
|
|
{
|
|
Debug.Assert(m_VelocitySupport);
|
|
m_RTIDs2[0] = m_VelocityRT.nameID;
|
|
m_RTIDs2[1] = m_NormalRT.nameID;
|
|
return m_RTIDs2;
|
|
}
|
|
}
|
|
|
|
// Request the normal buffer (MSAA or not)
|
|
public RTHandleSystem.RTHandle GetNormalBuffer(bool isMSAA = false)
|
|
{
|
|
if (isMSAA)
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
return m_NormalMSAART;
|
|
}
|
|
else
|
|
{
|
|
return m_NormalRT;
|
|
}
|
|
}
|
|
|
|
// Request the velocity buffer (MSAA or not)
|
|
public RTHandleSystem.RTHandle GetVelocityBuffer(bool isMSAA = false)
|
|
{
|
|
Debug.Assert(m_VelocitySupport );
|
|
if (isMSAA)
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
return m_VelocityMSAART;
|
|
}
|
|
else
|
|
{
|
|
return m_VelocityRT;
|
|
}
|
|
}
|
|
|
|
// Request the depth stencil buffer (MSAA or not)
|
|
public RTHandleSystem.RTHandle GetDepthStencilBuffer(bool isMSAA = false)
|
|
{
|
|
if (isMSAA)
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
return m_CameraDepthStencilMSAABuffer;
|
|
}
|
|
else
|
|
{
|
|
return m_CameraDepthStencilBuffer;
|
|
}
|
|
}
|
|
|
|
// Request the depth texture (MSAA or not)
|
|
public RTHandleSystem.RTHandle GetDepthTexture(bool isMSAA = false)
|
|
{
|
|
if (isMSAA)
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
return m_DepthAsColorMSAART;
|
|
}
|
|
else
|
|
{
|
|
return m_CameraDepthBufferMipChain;
|
|
}
|
|
}
|
|
|
|
public RTHandleSystem.RTHandle GetDepthValuesTexture()
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
return m_CameraDepthValuesBuffer;
|
|
}
|
|
|
|
public void SetNumMSAASamples(MSAASamples msaaSamples)
|
|
{
|
|
m_MSAASamples = msaaSamples;
|
|
}
|
|
|
|
public RTHandleSystem.RTHandle GetStencilBufferCopy()
|
|
{
|
|
return m_CameraStencilBufferCopy;
|
|
}
|
|
|
|
public Vector2Int ComputeDepthBufferMipChainSize(Vector2Int screenSize)
|
|
{
|
|
m_CameraDepthBufferMipChainInfo.ComputePackedMipChainInfo(screenSize);
|
|
return m_CameraDepthBufferMipChainInfo.textureSize;
|
|
}
|
|
|
|
public HDUtils.PackedMipChainInfo GetDepthBufferMipChainInfo()
|
|
{
|
|
return m_CameraDepthBufferMipChainInfo;
|
|
}
|
|
|
|
public void Build(HDRenderPipelineAsset hdAsset)
|
|
{
|
|
}
|
|
|
|
public void Cleanup()
|
|
{
|
|
if (!m_ReuseGBufferMemory)
|
|
{
|
|
RTHandles.Release(m_NormalRT);
|
|
if (m_MSAASupported)
|
|
{
|
|
RTHandles.Release(m_NormalMSAART);
|
|
RTHandles.Release(m_DepthAsColorMSAART);
|
|
}
|
|
}
|
|
|
|
if (m_VelocitySupport)
|
|
{
|
|
RTHandles.Release(m_VelocityRT);
|
|
if (m_MSAASupported)
|
|
{
|
|
RTHandles.Release(m_VelocityMSAART);
|
|
}
|
|
}
|
|
|
|
RTHandles.Release(m_CameraDepthStencilBuffer);
|
|
RTHandles.Release(m_CameraDepthBufferMipChain);
|
|
RTHandles.Release(m_CameraStencilBufferCopy);
|
|
|
|
if (m_MSAASupported)
|
|
{
|
|
RTHandles.Release(m_CameraDepthStencilMSAABuffer);
|
|
RTHandles.Release(m_CameraDepthValuesBuffer);
|
|
|
|
// Do not forget to release the materials
|
|
CoreUtils.Destroy(m_DepthResolveMaterial);
|
|
CoreUtils.Destroy(m_ColorResolveMaterial);
|
|
}
|
|
}
|
|
|
|
public static int SampleCountToPassIndex(MSAASamples samples)
|
|
{
|
|
switch (samples)
|
|
{
|
|
case MSAASamples.None:
|
|
return 0;
|
|
case MSAASamples.MSAA2x:
|
|
return 1;
|
|
case MSAASamples.MSAA4x:
|
|
return 2;
|
|
case MSAASamples.MSAA8x:
|
|
return 3;
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Bind the normal buffer that is needed
|
|
public void BindNormalBuffer(CommandBuffer cmd, bool isMSAA = false)
|
|
{
|
|
// NormalBuffer can be access in forward shader, so need to set global texture
|
|
cmd.SetGlobalTexture(HDShaderIDs._NormalBufferTexture, GetNormalBuffer(isMSAA));
|
|
}
|
|
|
|
public void ResolveSharedRT(CommandBuffer cmd, HDCamera hdCamera)
|
|
{
|
|
if (hdCamera.frameSettings.enableMSAA)
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
using (new ProfilingSample(cmd, "ComputeDepthValues", CustomSamplerId.VolumeUpdate.GetSampler()))
|
|
{
|
|
// Grab the RTIs and set the output render targets
|
|
m_RTIDs2[0] = m_CameraDepthValuesBuffer.nameID;
|
|
m_RTIDs2[1] = m_NormalRT.nameID;
|
|
HDUtils.SetRenderTarget(cmd, hdCamera, m_RTIDs2, m_CameraDepthStencilBuffer);
|
|
|
|
// Set the input textures
|
|
Shader.SetGlobalTexture(HDShaderIDs._NormalTextureMS, m_NormalMSAART);
|
|
Shader.SetGlobalTexture(HDShaderIDs._DepthTextureMS, m_DepthAsColorMSAART);
|
|
|
|
// Resolve the depth and normal buffers
|
|
cmd.DrawProcedural(Matrix4x4.identity, m_DepthResolveMaterial, SampleCountToPassIndex(m_MSAASamples), MeshTopology.Triangles, 3, 1);
|
|
}
|
|
}
|
|
}
|
|
public void ResolveMSAAColor(CommandBuffer cmd, HDCamera hdCamera, RTHandleSystem.RTHandle msaaTarget, RTHandleSystem.RTHandle simpleTarget)
|
|
{
|
|
if (hdCamera.frameSettings.enableMSAA)
|
|
{
|
|
Debug.Assert(m_MSAASupported);
|
|
using (new ProfilingSample(cmd, "ResolveColor", CustomSamplerId.VolumeUpdate.GetSampler()))
|
|
{
|
|
// Grab the RTIs and set the output render targets
|
|
HDUtils.SetRenderTarget(cmd, hdCamera, simpleTarget);
|
|
|
|
// Set the input textures
|
|
m_PropertyBlock.SetTexture(HDShaderIDs._ColorTextureMS, msaaTarget);
|
|
|
|
// Resolve the depth and normal buffers
|
|
cmd.DrawProcedural(Matrix4x4.identity, m_ColorResolveMaterial, SampleCountToPassIndex(m_MSAASamples), MeshTopology.Triangles, 3, 1, m_PropertyBlock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|