int m_VelocityBuffer ;
int m_DistortionBuffer ;
bool m_Dirty = false ;
RenderTargetIdentifier m_CameraColorBufferRT ;
RenderTargetIdentifier m_CameraDepthBufferRT ;
RenderTargetIdentifier m_VelocityBufferRT ;
void OnValidate ( )
{
Rebuild ( ) ;
m_Dirty = true ;
}
public override void Rebuild ( )
m_lightList = new LightList ( ) ;
m_lightList . Allocate ( ) ;
m_Dirty = false ;
}
void OnDisable ( )
// We clear only the depth buffer, no need to clear the various color buffer as we overwrite them.
// Clear depth/stencil and init buffers
using ( new Utilities . ProfilingSample ( "InitGBuffers and clear Depth/Stencil" , renderLoop ) )
{
var cmd = new CommandBuffer ( ) ;
cmd . name = "" ;
{
var cmd = new CommandBuffer ( ) ;
cmd . name = "" ;
// Init buffer
// With scriptable render loop we must allocate ourself depth and color buffer (We must be independent of backbuffer for now, hope to fix that later).
// Also we manage ourself the HDR format, here allocating fp16 directly.
// With scriptable render loop we can allocate temporary RT in a command buffer, they will not be release with ExecuteCommandBuffer
// These temporary surface are release automatically at the end of the scriptable renderloop if not release explicitly
int w = camera . pixelWidth ;
int h = camera . pixelHeight ;
// Init buffer
// With scriptable render loop we must allocate ourself depth and color buffer (We must be independent of backbuffer for now, hope to fix that later).
// Also we manage ourself the HDR format, here allocating fp16 directly.
// With scriptable render loop we can allocate temporary RT in a command buffer, they will not be release with ExecuteCommandBuffer
// These temporary surface are release automatically at the end of the scriptable renderloop if not release explicitly
int w = camera . pixelWidth ;
int h = camera . pixelHeight ;
cmd . GetTemporaryRT ( m_CameraColorBuffer , w , h , 0 , FilterMode . Point , RenderTextureFormat . ARGBHalf , RenderTextureReadWrite . Linear ) ;
cmd . GetTemporaryRT ( m_CameraDepthBuffer , w , h , 2 4 , FilterMode . Point , RenderTextureFormat . Depth ) ;
if ( ! debugParameters . useForwardRenderingOnly )
{
m_gbufferManager . InitGBuffers ( w , h , cmd ) ;
}
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
cmd . GetTemporaryRT ( m_CameraColorBuffer , w , h , 0 , FilterMode . Point , RenderTextureFormat . ARGBHalf , RenderTextureReadWrite . Linear ) ;
cmd . GetTemporaryRT ( m_CameraDepthBuffer , w , h , 2 4 , FilterMode . Point , RenderTextureFormat . Depth ) ;
if ( ! debugParameters . useForwardRenderingOnly )
{
m_gbufferManager . InitGBuffers ( w , h , cmd ) ;
Utilities . SetRenderTarget ( renderLoop , m_CameraColorBufferRT , m_CameraDepthBufferRT , ClearFlag . ClearDepth ) ;
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
Utilities . SetRenderTarget ( renderLoop , m_CameraColorBufferRT , m_CameraDepthBufferRT , ClearFlag . ClearDepth ) ;
}
// TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.
// TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.
// Clear HDR target
using ( new Utilities . ProfilingSample ( "Clear HDR target" , renderLoop ) )
{
Utilities . SetRenderTarget ( renderLoop , m_CameraColorBufferRT , m_CameraDepthBufferRT , ClearFlag . ClearColor , Color . black ) ;
}
// Clear HDR target
using ( new Utilities . ProfilingSample ( "Clear HDR target" , renderLoop ) )
{
Utilities . SetRenderTarget ( renderLoop , m_CameraColorBufferRT , m_CameraDepthBufferRT , ClearFlag . ClearColor , Color . black ) ;
}
// Clear GBuffers
using ( new Utilities . ProfilingSample ( "Clear GBuffer" , renderLoop ) )
{
Utilities . SetRenderTarget ( renderLoop , m_gbufferManager . GetGBuffers ( ) , m_CameraDepthBufferRT , ClearFlag . ClearColor , Color . black ) ;
}
// Clear GBuffers
using ( new Utilities . ProfilingSample ( "Clear GBuffer" , renderLoop ) )
{
Utilities . SetRenderTarget ( renderLoop , m_gbufferManager . GetGBuffers ( ) , m_CameraDepthBufferRT , ClearFlag . ClearColor , Color . black ) ;
// END TEMP
// END TEMP
}
}
void RenderOpaqueRenderList ( CullResults cull , Camera camera , RenderLoop renderLoop , string passName , RendererConfiguration rendererConfiguration = 0 )
using ( new Utilities . ProfilingSample ( "Depth Prepass" , renderLoop ) )
{
// TODO: Must do opaque then alpha masked for performance!
// TODO: front to back for opaque and by materal for opaque tested when we split in two
// TODO: Must do opaque then alpha masked for performance!
// TODO: front to back for opaque and by materal for opaque tested when we split in two
RenderOpaqueRenderList ( cull , camera , renderLoop , "DepthOnly" ) ;
}
RenderOpaqueRenderList ( cull , camera , renderLoop , "DepthOnly" ) ;
}
}
void RenderGBuffer ( CullResults cull , Camera camera , RenderLoop renderLoop )
using ( new Utilities . ProfilingSample ( "GBuffer Pass" , renderLoop ) )
{
// setup GBuffer for rendering
// setup GBuffer for rendering
// render opaque objects into GBuffer
RenderOpaqueRenderList ( cull , camera , renderLoop , "GBuffer" , Utilities . kRendererConfigurationBakedLighting ) ;
}
// render opaque objects into GBuffer
RenderOpaqueRenderList ( cull , camera , renderLoop , "GBuffer" , Utilities . kRendererConfigurationBakedLighting ) ;
}
}
// This pass is use in case of forward opaque and deferred rendering. We need to render forward objects before tile lighting pass
if ( debugParameters . useDepthPrepass )
return ;
// TODO: Use the render queue index to only send the forward opaque!
Utilities . SetRenderTarget ( renderLoop , m_CameraDepthBufferRT , "Depth Prepass" ) ;
RenderOpaqueRenderList ( cull , camera , renderLoop , "DepthOnly" ) ;
using ( new Utilities . ProfilingSample ( "Depth Prepass" , renderLoop ) )
{
// TODO: Use the render queue index to only send the forward opaque!
Utilities . SetRenderTarget ( renderLoop , m_CameraDepthBufferRT ) ;
RenderOpaqueRenderList ( cull , camera , renderLoop , "DepthOnly" ) ;
}
}
void RenderDebugViewMaterial ( CullResults cull , Camera camera , RenderLoop renderLoop )
using ( new Utilities . ProfilingSample ( "Single Pass - Deferred Lighting Pass" , renderLoop ) )
{
// Bind material data
m_LitRenderLoop . Bind ( ) ;
m_SinglePassLightLoop . RenderDeferredLighting ( camera , renderLoop , m_CameraColorBuffer ) ;
// m_TilePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
}
// Bind material data
m_LitRenderLoop . Bind ( ) ;
m_SinglePassLightLoop . RenderDeferredLighting ( camera , renderLoop , m_CameraColorBuffer ) ;
// m_TilePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
}
}
void RenderSky ( Camera camera , RenderLoop renderLoop )
{
using ( new Utilities . ProfilingSample ( "Forward Pass" , renderLoop ) )
{
// Bind material data
m_LitRenderLoop . Bind ( ) ;
// Bind material data
m_LitRenderLoop . Bind ( ) ;
if ( debugParameters . useForwardRenderingOnly )
{
RenderOpaqueRenderList ( cullResults , camera , renderLoop , "Forward" ) ;
}
if ( debugParameters . useForwardRenderingOnly )
{
RenderOpaqueRenderList ( cullResults , camera , renderLoop , "Forward" ) ;
}
RenderTransparentRenderList ( cullResults , camera , renderLoop , "Forward" , Utilities . kRendererConfigurationBakedLighting ) ;
}
RenderTransparentRenderList ( cullResults , camera , renderLoop , "Forward" , Utilities . kRendererConfigurationBakedLighting ) ;
}
}
void RenderForwardUnlit ( CullResults cullResults , Camera camera , RenderLoop renderLoop )
// Bind material data
m_LitRenderLoop . Bind ( ) ;
// Bind material data
m_LitRenderLoop . Bind ( ) ;
RenderOpaqueRenderList ( cullResults , camera , renderLoop , "ForwardUnlit" ) ;
RenderTransparentRenderList ( cullResults , camera , renderLoop , "ForwardUnlit" ) ;
}
RenderOpaqueRenderList ( cullResults , camera , renderLoop , "ForwardUnlit" ) ;
RenderTransparentRenderList ( cullResults , camera , renderLoop , "ForwardUnlit" ) ;
}
}
void RenderVelocity ( CullResults cullResults , Camera camera , RenderLoop renderLoop )
// warning CS0162: Unreachable code detected // warning CS0429: Unreachable expression code detected
#pragma warning disable 162, 429
// If opaque velocity have been render during GBuffer no need to render it here
if ( ( ShaderConfig . VelocityInGbuffer = = 0 ) | | debugParameters . useForwardRenderingOnly )
return ;
// warning CS0162: Unreachable code detected // warning CS0429: Unreachable expression code detected
#pragma warning disable 162, 429
// If opaque velocity have been render during GBuffer no need to render it here
if ( ( ShaderConfig . VelocityInGbuffer = = 0 ) | | debugParameters . useForwardRenderingOnly )
return ;
int w = camera . pixelWidth ;
int h = camera . pixelHeight ;
int w = camera . pixelWidth ;
int h = camera . pixelHeight ;
cmd . GetTemporaryRT ( m_VelocityBuffer , w , h , 0 , FilterMode . Point , Builtin . RenderLoop . GetVelocityBufferFormat ( ) , Builtin . RenderLoop . GetVelocityBufferReadWrite ( ) ) ;
cmd . SetRenderTarget ( m_VelocityBufferRT , m_CameraDepthBufferRT ) ;
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
cmd . GetTemporaryRT ( m_VelocityBuffer , w , h , 0 , FilterMode . Point , Builtin . RenderLoop . GetVelocityBufferFormat ( ) , Builtin . RenderLoop . GetVelocityBufferReadWrite ( ) ) ;
cmd . SetRenderTarget ( m_VelocityBufferRT , m_CameraDepthBufferRT ) ;
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
RenderOpaqueRenderList ( cullResults , camera , renderLoop , "MotionVectors" ) ;
#pragma warning restore 162, 429
}
RenderOpaqueRenderList ( cullResults , camera , renderLoop , "MotionVectors" ) ;
#pragma warning restore 162, 429
}
}
void RenderDistortion ( CullResults cullResults , Camera camera , RenderLoop renderLoop )
int w = camera . pixelWidth ;
int h = camera . pixelHeight ;
int w = camera . pixelWidth ;
int h = camera . pixelHeight ;
cmd . GetTemporaryRT ( m_DistortionBuffer , w , h , 0 , FilterMode . Point , Builtin . RenderLoop . GetDistortionBufferFormat ( ) , Builtin . RenderLoop . GetDistortionBufferReadWrite ( ) ) ;
cmd . SetRenderTarget ( m_DistortionBufferRT , m_CameraDepthBufferRT ) ;
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
cmd . GetTemporaryRT ( m_DistortionBuffer , w , h , 0 , FilterMode . Point , Builtin . RenderLoop . GetDistortionBufferFormat ( ) , Builtin . RenderLoop . GetDistortionBufferReadWrite ( ) ) ;
cmd . SetRenderTarget ( m_DistortionBufferRT , m_CameraDepthBufferRT ) ;
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
// Only transparent object can render distortion vectors
RenderTransparentRenderList ( cullResults , camera , renderLoop , "DistortionVectors" ) ;
}
// Only transparent object can render distortion vectors
RenderTransparentRenderList ( cullResults , camera , renderLoop , "DistortionVectors" ) ;
}
}
{
// Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that
const float blackIn = 0.02f ;
const float whiteIn = 1 0.0f ;
const float blackOut = 0.0f ;
const float whiteOut = 1 0.0f ;
const float whiteLevel = 5.3f ;
const float whiteClip = 1 0.0f ;
const float dialUnits = 2 0.0f ;
const float halfDialUnits = dialUnits * 0.5f ;
// Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that
const float blackIn = 0.02f ;
const float whiteIn = 1 0.0f ;
const float blackOut = 0.0f ;
const float whiteOut = 1 0.0f ;
const float whiteLevel = 5.3f ;
const float whiteClip = 1 0.0f ;
const float dialUnits = 2 0.0f ;
const float halfDialUnits = dialUnits * 0.5f ;
// converting from artist dial units to easy shader-lerps (0-1)
var tonemapCoeff1 = new Vector4 ( ( blackIn * dialUnits ) + 1.0f , ( blackOut * halfDialUnits ) + 1.0f , ( whiteIn / dialUnits ) , ( 1.0f - ( whiteOut / dialUnits ) ) ) ;
var tonemapCoeff2 = new Vector4 ( 0.0f , 0.0f , whiteLevel , whiteClip / halfDialUnits ) ;
// converting from artist dial units to easy shader-lerps (0-1)
var tonemapCoeff1 = new Vector4 ( ( blackIn * dialUnits ) + 1.0f , ( blackOut * halfDialUnits ) + 1.0f , ( whiteIn / dialUnits ) , ( 1.0f - ( whiteOut / dialUnits ) ) ) ;
var tonemapCoeff2 = new Vector4 ( 0.0f , 0.0f , whiteLevel , whiteClip / halfDialUnits ) ;
m_FinalPassMaterial . SetVector ( "_ToneMapCoeffs1" , tonemapCoeff1 ) ;
m_FinalPassMaterial . SetVector ( "_ToneMapCoeffs2" , tonemapCoeff2 ) ;
m_FinalPassMaterial . SetVector ( "_ToneMapCoeffs1" , tonemapCoeff1 ) ;
m_FinalPassMaterial . SetVector ( "_ToneMapCoeffs2" , tonemapCoeff2 ) ;
m_FinalPassMaterial . SetFloat ( "_EnableToneMap" , debugParameters . enableTonemap ? 1.0f : 0.0f ) ;
m_FinalPassMaterial . SetFloat ( "_Exposure" , debugParameters . exposure ) ;
m_FinalPassMaterial . SetFloat ( "_EnableToneMap" , debugParameters . enableTonemap ? 1.0f : 0.0f ) ;
m_FinalPassMaterial . SetFloat ( "_Exposure" , debugParameters . exposure ) ;
// Resolve our HDR texture to CameraTarget.
cmd . Blit ( m_CameraColorBufferRT , BuiltinRenderTextureType . CameraTarget , m_FinalPassMaterial , 0 ) ;
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
}
// Resolve our HDR texture to CameraTarget.
cmd . Blit ( m_CameraColorBufferRT , BuiltinRenderTextureType . CameraTarget , m_FinalPassMaterial , 0 ) ;
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
}
}
// Function to prepare light structure for GPU lighting
m_LitRenderLoop . RenderInit ( renderLoop ) ;
}
if ( m_Dirty )
{
Rebuild ( ) ;
}
// Do anything we need to do upon a new frame.
NewFrame ( ) ;
ShadowOutput shadows ;
using ( new Utilities . ProfilingSample ( "Shadow Pass" , renderLoop ) )
{
m_ShadowPass . Render ( renderLoop , cullResults , out shadows ) ;
m_ShadowPass . Render ( renderLoop , cullResults , out shadows ) ;
}
renderLoop . SetupCameraProperties ( camera ) ; // Need to recall SetupCameraProperties after m_ShadowPass.Render