浏览代码

Add normalBufferManagement

/main
Sebastien Lagarde 6 年前
当前提交
c7c66abc
共有 4 个文件被更改,包括 146 次插入11 次删除
  1. 57
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs
  2. 8
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDStringConstants.cs
  3. 81
      com.unity.render-pipelines.high-definition/HDRP/Material/NormalBufferManager.cs
  4. 11
      com.unity.render-pipelines.high-definition/HDRP/Material/NormalBufferManager.cs.meta

57
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs


readonly GBufferManager m_GbufferManager;
readonly DBufferManager m_DbufferManager;
readonly SubsurfaceScatteringManager m_SSSBufferManager = new SubsurfaceScatteringManager();
readonly NormalBufferManager m_NormalBufferManager = new NormalBufferManager();
// Renderer Bake configuration can vary depends on if shadow mask is enabled or no
RendererConfiguration m_currentRendererConfigurationBakedLighting = HDUtils.k_RendererConfigurationBakedLighting;

m_DbufferManager = new DBufferManager();
m_SSSBufferManager.Build(asset);
m_NormalBufferManager.Build(asset);
// Initialize various compute shader resources
m_applyDistortionKernel = m_applyDistortionCS.FindKernel("KMain");

m_DbufferManager.CreateBuffers();
m_SSSBufferManager.InitSSSBuffers(m_GbufferManager, m_Asset.renderPipelineSettings);
m_NormalBufferManager.InitNormalBuffers(m_GbufferManager, m_Asset.renderPipelineSettings);
m_CameraColorBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGBHalf, sRGB: false, enableRandomWrite: true, enableMSAA: true, name: "CameraColor");
m_CameraSssDiffuseLightingBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.RGB111110Float, sRGB: false, enableRandomWrite: true, enableMSAA: true, name: "CameraSSSDiffuseLighting");

CoreUtils.Destroy(m_ErrorMaterial);
m_SSSBufferManager.Cleanup();
m_NormalBufferManager.Cleanup();
m_SkyManager.Cleanup();
m_VolumetricLightingSystem.Cleanup();
m_IBLFilterGGX.Cleanup();

RenderGBuffer(m_CullResults, hdCamera, enableBakeShadowMask, renderContext, cmd);
// We can now bind the normal buffer to be use by any effect
m_NormalBufferManager.BindNormalBuffers(cmd);
// In both forward and deferred, everything opaque should have been rendered at this point so we can safely copy the depth buffer for later processing.
CopyDepthBufferIfNeeded(cmd);
RenderDepthPyramid(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);

// by using the pass "ForwardOnly". In this case the .shader should not have "Forward" but only a "ForwardOnly" pass.
// It must also have a "DepthForwardOnly" and no "DepthOnly" pass as forward material (either deferred or forward only rendering) have always a depth pass.
// If a forward material have no depth prepass, then lighting can be incorrect (deferred sahdowing, SSAO), this may be acceptable depends on usage
bool addFullDepthPrepass = forcePrepass || hdCamera.frameSettings.enableForwardRenderingOnly || hdCamera.frameSettings.enableDepthPrepassWithDeferredRendering;
// Whatever the configuration we always render first the opaque object as opaque alpha tested are more costly to render and could be reject by early-z
// (but not Hi-z as it is disable with clip instruction). This is handled automatically with the RenderQueue value (OpaqueAlphaTested have a different value and thus are sorted after Opaque)
using (new ProfilingSample(cmd, !addFullDepthPrepass ? "Depth Prepass alpha test" : "Depth Prepass", CustomSamplerId.DepthPrepass.GetSampler()))
// Forward material always output normal buffer (unless they don't participate to shading)
// Deferred material never output normal buffer
if (hdCamera.frameSettings.enableForwardRenderingOnly)
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraDepthStencilBuffer);
if (addFullDepthPrepass) // Always true in case of forward rendering, use in case of deferred rendering if requesting a full depth prepass
using (new ProfilingSample(cmd, "Depth Prepass (forward)", CustomSamplerId.DepthPrepass.GetSampler()))
// We render first the opaque object as opaque alpha tested are more costly to render and could be reject by early-z (but not Hi-z as it is disable with clip instruction)
// This is handled automatically with the RenderQueue value (OpaqueAlphaTested have a different value and thus are sorted after Opaque)
cmd.EnableShaderKeyword("OUTPUT_NORMAL_BUFFER");
HDUtils.SetRenderTarget(cmd, hdCamera, m_NormalBufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer);
// Full forward: Output normal buffer for both forward and forwardOnly
else // Deferred rendering with partial depth prepass
}
else if (hdCamera.frameSettings.enableDepthPrepassWithDeferredRendering || forcePrepass)
{
using (new ProfilingSample(cmd, "Depth Prepass (deferred)", CustomSamplerId.DepthPrepass.GetSampler()))
// We always do a DepthForwardOnly pass with all the opaque (including alpha test)
cmd.DisableShaderKeyword("OUTPUT_NORMAL_BUFFER"); // Note: This only disable the output of normal buffer for Lit shader, not the other shader that don't use multicompile
HDUtils.SetRenderTarget(cmd, hdCamera, m_NormalBufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer);
// First deferred material
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
// Then forward only material that output normal buffer
}
}
else // Deferred with partial depth prepass
{
using (new ProfilingSample(cmd, "Depth Prepass (deferred incomplete)", CustomSamplerId.DepthPrepass.GetSampler()))
{
cmd.DisableShaderKeyword("OUTPUT_NORMAL_BUFFER");
// Alpha tested materials always have a prepass.
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraDepthStencilBuffer);
// First deferred alpha tested materials. Alpha tested object have always a prepass even if enableDepthPrepassWithDeferredRendering is disabled
HDUtils.SetRenderTarget(cmd, hdCamera, m_NormalBufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer);
// Then forward only material that output normal buffer
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
}
}

