whoimi

A geek blog

View on GitHub

代码结构

hdrp的所有渲染过程描述在HDRenderPipeline类的Render方法当中:

namespace UnityEngine.Experimental.Rendering.HDPipeline
{
	public class HDRenderPipeline {
	...
		 public override void Render(
		 	ScriptableRenderContext renderContext, Camera[] cameras
		 	)
	...
	}
}

Render方法

render方法当中的主要输入的ScriptableRenderContext和Camera列表:

ScriptableRenderContext:定义状态、收集渲染命令。

摄像机列表

render主要过程

收件进行物体剪裁

然后调用一系列DrawRenderers和CommandBuffer

最终提交

public override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
{
  	//调用父类方法
  	base.Render(renderContext, cameras);
  
  	//渲染时间控制
    {

    }
  
  	// 渲染平面反射 :统计需要渲染的反射类型:反射探针 和 平面反射
  	// 通过深层调用可以发现最终调用的是 renderCamera.Render();
    ReflectionSystem.RenderAllRealtimeProbes(probeTypeToRender);
  
  	// 更新HDRP assets 设置
    m_Asset.UpdateDirtyFrameSettings();
  
    // 为每个摄像机循环渲染
    foreach (var camera in cameras)
    {
      RenderPipeline.BeginCameraRendering(camera);
    }
}

为每个摄像机循环渲染

准备设置参数

if (camera == null) continue;

// 首先从摄像机上获取摄像机设置。
var additionalCameraData = camera.GetComponent<HDAdditionalCameraData>();
FrameSettings srcFrameSettings;
// 如果有这个组件则从组件当中获取最新设置FrameSettings。
if (additionalCameraData)
{                additionalCameraData.UpdateDirtyFrameSettings(assetFrameSettingsIsDirty, m_Asset.GetFrameSettings());
 srcFrameSettings = additionalCameraData.GetFrameSettings();
 }
// 如果没有则从HDRenderPipelineAsset中获取设置
else
{
    srcFrameSettings = m_Asset.GetFrameSettings();
}

//  根据各方面内容初始化帧设置。
   FrameSettings currentFrameSettings = new FrameSettings();
 FrameSettings.InitializeFrameSettings(camera, m_Asset.GetRenderPipelineSettings(), srcFrameSettings, ref currentFrameSettings);


//初始化commandbuffer来提交主要的渲染命令
var cmd = CommandBufferPool.Get("");

// 完全自定义内容的摄像机,不进入渲染过程
if (additionalCameraData 
&& additionalCameraData.renderingPath == HDAdditionalCameraData.RenderingPath.FullscreenPassthrough)
{
  // 直接提交一个空的command buffer执行
  // 这里思考一下我们的Command在哪里起作用
  renderContext.ExecuteCommandBuffer(cmd);
  CommandBufferPool.Release(cmd);
  renderContext.Submit();
  continue;
}

// 渲染反射:如果注意就可以发现,上面也有一个RenderAllRealtimeViewerDependentProbes区别在于上面的没有提供摄像机,一个是静态的、一个是为当前摄像机渲染的动态的。
if (camera.cameraType != CameraType.Reflection && camera.cameraType != CameraType.Preview && !camera.orthographic) ReflectionSystem.RenderAllRealtimeViewerDependentProbesFor(ReflectionProbeType.PlanarReflection, camera);

/*
可以查看反射探针和镜面反射探针,都保存在下面的数组中
m_PlanarReflectionProbe_PerCamera_RealtimeUpdate
m_PlanarReflectionProbe_RealtimeUpdate_WorkArray
*/

// 初始化材质资源,材质列表中每个材质需要的资源初始化。用cmd来申请
// m_MaterialList如何填充的?
foreach (var material in m_MaterialList)
   material.RenderInit(cmd);

// 使用ProfilingSamplig采样渲染
// 填充CommandBuffer来指定渲染过程
using (new ProfilingSample(cmd, "HDRenderPipeline::Render", CustomSamplerId.HDRenderPipelineRender.GetSampler()))
{
   
}

// 执行组装好的CommandBuffer
renderContext.ExecuteCommandBuffer(cmd);
// 释放
CommandBufferPool.Release(cmd);
// 提交
renderContext.Submit();

// 和调试相关的内容暂时忽略
if (m_CurrentDebugDisplaySettings.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceTracing)
{
}

填充CommandBuffer来指定渲染过程


