lwrp2019之后对渲染管线做了一些优化,比较明显的就是feature了,他可以让我们定义一些类似相机的功能。
首先用法是:
创建一个lwrp:
然后再graphics中指定
然后我们的渲染方式就是按照我们指定的lwrp来渲染了。
关于Quality,Lighting,Shadows,Advanced跟之前差不多,其中shaderVariantLogLevel是我们输出shader的一些错误或提示信息。
重点说下features,刚说了他是设置了相机的属性。
Feature执行流程
也就是说他会对需要渲染的物体多做一次渲染操作,也就会多一个drawcall。主要原因可以看源码LightweightRenderPipeline的RenderSingleCamera中
这里会执行到ScriptableRenderer的
里面会拿到所有的ScriptableRenderPass来执行(刚开始会EnqueuePass把ScriptableRenderPass都加进去)
最终再RenderObjectsPass执行Execute设置到指定的CommandBuffer再给到ScriptableRenderContext执行。
加入feature的地方再ForwardRenderer中的
当然我们也可以写自己的feature加入和实现方式。
设置和代码相关
按照上面说的,就会有多少feature就会多多少drawcall。但是有一点需要注意,我们的feature是可以过滤内容的。主要的过滤方式其实也类似相机。
可剔除drawcall部分
其中过滤会在Queue和layerMask和ShaderPasses之中,这里的过滤是真的会把相应的drawcall给去掉的,比如我们这个feature只需要在Transparent中,则不会渲染Opaque,layerMask是可以设置自己想渲染的层级,shader passes是可以让我们指定只渲染指定的pass类型,不是该类型会被过滤。
因为他在RenderObjectsPass中会设置到DrawingSettings中,DrawingSettings里面的属性最终会让ScriptableRenderContext来执行DrawRenderers。给unity渲染框架去处理对象的剔除。
渲染位置:
我们可以指定我们这个pass在上面阶段进行渲染,
是在ScriptableRenderPass中定义的
public enum RenderPassEvent
{
BeforeRendering = 0,
BeforeRenderingShadows = 50,
AfterRenderingShadows = 100,
BeforeRenderingPrepasses = 150,
AfterRenderingPrePasses = 200,
BeforeRenderingOpaques = 250,
AfterRenderingOpaques = 300,
BeforeRenderingSkybox = 350,
AfterRenderingSkybox = 400,
BeforeRenderingTransparents = 450,
AfterRenderingTransparents = 500,
BeforeRenderingPostProcessing = 550,
AfterRenderingPostProcessing = 600,
AfterRendering = 1000,
}
这里是从前到后渲染的顺序
主要在ScriptableRenderer中FillBlockRanges设置把当前feature中大于等于要渲染的层级设置下,最终还是在ExecuteBlock中ExecuteRenderPass执行一个pass的时候决定,也就是说这个顺序是lwrp排序后按顺序给到unity的。
overrides
在overrides下面是一些可以替换材质或光照或显示的设置。这里不会减少drawcall但可以修改一些数值来达到摄像机或全局材质变更的效果。
Material就是指定的材质,passindex就是指定的pass的id。材质也是RenderObjectsPass最终在DrawingSettings中设置替换的材质,然后给到ScriptableRenderContext。
Depth就是判断深度在多少的情况下可以渲染,并且是否是否写入深度都可以设置。是在RenderObjectsPass中SetDetphState设置深度和写入与否,给到RenderStateBlock中然后设置进ScriptableRenderContext。
模板也是会设置到RenderStateBlock中然后设置进ScriptableRenderContext。
摄像机的fov,为主偏移。restoreCamera从代码上看是跟overrideCamera一样可以重置摄像机矩阵的。fov设置方式是通过Matrix4x4.Perspective(camera.fieldOfView, cameraAspect,
camera.nearClipPlane, camera.farClipPlane);把相关的属性设置后给到一个矩阵,把矩阵信息给到commandbuffer的SetViewProjectionMatrices。
位移是
Matrix4x4 viewMatrix = camera.worldToCameraMatrix;
Vector4 cameraTranslation = viewMatrix.GetColumn(3);
viewMatrix.SetColumn(3, cameraTranslation + m_CameraSettings.offset);
cmd.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
先转换到摄像机矩阵,再设置到矩阵的第四维中(位移)。
总结
其实更多的是unity提供了更多管线的方式,比如commandbuffer设置相机视角之类的。达到比之前多个摄像机更好的效果。因为现在只需要执行矩阵运算就可以改变对应的fov等摄像机效果了。以前需要每个feature加一个相机。因为每个相机都要走一遍剔除对象,剔除光照等的操作。所以会比较快比较省。