浏览代码

HDRenderPipeline: Split opaque and opaque alpha tested prepass

/Add-support-for-light-specular-color-tint
sebastienlagarde 7 年前
当前提交
cdd59e19
共有 2 个文件被更改,包括 54 次插入20 次删除
  1. 68
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs

68
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


CommandBuffer cmd,
ShaderPassName passName,
RendererConfiguration rendererConfiguration = 0,
RenderQueueRange? renderQueueRange = null,
RenderQueueRange? inRenderQueueRange = null,
RenderOpaqueRenderList(cull, camera, renderContext, cmd, new ShaderPassName[] { passName }, rendererConfiguration, renderQueueRange, stateBlock, overrideMaterial);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, new ShaderPassName[] { passName }, rendererConfiguration, inRenderQueueRange, stateBlock, overrideMaterial);
}
void RenderOpaqueRenderList(CullResults cull,

ShaderPassName[] passNames,
RendererConfiguration rendererConfiguration = 0,
RenderQueueRange? renderQueueRange = null,
RenderQueueRange? inRenderQueueRange = null,
RenderStateBlock? stateBlock = null,
Material overrideMaterial = null)
{

drawSettings.SetOverrideMaterial(overrideMaterial, 0);
}
var filterSettings = new FilterRenderersSettings(true) {renderQueueRange = renderQueueRange == null ? RenderQueueRange.opaque : renderQueueRange.Value };
var filterSettings = new FilterRenderersSettings(true) { renderQueueRange = inRenderQueueRange == null ? RenderQueueRange.opaque : inRenderQueueRange.Value };
if(stateBlock == null)
renderContext.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);
else

renderContext.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings, stateBlock.Value);
}
// RenderDepthPrepass render both opaque and opaque alpha tested based on engine configuration.
// Forward only renderer: We always render everything
// Deferred renderer: We render a depth prepass only if engine request it. We can decide if we render everything or only opaque alpha tested object.
// Forward opaque with deferred renderer (ForwardOnlyOpaqueDepthOnly pass): We always render everything
void RenderDepthPrepass(CullResults cull, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
// Guidelines: To be able to switch from deferred to forward renderer we need to have forward opaque material with both DepthOnly and ForwardOnlyOpaqueDepthOnly pass.

using (new Utilities.ProfilingSample(addDepthPrepass ? "Depth Prepass" : "Depth Prepass forward opaque ", cmd))
{
// Default depth prepass (forward and deferred) will render all opaque geometry.
RenderQueueRange renderQueueRange = RenderQueueRange.opaque;
// If we want only alpha tested geometry in prepass for deferred we change the RenderQueueRange
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() && m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering && m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass)
renderQueueRange = new RenderQueueRange { min = (int)RenderQueue.AlphaTest, max = (int)RenderQueue.GeometryLast - 1 };
if (false)
{
// Default depth prepass (forward and deferred) will render all opaque geometry.
RenderQueueRange renderQueueRange = RenderQueueRange.opaque;
// If we want only alpha tested geometry in prepass for deferred we change the RenderQueueRange
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() && m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering && m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass)
renderQueueRange = new RenderQueueRange { min = (int)RenderQueue.AlphaTest, max = (int)RenderQueue.GeometryLast - 1 };
// TODO: We should sort the Material by opaque then alpha masked Must do opaque then alpha masked for performance
Utilities.SetRenderTarget(cmd, m_CameraDepthStencilBufferRT);
// Note: addDepthPrepass and addForwardOnlyOpaqueDepthPrepass can't be both true at the same time. And if we are here both are not false
RenderOpaqueRenderList(cull, camera, renderContext, cmd, addDepthPrepass ? HDShaderPassNames.m_DepthOnlyName : HDShaderPassNames.m_ForwardOnlyOpaqueDepthOnlyName, 0, renderQueueRange);
// TODO: We should sort the Material by opaque then alpha masked Must do opaque then alpha masked for performance
Utilities.SetRenderTarget(cmd, m_CameraDepthStencilBufferRT);
// Note: addDepthPrepass and addForwardOnlyOpaqueDepthPrepass can't be both true at the same time. And if we are here both are not false
RenderOpaqueRenderList(cull, camera, renderContext, cmd, addDepthPrepass ? HDShaderPassNames.m_DepthOnlyOpaqueName : HDShaderPassNames.m_ForwardOnlyOpaqueDepthOnlyOpaqueName, 0, renderQueueRange);
}
else
{
Utilities.SetRenderTarget(cmd, m_CameraDepthStencilBufferRT);
// 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)
// Note: addDepthPrepass and addForwardOnlyOpaqueDepthPrepass can't be both true at the same time. And if we are here both are not false.
// Render opaque first
// In case of deferred we only render pure opaque if requested by the engine
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() && m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering && m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass)
{
RenderQueueRange rangeOpaqueNoAlphaTest = new RenderQueueRange { min = (int)RenderQueue.Geometry, max = (int)RenderQueue.AlphaTest - 1 };
RenderOpaqueRenderList(cull, camera, renderContext, cmd, addDepthPrepass ? HDShaderPassNames.m_DepthOnlyOpaqueName : HDShaderPassNames.m_ForwardOnlyOpaqueDepthOnlyOpaqueName, 0, rangeOpaqueNoAlphaTest);
}
// Then Render alpha tested object
RenderQueueRange rangeOpaqueAlphaTest = new RenderQueueRange { min = (int)RenderQueue.AlphaTest, max = (int)RenderQueue.GeometryLast - 1 };
RenderOpaqueRenderList(cull, camera, renderContext, cmd, addDepthPrepass ? HDShaderPassNames.m_DepthOnlyOpaqueAlphaTestName : HDShaderPassNames.m_ForwardOnlyOpaqueDepthOnlyOpaqueAlphaTestName, 0, rangeOpaqueAlphaTest);
}
// RenderGBuffer do the gbuffer pass. This is solely call with deferred. If we use a depth prepass, then the depth prepass will perform the alpha testing for opaque apha tested and we don't need to do it anymore
// during Gbuffer pass. This is handled in the shader and the depth test (equal and no depth write) is done here.
void RenderGBuffer(CullResults cull, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())