// 初始化设置  @@
m_LightLoop.NewFrame(currentFrameSettings);

// 根据摄像机类型设置m_CurrentDebugDisplaySettings
if (camera.cameraType == CameraType.Reflection || camera.cameraType == CameraType.Preview)
{
  m_CurrentDebugDisplaySettings = s_NeutralDebugDisplaySettings;
}
else
{
  m_CurrentDebugDisplaySettings = m_DebugDisplaySettings;
}

// Volume相关的处理
using (new ProfilingSample(cmd, "Volume Update", CustomSamplerId.VolumeUpdate.GetSampler()))
{
}

// 或处理判断
var postProcessLayer = camera.GetComponent<PostProcessLayer>();
// Disable post process if we enable debug mode or if the post process layer is disabled
if (m_CurrentDebugDisplaySettings.IsDebugDisplayRemovePostprocess() || !HDUtils.IsPostProcessingActive(postProcessLayer))
{
  currentFrameSettings.enablePostprocess = false;
}
// 摄像机HDCamera设置,体积光系统?
var hdCamera = HDCamera.Get(camera);
if (hdCamera == null)
{
  	hdCamera = HDCamera.Create(camera, m_VolumetricLightingSystem);
}
hdCamera.Update(currentFrameSettings, postProcessLayer, m_VolumetricLightingSystem);
Resize(hdCamera);
ApplyDebugDisplaySettings(hdCamera, cmd);
UpdateShadowSettings(hdCamera);
m_SkyManager.UpdateCurrentSkySettings(hdCamera);

剪裁

ScriptableCullingParameters cullingParams;
if (!CullResults.GetCullingParameters(camera, hdCamera.frameSettings.enableStereo, out cullingParams))
{
  renderContext.Submit();
  continue;
}
m_LightLoop.UpdateCullingParameters(ref cullingParams);
hdCamera.UpdateStereoDependentState(ref cullingParams);

####一堆看不懂的设置

if (hdCamera.frameSettings.enableDBuffer)
{
  // decal system needs to be updated with current camera, it needs it to set up culling and light list generation parameters
  DecalSystem.instance.CurrentCamera = camera;
  DecalSystem.instance.BeginCull();
}

ReflectionSystem.PrepareCull(camera, m_ReflectionProbeCullResults);

using (new ProfilingSample(cmd, "CullResults.Cull", CustomSamplerId.CullResultsCull.GetSampler()))
{
  CullResults.Cull(ref cullingParams, renderContext, ref m_CullResults);
}

m_ReflectionProbeCullResults.Cull();

m_DbufferManager.EnableDBUffer = false;
using (new ProfilingSample(cmd, "DBufferPrepareDrawData", CustomSamplerId.DBufferPrepareDrawData.GetSampler()))
{
  if (hdCamera.frameSettings.enableDBuffer)
  {
    DecalSystem.instance.EndCull();
    m_DbufferManager.EnableDBUffer = true;              // mesh decals are renderers managed by c++ runtime and we have no way to query if any are visible, so set to true
    DecalSystem.instance.UpdateCachedMaterialData();    // textures, alpha or fade distances could've changed
    DecalSystem.instance.CreateDrawData();              // prepare data is separate from draw
    DecalSystem.instance.UpdateTextureAtlas(cmd);       // as this is only used for transparent pass, would've been nice not to have to do this if no transparent renderers are visible, needs to happen after CreateDrawData
  }
}
renderContext.SetupCameraProperties(camera, hdCamera.frameSettings.enableStereo);

PushGlobalParams(hdCamera, cmd, diffusionProfileSettings);

// TODO: Find a correct place to bind these material textures
// We have to bind the material specific global parameters in this mode
m_MaterialList.ForEach(material => material.Bind());

// Frustum cull density volumes on the CPU. Can be performed as soon as the camera is set up.
DensityVolumeList densityVolumes = m_VolumetricLightingSystem.PrepareVisibleDensityVolumeList(hdCamera, cmd, m_Time);

