CommandBuffer cmd ,
ShaderPassName passName ,
RendererConfiguration rendererConfiguration = 0 ,
RenderQueueRange ? r enderQueueRange = null ,
RenderQueueRange ? inR enderQueueRange = null ,
RenderOpaqueRenderList ( cull , camera , renderContext , cmd , new ShaderPassName [ ] { passName } , rendererConfiguration , r enderQueueRange, stateBlock , overrideMaterial ) ;
RenderOpaqueRenderList ( cull , camera , renderContext , cmd , new ShaderPassName [ ] { passName } , rendererConfiguration , inR enderQueueRange, stateBlock , overrideMaterial ) ;
}
void RenderOpaqueRenderList ( CullResults cull ,
ShaderPassName [ ] passNames ,
RendererConfiguration rendererConfiguration = 0 ,
RenderQueueRange ? r enderQueueRange = null ,
RenderQueueRange ? inR enderQueueRange = null ,
RenderStateBlock ? stateBlock = null ,
Material overrideMaterial = null )
{
drawSettings . SetOverrideMaterial ( overrideMaterial , 0 ) ;
}
var filterSettings = new FilterRenderersSettings ( true ) { renderQueueRange = r enderQueueRange = = null ? RenderQueueRange . opaque : r enderQueueRange. Value } ;
var filterSettings = new FilterRenderersSettings ( true ) { renderQueueRange = inR enderQueueRange = = null ? RenderQueueRange . opaque : inR enderQueueRange. 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 ) ;
}
}