{
// setup GBuffer for rendering
Utilities.SetRenderTarget(cmd, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT);
// render opaque objects into GBuffer
if(m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled())
// Render opaque objects into GBuffer
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled())
{
// When doing debug display, the shader has the clip instruction regardless of the depth prepass so we can use regular depth test.
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferDebugDisplayName, Utilities.kRendererConfigurationBakedLighting, RenderQueueRange.opaque, m_DepthStateOpaque);

if(m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering)
if (m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering)
// When using depth prepass for alpha test only we need to use regular depth test for normal opaque objects.
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferWithPrepassName, Utilities.kRendererConfigurationBakedLighting, rangeOpaqueNoAlphaTest, m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass ? m_DepthStateOpaque : m_DepthStateOpaqueWithPrepass);
// When using depth prepass for opaque alpha test only we need to use regular depth test for normal opaque objects.
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferName, Utilities.kRendererConfigurationBakedLighting, rangeOpaqueNoAlphaTest, m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass ? m_DepthStateOpaque : m_DepthStateOpaqueWithPrepass);
// but for opaque alpha tested object we use a depth equal and no depth write. And we rely on the shader pass GbufferWithDepthPrepass
// No depth prepass, use regular depth test
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.m_GBufferName, Utilities.kRendererConfigurationBakedLighting, RenderQueueRange.opaque, m_DepthStateOpaque);
}
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs


internal static readonly ShaderPassName s_EmptyName = new ShaderPassName("");
internal static readonly ShaderPassName m_ForwardName = new ShaderPassName("Forward");
internal static readonly ShaderPassName m_ForwardDisplayDebugName = new ShaderPassName("ForwardDisplayDebug");
internal static readonly ShaderPassName m_DepthOnlyName = new ShaderPassName("DepthOnly");
internal static readonly ShaderPassName m_ForwardOnlyOpaqueDepthOnlyName = new ShaderPassName("ForwardOnlyOpaqueDepthOnly");
internal static readonly ShaderPassName m_DepthOnlyOpaqueName = new ShaderPassName("DepthOnlyOpaque");
internal static readonly ShaderPassName m_DepthOnlyOpaqueAlphaTestName = new ShaderPassName("DepthOnlyOpaqueAlphaTest");
internal static readonly ShaderPassName m_ForwardOnlyOpaqueDepthOnlyOpaqueName = new ShaderPassName("ForwardOnlyOpaqueDepthOnlyOpaque");
internal static readonly ShaderPassName m_ForwardOnlyOpaqueDepthOnlyOpaqueAlphaTestName = new ShaderPassName("ForwardOnlyOpaqueDepthOnlyOpaqueAlphaTest");
internal static readonly ShaderPassName m_ForwardOnlyOpaqueName = new ShaderPassName("ForwardOnlyOpaque");
internal static readonly ShaderPassName m_ForwardOnlyOpaqueDisplayDebugName = new ShaderPassName("ForwardOnlyOpaqueDisplayDebug");
internal static readonly ShaderPassName m_GBufferName = new ShaderPassName("GBuffer");

正在加载...
取消
保存