// Note: Legacy Unity behave like this for ShadowMask
// When you select ShadowMask in Lighting panel it recompile shaders on the fly with the SHADOW_MASK keyword.
// However there is no C# function that we can query to know what mode have been select in Lighting Panel and it will be wrong anyway. Lighting Panel setup what will be the next bake mode. But until light is bake, it is wrong.
// Currently to know if you need shadow mask you need to go through all visible lights (of CullResult), check the LightBakingOutput struct and look at lightmapBakeType/mixedLightingMode. If one light have shadow mask bake mode, then you need shadow mask features (i.e extra Gbuffer).
// It mean that when we build a standalone player, if we detect a light with bake shadow mask, we generate all shader variant (with and without shadow mask) and at runtime, when a bake shadow mask light is visible, we dynamically allocate an extra GBuffer and switch the shader.
// So the first thing to do is to go through all the light: PrepareLightsForGPU
bool enableBakeShadowMask;
using (new ProfilingSample(cmd, "TP_PrepareLightsForGPU", CustomSamplerId.TPPrepareLightsForGPU.GetSampler()))
{
  enableBakeShadowMask = m_LightLoop.PrepareLightsForGPU(cmd, hdCamera, m_ShadowSettings, m_CullResults, m_ReflectionProbeCullResults, densityVolumes);
}
ConfigureForShadowMask(enableBakeShadowMask, cmd);

正式开始渲染:必要部分1

StartStereoRendering(renderContext, hdCamera);
ClearBuffers(hdCamera, cmd);

// 预先深度
RenderDepthPrepass(m_CullResults, hdCamera, renderContext, cmd);

// 渲染深度给Decal使用
RenderDBuffer(hdCamera, cmd, renderContext, m_CullResults);

// 渲染Gbuffer
RenderGBuffer(m_CullResults, hdCamera, enableBakeShadowMask, renderContext, cmd);

// 绑定NormalBuffer到某个外部纹理??
m_NormalBufferManager.BindNormalBuffers(cmd);

// 渲染深度和深度金字塔
CopyDepthBufferIfNeeded(cmd);
RenderDepthPyramid(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);

// 渲染MotionVector??
RenderObjectsVelocity(m_CullResults, hdCamera, renderContext, cmd);
RenderCameraVelocity(m_CullResults, hdCamera, renderContext, cmd);

// 设置全局的深度纹理
cmd.SetGlobalTexture(HDShaderIDs._CameraDepthTexture, GetDepthTexture());

// 天空盒更新
UpdateSkyEnvironment(hdCamera, cmd);

StopStereoRendering(renderContext, hdCamera);

if (m_CurrentDebugDisplaySettings.IsDebugMaterialDisplayEnabled())
{
  RenderDebugViewMaterial(m_CullResults, hdCamera, renderContext, cmd);

  PushColorPickerDebugTexture(cmd, m_CameraColorBuffer, hdCamera);
}
else
{
  //正式开始渲染:必要部分2
}

####正式开始渲染:必要部分2

StartStereoRendering(renderContext, hdCamera);

using (new ProfilingSample(cmd, "Render SSAO", CustomSamplerId.RenderSSAO.GetSampler()))
{
	//渲染SSAO,屏幕空间环境光,这里需要PostProcessing???
  RenderSSAO(cmd, hdCamera, renderContext, postProcessLayer);
}


// FeatureVariamts ??? 和Stencil相关
if (m_LightLoop.GetFeatureVariantsEnabled())
{
  // For material classification we use compute shader and so can't read into the stencil, so prepare it.
  using (new ProfilingSample(cmd, "Clear and copy stencil texture", CustomSamplerId.ClearAndCopyStencilTexture.GetSampler()))
  {
    HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraStencilBufferCopy, ClearFlag.Color, CoreUtils.clearColorAllBlack);

    // In the material classification shader we will simply test is we are no lighting
    // Use ShaderPassID 1 => "Pass 1 - Write 1 if value different from stencilRef to output"
    HDUtils.DrawFullScreen(cmd, hdCamera, m_CopyStencilForNoLighting, m_CameraStencilBufferCopy, m_CameraDepthStencilBuffer, null, 1);
  }
}

StopStereoRendering(renderContext, hdCamera);

// 异步计算阴影??
GPUFence buildGPULightListsCompleteFence = new GPUFence();
if (hdCamera.frameSettings.enableAsyncCompute)
{
  GPUFence startFence = cmd.CreateGPUFence();
  renderContext.ExecuteCommandBuffer(cmd);
  cmd.Clear();

  buildGPULightListsCompleteFence = m_LightLoop.BuildGPULightListsAsyncBegin(hdCamera, renderContext, m_CameraDepthStencilBuffer, m_CameraStencilBufferCopy, startFence, m_SkyManager.IsLightingSkyValid());
}

