Unity可编程渲染管线SRP

一、RenderPipeline类

通过SRP可以实现对渲染管线的完全控制,它提供了需要的工具来创建符合项目需求的渲染管线和效果;通过在C#脚本中定义一系列的命令来控制每一帧的渲染过程,和传统内置管线不同,它开放了更多的接口,给了开发者更大的自由度,但是又不至于像OpenGL手写管线那么复杂,可以很好满足开发者既需要自定义管线又要简单快捷的开发需求,降低了渲染管线的开发门槛;

该类用于srp中的渲染方式,它通过定义一系列的命令和设置来告诉unity怎么渲染一帧;

二、相关类

所有可编程渲染管线相关的类定义在UnityEngine.Rendering中;

1. RenderPipelineAsset

所有的管线资源都要继承自该类,并重写其创建管线的CreatePipeline()方法,返回一个RenderPipeline实例,并且需要将该值赋予到GraphicSettings,然后才可以使用这个自定义的管线来进行渲染;

2. GraphicsSettings

它和编辑器中的Project Settings中的Graphics的设置是紧密相关的,用于以脚本的方式来进行自动设置来代替手动设置;所以,它提供的属性和方法都是和设置面板相对应的;例如,创建一条管线后,就可以通过GraphicsSettings.renderPipelineAsset来将其设置为当前的渲染管线;

3. RenderPipeline

核心类,可编程的渲染管线的具体流程在此定义,所有的可编程渲染管线继承自该类,在创建新的管线资源时,需要使用到该类的子类进行实例化;

4. ScriptableRenderContext

渲染上下文,在自定义渲染管线中定义一些状态和渲染命令,然后调用Submit函数提交到GPU;这个上下文的概念类似于OpenGL中上下文的概念,定义渲染管线要使用的许多状态以及绘制命令,相当于整个渲染的manager;

SetupCameraProperties(camera):相机的配置是第一步,设置相机的属性,获取一个相机实例后,就可以获取它的观察矩阵(transform)和裁剪矩阵(clip plane等)等属性值;


5. CommandBuffer

它的出现早于SRP,在没有SRP时,它用于对unity内置的渲染管线进行扩展;该缓冲区用于存储一系列渲染命令,然后提交到渲染上下文中;

使用步骤:创建缓冲区-设置-提交-释放缓冲区

CommandBuffer buf=new CommandBuffer();
//设置渲染命令....
context.ExecuteCommandBuffer(buf) //非立即执行
buf.Release()

6. SortSettings 

设置场景中物体的排序方式,使用默认方式和使用自定义方式

默认方式,设置criteria,这是一个SortingCriteria枚举类型,包含了透明物体(从前到后)、半透明(从后到前);

自定义方式,设置cameraPosition、customAxi、worldToCameraMatrix三个变量联合使用;

三、第一步-完成一个最基础的渲染管线

创建命令缓冲区,如下,设置清空渲染目标的命令;

剔除操作,通过相机获取剔除参数,剔除场景中的不可见物体;

绘制命令,绘制前需要对场景中的物体进行排序,为不同的物体设置不同的排序方式,比如半透明物体要从后到前渲染;在DrawingSettings中,构造函数第一个参数为ShaderTagId类型,也就是要使用的pass的tag的Id值,以及排序的设置;FilteringSettings则设置渲染队列的范围,用于设置哪些物体将会被渲染,如下例子,将透明和半透明分开进行渲染;

注意:天空盒的渲染在不透明物体之后,在半透明物体之前;

        var cmd = new CommandBuffer();
        CameraClearFlags clearFlags = camera.clearFlags;
        cmd.ClearRenderTarget((CameraClearFlags.Color&clearFlags)!=0,(CameraClearFlags.Depth&clearFlags)!=0,camera.backgroundColor);
        context.ExecuteCommandBuffer(cmd);
        cmd.Release();
 
        context.SetupCameraProperties(camera);
 
        //剔除
        ScriptableCullingParameters cullingPrama;
        camera.TryGetCullingParameters(out cullingPrama);
        CullingResults cullRet = context.Cull(ref cullingPrama);
 
        //绘制
        SortingSettings sortSettings = new SortingSettings(camera);
        sortSettings.criteria = SortingCriteria.CommonOpaque;
        DrawingSettings drawSettings = new DrawingSettings(new ShaderTagId("BasicPass"),sortSettings);
        FilteringSettings filterSettings = new FilteringSettings(RenderQueueRange.opaque);
        context.DrawRenderers(cullRet,ref drawSettings,ref filterSettings);
 
        context.DrawSkybox(camera);
 
        sortSettings.criteria = SortingCriteria.CommonTransparent;
        drawSettings.sortingSettings = sortSettings;
        filterSettings.renderQueueRange = RenderQueueRange.transparent;
        context.DrawRenderers(cullRet,ref drawSettings,ref filterSettings);
 
        context.Submit();

版权声明:本文为CSDN博主「莫之」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36383623/java/article/details/97920699

推荐阅读