Unity SRP系列——自定义渲染管道

实例原文:

Unity通用渲染管线(URP)系列(一)——自定义渲染管线 - 知乎 (zhihu.com)

Custom Render Pipeline (catlikecoding.com)

类图分析

管线资产

CustomRenderPipelineAsset

资产类型必须继承自RenderPipelineAsset,它是一个抽象类,提供了一个抽象方法:

protected abstract RenderPipeline CreatePipeline();

RP资产的主要目的是提供一种方法来获取负责渲染的管线的对象实例。资产本身只是一个句柄和存储设置的地方。我们还没有进行任何设置,所以所要做的就是给Unity一个获得管线对象实例的方法。通过重写抽象方法CreatePipeline方法来完成,该方法需要返回RenderPipeline实例。

渲染管线实例

建CustomRenderPipeline类,这将是我们的资产返回的RP实例所使用的类型,因此它必须从RenderPipeline继承。

RenderPipeline定义了一个受保护的抽象的Render方法,我们必须重写这个方法来创建一个具体的管线。

protected abstract void Render(ScriptableRenderContext context, Camera[] cameras);

它有两个参数:一个ScriptableRenderContext和一个Camera数组。暂时保持该方法为空。

CustomRenderPipelineAsset 的CreatePipeline方法中返回一个CustomRenderPipeline 新实例。他会给我们一个有效的,附带功能的管线实例,尽管它现在还没有提供任何功能。

渲染呈现

每一帧Unity都会调用RP实例的Render方法。它传递一个上下文结构,该结构会提供到当前引擎的连接,我们可以使用它来进行渲染。它也需要传递一个相机的数组,因为可以有多个活动相机在当前场景。按照提供的摄像机顺序进行渲染是RP的责任。

每个相机的渲染都是独立的。因此,与其让CustomRenderPipeline渲染所有摄像机,倒不如把这个责任转发给一个专门用于渲染单个摄像机的新类。将其命名为CameraRenderer,并给它一个带有上下文和照相机参数的公开的Public方法。

Cull剔除

并不是需要把每一个物体都画出来,我们只会渲染那些相机能看见的物体。所以从场景中所有有renderer组件的物体开始,然后剔除掉那些落在摄像机视野以外的物体。

找出什么可以被剔除需要我们跟踪多个相机设置和矩阵,可以使用ScriptableCullingParameters结构。这个结构可以在摄像机上调用TryGetCullingParameters,而不是自己去填充它。它返回是否可以成功检索该参数,因为它可能会获取失败。要获得参数数据,我们必须将其作为输出(out)参数提供,方法是在它前面写一个out。在返回成功或失败的单独的Cull方法中执行此操作。

Out关键字告诉我们,该方法负责正确设置参数,替换以前的值。
TryGet方法是表示成功或失败并产生结果的常见方法。

当用作输出参数时,可以在参数列表中内联变量声明,看看写法。

在“Render”中的“Setup”之前调用Cull,如果失败则中止。

实际的裁剪是通过调用上下文上的Cull来完成的,这会产生一个CullingResults结构。如果成功的话,可以在清除中执行此操作,并将结果存储在字段中。在这种情况下,我们必须将剔除参数作为引用参数传递,方法是在前面写ref。

SetUp

通过SetupCameraProperties方法将摄像机的属性应用于上下文。这会设置矩阵以及其他一些属性。

设置相机的清除标志ClearRenderTarget

 

DrawVisibleGeometry画几何

一旦我们知道什么是可见的,我们就可以继续渲染它们。这是通过调用上下文中的DrawRenderers作为参数来实现的,并告诉它要使用哪个renderers 。此外,我们还必须提供绘图设置和筛选设置。这两种都是结构体DrawingSettingsFilteringSettings

帧调试器向我们展示透明对象会被绘制,但是Skybox会被绘制到不透明对象前面的所有东西前面。如果让Skybox在不透明几何图形之后绘制,就可以跳过所有隐藏的片段,但是它又会覆盖透明的几何图形。这是因为透明着色器不会写入深度缓冲区。他们不会隐藏他们身后的任何东西,因为我们需要看穿它们。解决方案是首先绘制不透明对象,然后是Skybox,然后才是透明对象。

编辑器渲染

旧的Shaders:DrawUnsupportedShaders

在Editor下绘制不受支持的Shader

Gizmoz:DrawGizmos

可以通过调用UnityEditor.Handles.ShouldRenderGizmos来检查是否应该绘制gizmos。

UnityUI:PrepareForSceneWindow

当它的CameraType属性等于CameraTypes.SceneView时,我们便能使用场景摄像机渲染。

在裁剪前完成。

多摄像机

Preparebuffer处理更改的缓冲区名称

由于具有相同名称的相邻Sample作用域会被合并,所以我们最终只使用一个Render Camera作用域。

如果每个相机都有自己的镜头,那就更清楚了。为此,添加一个仅编辑器能用的PrepareBuffer方法,使缓冲区的名称与摄像机的名称相等。

在准备场景窗口之前调用它。

Layers与清除标志

通过调整他们的Culling Mask,相机也可以配置成只能看到某些层上的东西。

CameraClearFlag枚举定义了四个值。从1到4,它们是Skybox,Color,Depth和Nothing。它实际上不是一个独立的标志值,但表示清除量递减。除最后一种情况外,其他情况都必须清除深度缓冲区,因此,标志值最多的设置是Depth。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值