//正式开始渲染:必要部分3 

####正式开始渲染:必要部分3

 // 渲染阴影
using (new ProfilingSample(cmd, "Render shadows", CustomSamplerId.RenderShadows.GetSampler()))
{
  m_LightLoop.RenderShadows(renderContext, cmd, m_CullResults);

  // Overwrite camera properties set during the shadow pass with the original camera properties.
  renderContext.SetupCameraProperties(camera, hdCamera.frameSettings.enableStereo);
  hdCamera.SetupGlobalParams(cmd, m_Time, m_LastTime, m_FrameCount);
  if (hdCamera.frameSettings.enableStereo)
    hdCamera.SetupGlobalStereoParams(cmd);
}

// 渲染deffered直接阴影
using (new ProfilingSample(cmd, "Deferred directional shadows", CustomSamplerId.RenderDeferredDirectionalShadow.GetSampler()))
{
    // When debug is enabled we need to clear otherwise we may see non-shadows areas with stale values.
    if (m_CurrentDebugDisplaySettings.fullScreenDebugMode == FullScreenDebugMode.DeferredShadows)
    {
      HDUtils.SetRenderTarget(cmd, hdCamera, m_DeferredShadowBuffer, ClearFlag.Color, CoreUtils.clearColorAllBlack);
    }

    m_LightLoop.RenderDeferredDirectionalShadow(hdCamera, m_DeferredShadowBuffer, GetDepthTexture(), cmd);
    PushFullScreenDebugTexture(hdCamera, cmd, m_DeferredShadowBuffer, FullScreenDebugMode.DeferredShadows);
}

// 异步计算阴影结束?
if (hdCamera.frameSettings.enableAsyncCompute)
{
  m_LightLoop.BuildGPULightListAsyncEnd(hdCamera, cmd, buildGPULightListsCompleteFence);
}
else
{
  // 配置光照列表
  using (new ProfilingSample(cmd, "Build Light list", CustomSamplerId.BuildLightList.GetSampler()))
  {
    m_LightLoop.BuildGPULightLists(hdCamera, cmd, m_CameraDepthStencilBuffer, m_CameraStencilBufferCopy, m_SkyManager.IsLightingSkyValid());
  }
}

// 和体积光相关的雾参数
{
  // Set fog parameters for volumetric lighting.
  var visualEnv = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
  visualEnv.PushFogShaderParameters(hdCamera, cmd);
}

// 体素化阶段
m_VolumetricLightingSystem.VolumeVoxelizationPass(hdCamera, cmd, m_FrameCount, densityVolumes);

// 渲染体积光
m_VolumetricLightingSystem.VolumetricLightingPass(hdCamera, cmd, m_FrameCount);

// 渲染延迟光照
RenderDeferredLighting(hdCamera, cmd);

// Might float this higher if we enable stereo w/ deferred
StartStereoRendering(renderContext, hdCamera);

// 渲染前向物体
RenderForward(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Opaque);

// SSS pass here handle both SSS material from deferred and forward
m_SSSBufferManager.SubsurfaceScatteringPass(hdCamera, cmd, diffusionProfileSettings,m_CameraColorBuffer, m_CameraSssDiffuseLightingBuffer, m_CameraDepthStencilBuffer, GetDepthTexture());

// 渲染天空
RenderSky(hdCamera, cmd);

// 渲染每一个反射物体
RenderForward(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.PreRefraction);

// 渲染颜色金字塔
RenderColorPyramid(hdCamera, cmd, renderContext, true);

// 渲染前向物体
// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
RenderForward(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Transparent);

// 渲染错误
// Render All forward error
RenderForwardError(m_CullResults, hdCamera, renderContext, cmd);

// Fill depth buffer to reduce artifact for transparent object during postprocess
// 给后处理渲染透明物体的深度
RenderTransparentDepthPostpass(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Transparent);

// 渲染颜色金字塔2
RenderColorPyramid(hdCamera, cmd, renderContext, false);

// ??
AccumulateDistortion(m_CullResults, hdCamera, renderContext, cmd);
RenderDistortion(hdCamera, cmd, m_Asset.renderPipelineResources);

StopStereoRendering(renderContext, hdCamera);

// 测设相关
PushFullScreenDebugTexture(hdCamera, cmd, m_CameraColorBuffer, FullScreenDebugMode.NanTracker);
PushColorPickerDebugTexture(hdCamera, cmd, m_CameraColorBuffer);