// In case of forward SSS we will bind all the required target. It is up to the shader to write into it or not.
if (hdCamera.frameSettings.enableSubsurfaceScattering)
{
RenderTargetIdentifier[] m_MRTWithSSS =
new RenderTargetIdentifier[2 + m_SSSBufferManager.sssBufferCount];
RenderTargetIdentifier[] m_MRTWithSSS = new RenderTargetIdentifier[2 + m_SSSBufferManager.sssBufferCount];
m_MRTWithSSS[0] = m_CameraColorBuffer; // Store the specular color
m_MRTWithSSS[1] = m_CameraSssDiffuseLightingBuffer;
for (int i = 0; i < m_SSSBufferManager.sssBufferCount; ++i)

8
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDStringConstants.cs


Shader.PropertyToID("_SSSBufferTexture3"),
};
public static readonly int[] _NormalBufferTexture =
{
Shader.PropertyToID("_NormalBufferTexture0"),
Shader.PropertyToID("_NormalBufferTexture1"),
Shader.PropertyToID("_NormalBufferTexture2"),
Shader.PropertyToID("_NormalBufferTexture3"),
};
public static readonly int _SSRefractionRayMarchBehindObjects = Shader.PropertyToID("_SSRefractionRayMarchBehindObjects");
public static readonly int _SSRefractionRayMaxScreenDistance = Shader.PropertyToID("_SSRefractionRayMaxScreenDistance");
public static readonly int _SSRefractionRayBlendScreenDistance = Shader.PropertyToID("_SSRefractionRayBlendScreenDistance");

81
com.unity.render-pipelines.high-definition/HDRP/Material/NormalBufferManager.cs


using UnityEngine.Rendering;
using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class NormalBufferManager
{
// Currently we only support NormalBuffer with one buffer. If the shader code change, it may require to update the shader manager
public const int k_MaxNormalBuffer = 1;
public int normalBufferCount { get { return k_MaxNormalBuffer; } }
RTHandleSystem.RTHandle[] m_ColorMRTs = new RTHandleSystem.RTHandle[k_MaxNormalBuffer];
protected RenderTargetIdentifier[] m_RTIDs = new RenderTargetIdentifier[k_MaxNormalBuffer];
bool[] m_ExternalBuffer = new bool[k_MaxNormalBuffer];
RTHandleSystem.RTHandle m_HTile;
public NormalBufferManager()
{
}
public void InitNormalBuffers(GBufferManager gbufferManager, RenderPipelineSettings settings)
{
if (settings.supportOnlyForward)
{
// 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_ColorMRTs[0] = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGB32, sRGB: false, name: "NormalBuffer");
m_ExternalBuffer[0] = false;
}
else
{
// In case of deferred, we must be in sync with NormalBuffer.hlsl and lit.hlsl files and setup the correct buffers
m_ColorMRTs[0] = gbufferManager.GetBuffer(1); // Normal + Roughness is GBuffer(1)
m_ExternalBuffer[0] = true;
}
}
public RenderTargetIdentifier[] GetBuffersRTI()
{
// nameID can change from one frame to another depending on the msaa flag so so we need to update this array to be sure it's up to date.
for (int i = 0; i < normalBufferCount; ++i)
{
m_RTIDs[i] = m_ColorMRTs[i].nameID;
}
return m_RTIDs;
}
public RTHandleSystem.RTHandle GetNormalBuffer(int index)
{
Debug.Assert(index < normalBufferCount);
return m_ColorMRTs[index];
}
public void Build(HDRenderPipelineAsset hdAsset)
{
}
public void Cleanup()
{
for (int i = 0; i < k_MaxNormalBuffer; ++i)
{
if (!m_ExternalBuffer[i])
{
RTHandles.Release(m_ColorMRTs[i]);
}
}
}
public void BindNormalBuffers(CommandBuffer cmd)
{
// NormalBuffer can be access in forward shader, so need to set global texture
for (int i = 0; i < normalBufferCount; ++i)
{
cmd.SetGlobalTexture(HDShaderIDs._NormalBufferTexture[i], GetNormalBuffer(i));
}
}
}
}

11
com.unity.render-pipelines.high-definition/HDRP/Material/NormalBufferManager.cs.meta


fileFormatVersion: 2
guid: 37fd75386a4957c43b0e2d0311efe2c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存