zoukankan      html  css  js  c++  java
  • URP学习之四--各类Pass

    上次我们了解了URP大致的框架,接下来看看每个Pass都是做什么的,先看DrawObjectPass:

     从截图中我们可以看到这个Pass主要用于渲染不透明物体和半透明物体(ForwardPath)。

    首先我们看一下这个Pass的构造:

    public DrawObjectsPass(
          string profilerTag,
          bool opaque,
          RenderPassEvent evt,
          RenderQueueRange renderQueueRange,
          LayerMask layerMask,
          StencilState stencilState,
          int stencilReference)
        {
          this.m_ProfilerTag = profilerTag;
          this.m_ShaderTagIdList.Add(new ShaderTagId("UniversalForward"));
          this.m_ShaderTagIdList.Add(new ShaderTagId("LightweightForward"));
          this.m_ShaderTagIdList.Add(new ShaderTagId("SRPDefaultUnlit"));
          this.renderPassEvent = evt;
          this.m_FilteringSettings = new FilteringSettings(new RenderQueueRange?(renderQueueRange), (int) layerMask, uint.MaxValue, 0);
          this.m_RenderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
          this.m_IsOpaque = opaque;
          if (!stencilState.enabled)
            return;
          this.m_RenderStateBlock.stencilReference = stencilReference;
          this.m_RenderStateBlock.mask = RenderStateMask.Stencil;
          this.m_RenderStateBlock.stencilState = stencilState;
        }

    这个Pass会执行标有以上三个tag(UniversalForward、LightweightForward、SRPDefaultUnlit)的shaderPass。通过是否是Opaque决定这个Pass是用来渲染不透明物体还是半透明物体,最后初始化了模板测试相关数据。

    接下来是执行(Execute)方法:

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
          CommandBuffer commandBuffer = CommandBufferPool.Get(this.m_ProfilerTag);
          using (new ProfilingSample(commandBuffer, this.m_ProfilerTag, (CustomSampler) null))
          {
            context.ExecuteCommandBuffer(commandBuffer);
            commandBuffer.Clear();
            Camera camera = renderingData.cameraData.camera;
            SortingCriteria sortingCriteria = this.m_IsOpaque ? renderingData.cameraData.defaultOpaqueSortFlags : SortingCriteria.CommonTransparent;
            DrawingSettings drawingSettings = this.CreateDrawingSettings(this.m_ShaderTagIdList, ref renderingData, sortingCriteria);
            context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref this.m_FilteringSettings, ref this.m_RenderStateBlock);
            RenderingUtils.RenderObjectsWithError(context, ref renderingData.cullResults, camera, this.m_FilteringSettings, SortingCriteria.None);
          }
          context.ExecuteCommandBuffer(commandBuffer);
          CommandBufferPool.Release(commandBuffer);
        }

    这个方法和我们写SRP时基本一样,排序设置是根据Opaque字段决定,DrawSettings通过CreateDrawingSettings方法生成:

    public DrawingSettings CreateDrawingSettings(
          List<ShaderTagId> shaderTagIdList,
          ref RenderingData renderingData,
          SortingCriteria sortingCriteria)
        {
          if (shaderTagIdList == null || shaderTagIdList.Count == 0)
          {
            Debug.LogWarning((object) "ShaderTagId list is invalid. DrawingSettings is created with default pipeline ShaderTagId");
            return this.CreateDrawingSettings(new ShaderTagId("UniversalPipeline"), ref renderingData, sortingCriteria);
          }
          DrawingSettings drawingSettings = this.CreateDrawingSettings(shaderTagIdList[0], ref renderingData, sortingCriteria);
          for (int index = 1; index < shaderTagIdList.Count; ++index)
            drawingSettings.SetShaderPassName(index, shaderTagIdList[index]);
          return drawingSettings;
        }

    最后DrawRenderers,但是我们发现后面还有个RenderObjects方法,这个方法是对以前一些TagId做的兼容,有以下Tag:

    private static List<ShaderTagId> m_LegacyShaderPassNames = new List<ShaderTagId>()
        {
          new ShaderTagId("Always"),
          new ShaderTagId("ForwardBase"),
          new ShaderTagId("PrepassBase"),
          new ShaderTagId("Vertex"),
          new ShaderTagId("VertexLMRGBM"),
          new ShaderTagId("VertexLM")
        };

    我们会发现非常简短的代码,一个Pass就完成了,可见我们如果要扩展Pass也是方便的很(其实最关键是核心方法都被封装了,不需要我们操心,哈哈哈~)

    接下来我们看一下DepthOnlyPass,构造函数确定了FilterSettings和RenderEvent(过于简单,就不贴代码了),Setup函数如下:

    public void Setup(
          RenderTextureDescriptor baseDescriptor,
          RenderTargetHandle depthAttachmentHandle)
        {
          this.depthAttachmentHandle = depthAttachmentHandle;
          baseDescriptor.colorFormat = RenderTextureFormat.Depth;
          baseDescriptor.depthBufferBits = this.kDepthBufferBits;
          baseDescriptor.msaaSamples = 1;
          this.descriptor = baseDescriptor;
        }

    这里不了解RenderTextureDescriptor 结构的小伙伴可以去官方api查一下,里面记录的是对于RT的一些描述信息,depthBufferBits默认给的32bit。RenderTargetHandle结构主要记录了一个shader property id。

    接下来是一个Configure方法:

        public override void Configure(
          CommandBuffer cmd,
          RenderTextureDescriptor cameraTextureDescriptor)
        {
          cmd.GetTemporaryRT(this.depthAttachmentHandle.id, this.descriptor, FilterMode.Point);
          this.ConfigureTarget(this.depthAttachmentHandle.Identifier());
          this.ConfigureClear(ClearFlag.All, Color.black);
        }

    这个方法是获取RT,所有Pass的Configure方法都是在Pass的Execute方法之前执行,说到这里,笔者忽然发现这些Pass过于简单,没有什么好说的,于是大概看了看所有的Pass,挑笔者觉得重要的东西说一下吧:

    首先我们看一下Pass的执行顺序:

    MainLightShadowCasterPass、AdditionalLightsShadowCasterPass、DepthOnlyPass、ScreenSpaceShadowResolvePass、ColorGradingLutPass、OpaqueForwardPass、CopyDepthPass、DrawSkyboxPass、CopyColorPass、TransparentForwardPass、InvokeOnRenderObjectCallbackPass、PostProcessPass、CapturePass、FinalBlitPass。

    需要注意的是比默认管线多了CopyColor和CopyDepth两个步骤,这两个步骤对于我们做水面需要抓取color做折射的效果很有帮助,但是缺陷是无法多重折射,因为Color只有Opaque信息。

    ShadowCasterPass和ScreenSpaceShadowResolvePass熟悉屏幕空间阴影的实现的伙伴都很熟悉了,在这里就不赘述了。

    DepthOnlyPass主要绘制了有“DepthOnly” Tag的Pass,需要注意的是DepthOnly是可以AlphaClip的。

    CapturePass时所有渲染行为结束时的Pass,目前还不知道可以用来干什么。

    其他pass基本上见名知意。接下来的几节笔者会挑URP的几个shader一起学习一下,通过学习官方提供的shader,增加对URP渲染代码编写的熟练度,避免踩一些坑,也可以学习到不同问题下Unity官方的解决思路。

  • 相关阅读:
    hadoop mysql install (5)
    hadoop redis install (4)
    hadoop mongodb install(3)
    hadoop hbase install (2)
    水平交错效果显示图像
    实现推拉效果显示图片
    百叶窗效果显示图像
    以椭圆形显示图像
    图像的放大与缩小
    鼠标拖拽图像
  • 原文地址:https://www.cnblogs.com/shenyibo/p/12518017.html
Copyright © 2011-2022 走看看