StartStereoRendering(renderContext, hdCamera);

// 后处理
// Final blit
if (hdCamera.frameSettings.enablePostprocess)
{
  RenderPostProcess(hdCamera, cmd, postProcessLayer);
}
else
{
  using (new ProfilingSample(cmd, "Blit to final RT", CustomSamplerId.BlitToFinalRT.GetSampler()))
  {
    // This Blit will flip the screen on anything other than openGL
    HDUtils.BlitCameraTexture(cmd, hdCamera, m_CameraColorBuffer, BuiltinRenderTextureType.CameraTarget);
  }
}

StopStereoRendering(renderContext, hdCamera);
// Pushes to XR headset and/or display mirror
if (hdCamera.frameSettings.enableStereo)
  renderContext.StereoEndRender(hdCamera.camera);

具体渲染方法

RenderDepthPrepass

渲染内容:根据渲染设置提前渲染深度。

在Deferred渲染过程中,我们可以使用Forward不透明材质,这些材质需要渲染深度,来得到正确的灯光列表

之后再Deferred光照阶段(deferred lighting pass),不去渲染这些forward的不透明材质。

在deferred模式下,默认是没有forward不透明物体的。但是如果有了,就需要ForwardOnly强行渲染不透明物体。这时候Forward没用,只有FOrwardOnly有用。同时也需要有DepthForwardOnly。

如果forward材质没有深度,则光照可能不正确。

// Forward material always output normal buffer (unless they don’t participate to shading)

// Deferred material never output normal buffer

//Asset当中开启了Forward Only,则只会渲染前向物体。则depthonly 和depthforwardonly都会渲染。
if (hdCamera.frameSettings.enableForwardRenderingOnly)
{
  HDUtils.SetRenderTarget 设置渲染目标
  // Full forward: Output normal buffer for both forward and forwardOnly
 RenderOpaqueRenderList(cull, // 剪裁结果保存了所有Render
                        hdCamera, //摄像机参数
                        renderContext,  // 渲染上下文
                        cmd, 
                        // 需要渲染的pass ,所有深度pass都会渲染
                        m_DepthOnlyAndDepthForwardOnlyPassNames,
                        0, 
                        // 渲染队列
                        HDRenderQueue.k_RenderQueue_AllOpaque);
}
// 如果是deferred render的物体(也就是没有开启Forward Only设置)开启了DepthPrepass,或者开启了深度DBuffer,就会给Deferred渲染的物体也进行prepass深度渲染,一般主需要渲染forward的深度就可以。
else if (hdCamera.frameSettings.enableDepthPrepassWithDeferredRendering || m_DbufferManager.EnableDBUffer)
{
  HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraDepthStencilBuffer);
  // 用DepthOnly写入deferred的深度
  RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);

  	//与上面不同的是颜色缓存使用了法线 RTI(rendertexture index)也就是forward物体需要填充法线纹理。
  HDUtils.SetRenderTarget(cmd, hdCamera, 
                          m_NormalBufferManager.GetBuffersRTI(),
                          m_CameraDepthStencilBuffer);

  // 用DepthForwardOnly写入Forward物体的深度
  RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);

}
else // Deferred with partial depth prepass
{
  cmd.DisableShaderKeyword("WRITE_NORMAL_BUFFER");
// 给Deferred alpha tested materials必须渲染prepass。
  HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraDepthStencilBuffer);
  var renderQueueRange = new RenderQueueRange { min = (int)RenderQueue.AlphaTest, max = (int)RenderQueue.GeometryLast - 1 };
  RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthOnlyPassNames, 0, renderQueueRange);

  HDUtils.SetRenderTarget(cmd, hdCamera, m_NormalBufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer);
// 在deferred 模式下强行渲染Forward不透明物体,需要有DepthForwardonlyPath,否则光照错误。
  RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);

}

// 透明物体的Prepass
if (hdCamera.frameSettings.enableTransparentPrepass)
{
	RenderTransparentRenderList(cull, hdCamera, 
                                renderContext, 
                                cmd, 
                                m_TransparentDepthPrepassNames);
}

RenderDBuffer

如果需要深度贴图则绑定一个DBuffer,需要接受Decal的也在这里渲染

//如果开启Dbuffer
if (!hdCamera.frameSettings.enableDBuffer)
  return;


  // We need to copy depth buffer texture if we want to bind it at this stage
// 复制了一份CameraDepthStencil
  CopyDepthBufferIfNeeded(cmd);

  // Depth texture is now ready, bind it. 把复制得到的深度设置成全局深度
// _CameraDepthTexture在这里生产
  cmd.SetGlobalTexture(HDShaderIDs._CameraDepthTexture, GetDepthTexture());
  m_DbufferManager.ClearTargets(cmd, hdCamera);
  HDUtils.SetRenderTarget(cmd, hdCamera, m_DbufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer); // do not clear anymore
  m_DbufferManager.SetHTile(m_DbufferManager.bufferCount, cmd);
  renderContext.ExecuteCommandBuffer(cmd);
  cmd.Clear();

// 渲染空pass  绘制DBufferMesh Pass decal?
// 使用——MeshDecalsPass 渲染一个_DecalHTileTexture纹理
  DrawRendererSettings drawSettings = new DrawRendererSettings(hdCamera.camera, HDShaderPassNames.s_EmptyName)
  {
    rendererConfiguration = 0,
    sorting = { flags = SortFlags.CommonOpaque }
  };
  drawSettings.SetShaderPassName(0, HDShaderPassNames.s_MeshDecalsName);
  FilterRenderersSettings filterRenderersSettings = new FilterRenderersSettings(true)
  {
    renderQueueRange = HDRenderQueue.k_RenderQueue_AllOpaque
  };
// 渲染需要接受decal的物体
  renderContext.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, filterRenderersSettings);

// 渲染Decal到Dbuffer  HtileDepth?
  DecalSystem.instance.RenderIntoDBuffer(cmd);
  m_DbufferManager.UnSetHTile(cmd);
  m_DbufferManager.SetHTileTexture(cmd);  // mask per 8x8 tile used for optimization when looking up dbuffer values

RenderGBuffer

// 只渲染前向物体
if (hdCamera.frameSettings.enableForwardRenderingOnly)
  return;
// 设置Gbuffer目标,和深度
HDUtils.SetRenderTarget(cmd, hdCamera, m_GbufferManager.GetBuffersRTI(enableShadowMask), m_CameraDepthStencilBuffer);
// 进行渲染,渲染的过程填充深度
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, HDShaderPassNames.s_GBufferName, m_currentRendererConfigurationBakedLighting, HDRenderQueue.k_RenderQueue_AllOpaque);
// 设置Gbuffer _GBufferTexture0 - 4
m_GbufferManager.BindBufferAsTextures(cmd);

RenderDepthPyramid

computeShader计算深度金字塔

RenderObjectsVelocity

渲染物体速度

RenderCameraVelocity

渲染摄像机速度

##cmd.SetGlobalTexture();

设置全局深度贴图

RenderSSAO

SSAO, Shadow, Build light list, deferred shadow, material and light classification can be parallelize with Async compute

同时计算各种效果

m_VolumetricLightingSystem

和体积光相关的操作

m_LightLoop.RenderShadows

渲染阴影

m_LightLoop.RenderDeferredDirectionalShadow

RenderDeferredLighting

计算deferred物体光照

实现了ComputeShader和Shader两个版本的Deferred计算。

RenderForward

ForwardPass.Opaque Pass

在不同模式下的渲染:

在RenderForward的过程中,渲染那个pass会根据设置不同发生改变。

如果启用ForwardOnly Rnedering,那么Forward和ForwardOnly就都会渲染,无论是不透明物体还是透明物体。

如果是Deferred模式,那么对于transparent Forward和ForwardOnly就都会渲染,对于opaque就只会渲染ForwardOnly。

所以ForwardOnly 和Forward是互斥的。

// Debug相关内容
string profileName;
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled())
{
  profileName = k_ForwardPassDebugName[(int)pass];
}
else
{
  profileName = k_ForwardPassName[(int)pass];
}


// 获取摄像机
var camera = hdCamera.camera;

// ???????
m_LightLoop.RenderForward(camera, cmd, pass == ForwardPass.Opaque);

// 屏幕空间Tracing
var debugScreenSpaceTracing = m_CurrentDebugDisplaySettings.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceTracing;

// 不透明物体
if (pass == ForwardPass.Opaque)
{
  // 使用SSS效果
  if (hdCamera.frameSettings.enableSubsurfaceScattering)
  {
    RenderTargetIdentifier[] m_MRTWithSSS = new RenderTargetIdentifier[2 + m_SSSBufferManager.sssBufferCount];
    // 准备所有的SSS需要的buffer
    m_MRTWithSSS[0] = m_CameraColorBuffer; // Store the specular color
    m_MRTWithSSS[1] = m_CameraSssDiffuseLightingBuffer;
    
    for (int i = 0; i < m_SSSBufferManager.sssBufferCount; ++i)
    {
      m_MRTWithSSS[i + 2] = m_SSSBufferManager.GetSSSBuffer(i);
    }

    HDUtils.SetRenderTarget(cmd, hdCamera, m_MRTWithSSS, m_CameraDepthStencilBuffer);
  }
  else
  {
	//不使用SSS效果,则就是用一般的Depth和COlorbuffer
    HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraColorBuffer, m_CameraDepthStencilBuffer);
  }

  //根据渲染设置使用不同的Forwardpass  : ForwardOnly Or Forward
  var passNames = hdCamera.frameSettings.enableForwardRenderingOnly
    ? m_ForwardAndForwardOnlyPassNames
    : m_ForwardOnlyPassNames;
  // 调试模式
  var debugSSTThisPass = debugScreenSpaceTracing && (m_CurrentDebugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.ScreenSpaceTracingReflection);

  if (debugSSTThisPass)
    cmd.SetRandomWriteTarget(7, m_DebugScreenSpaceTracingData);
  
  // 渲染不透明物体
  RenderOpaqueRenderList(cullResults, hdCamera, renderContext, cmd, passNames, m_currentRendererConfigurationBakedLighting);
  
  if (debugSSTThisPass)
    cmd.ClearRandomWriteTargets();
}
//渲染透明物体
else
{
  // 设置透明物体渲染目标
  HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraColorBuffer, m_CameraDepthStencilBuffer);
  // 使用dbuffer 并且有Decal 则SetAtlas????
  if ((hdCamera.frameSettings.enableDBuffer) && (DecalSystem.m_DecalDatasCount > 0)) 
  {
    DecalSystem.instance.SetAtlas(cmd); // for clustered decals
  }

  var debugSSTThisPass = debugScreenSpaceTracing && (m_CurrentDebugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.ScreenSpaceTracingRefraction);
  if (debugSSTThisPass)
    cmd.SetRandomWriteTarget(7, m_DebugScreenSpaceTracingData);
  
  // 渲染透明物体
  RenderTransparentRenderList(cullResults, hdCamera, renderContext, cmd, m_AllTransparentPassNames, m_currentRendererConfigurationBakedLighting, pass == ForwardPass.PreRefraction ? HDRenderQueue.k_RenderQueue_PreRefraction : HDRenderQueue.k_RenderQueue_Transparent);
  
  if (debugSSTThisPass)
    cmd.ClearRandomWriteTargets();
}

//渲染的ShaderPass
   var passNames = hdCamera.frameSettings.enableForwardRenderingOnly
                        ? m_ForwardAndForwardOnlyPassNames
                        : m_ForwardOnlyPassNames;

// HDShaderPassNames.s_SRPDefaultUnlitName  是一个FallBack
ShaderPassName[] m_ForwardAndForwardOnlyPassNames = { HDShaderPassNames.s_ForwardOnlyName, 
                                                     HDShaderPassNames.s_ForwardName, 
                                                     HDShaderPassNames.s_SRPDefaultUnlitName };
ShaderPassName[] m_ForwardOnlyPassNames = { HDShaderPassNames.s_ForwardOnlyName, 
                                           HDShaderPassNames.s_SRPDefaultUnlitName };

// 渲染队列
RenderQueueRange k_RenderQueue_AllOpaque = new RenderQueueRange { 
  min = (int)Priority.Opaque,    2000
  max = (int)Priority.OpaqueLast }; 2500

RenderSky

RenderForward

forwardPass.PreRefraction Pass

//渲染的pass
ShaderPassName[] m_AllTransparentPassNames = {  HDShaderPassNames.s_TransparentBackfaceName,
                                                        HDShaderPassNames.s_ForwardOnlyName,
                                                        HDShaderPassNames.s_ForwardName,
                                                        HDShaderPassNames.s_SRPDefaultUnlitName };
// 渲染队列
 public static readonly RenderQueueRange k_RenderQueue_Transparent = new RenderQueueRange { 
   min = (int)Priority.PreRefractionFirst,  2750 - 100
   max = (int)Priority.PreRefractionLast }; 2750 + 100

RenderColorPyramid

Gpu计算,会根据是否需要Bloom,Distortion,SSR等内容来判断是否使用。

 RenderColorPyramid(hdCamera, cmd, renderContext, true);

RenderForward

ForwardPass.Transparent Pass

ShaderPassName[] m_AllTransparentPassNames = {  							HDShaderPassNames.s_TransparentBackfaceName,
                                                        HDShaderPassNames.s_ForwardOnlyName,
                                                        HDShaderPassNames.s_ForwardName,
                                                        HDShaderPassNames.s_SRPDefaultUnlitName };

//渲染队列
 public static readonly RenderQueueRange k_RenderQueue_PreRefraction = new RenderQueueRange { min = (int)Priority.TransparentFirst,     3000 - 100
max = (int)Priority. TransparentLast};    3000 + 100

##RednerTransparentDepthPostpass

if (!hdCamera.frameSettings.enableTransparentPostpass)
return;


HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraDepthStencilBuffer);
RenderTransparentRenderList(cullResults, hdCamera, renderContext, cmd, m_TransparentDepthPostpassNames);

//使用Pass
TransparentDepthPostpass

##RenderColorPyramid

RenderColorPyramid(hdCamera, cmd, renderContext, false); 

渲染错误的Pass

都是之前遗留的PassName

    public static readonly ShaderPassName s_AlwaysName = new ShaderPassName("Always");
    public static readonly ShaderPassName s_ForwardBaseName = new ShaderPassName("ForwardBase");
    public static readonly ShaderPassName s_DeferredName = new ShaderPassName("Deferred");
    public static readonly ShaderPassName s_PrepassBaseName = new ShaderPassName("PrepassBase");
    public static readonly ShaderPassName s_VertexName = new ShaderPassName("Vertex");
    public static readonly ShaderPassName s_VertexLMRGBMName = new ShaderPassName("VertexLMRGBM");
    public static readonly ShaderPassName s_VertexLMName = new ShaderPassName("VertexLM"); ## AccumulateDistortion & RenderDistortion

失真计算?

RenderPostProcess

后处理

进一步调用

RenderOpaqueRenderList

void RenderTransparentRenderList(CullResults cull,
            HDCamera hdCamera,
            ScriptableRenderContext renderContext,
            CommandBuffer cmd,
            ShaderPassName passName,
            RendererConfiguration rendererConfiguration = 0,
            RenderQueueRange? inRenderQueueRange = null,
            RenderStateBlock? stateBlock = null,
            Material overrideMaterial = null
                                 
void RenderTransparentRenderList(CullResults cull,
            HDCamera hdCamera,
            ScriptableRenderContext renderContext,
            CommandBuffer cmd, 
            ShaderPassName[] passName,   //  多个pass
            RendererConfiguration rendererConfiguration = 0,
            RenderQueueRange? inRenderQueueRange = null,
            RenderStateBlock? stateBlock = null,
            Material overrideMaterial = null
// 想要渲染不都名物体 
if (!hdCamera.frameSettings.enableOpaqueObjects)
     return;
// DrawRender 不再Command当中渲染,所以想把之前的做完。
renderContext.ExecuteCommandBuffer(cmd);
cmd.Clear();

// 设置绘制参数,排序方式
var drawSettings = new DrawRendererSettings(hdCamera.camera, HDShaderPassNames.s_EmptyName)
{
  rendererConfiguration = rendererConfiguration,
  sorting = { flags = SortFlags.CommonOpaque }
};

// 收集需要渲染的pass Name
for (int i = 0; i < passNames.Length; ++i)
{
  drawSettings.SetShaderPassName(i, passNames[i]);
}

// 设置全局材质,渲染某些通用效果的时候使用
if (overrideMaterial != null)
  drawSettings.SetOverrideMaterial(overrideMaterial, 0);

// 渲染队列,指定还是范围
var filterSettings = new FilterRenderersSettings(true)
{
  renderQueueRange = inRenderQueueRange == null ? 
    HDRenderQueue.k_RenderQueue_AllOpaque : inRenderQueueRange.Value
      //2000 -  2500
};

if (stateBlock == null)
  renderContext.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);
else
  renderContext.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings, stateBlock.Value);

###RenderTransparentRenderList

初始化与HDRenderPipelineAsset