unity渲染管线笔记1,创建自定义渲染管线(自用)

先创建一个类,这个就是关于渲染管线Asset的用于储存渲染管线
using UnityEngine;
using UnityEngine.Rendering;
[CreateAssetMenu(menuName = "Rendering/Custom Render Pipeline")]
public class CustomRenderPipelineAsset : RenderPipelineAsset {
    [SerializeField]
    bool useDynamicBatching = true,useGPUInstancing = true,useSRPBatcher = true;
    protected override RenderPipeline CreatePipeline()
    {
        return new CustomRenderPipeline(useDynamicBatching,useGPUInstancing,useSRPBatcher);
    }
    
}
就是这样一个类,非常的简单,其中有三个参数,三个参数是用于控制批处理,然后定义一个构造方法,带上三个参数


然后我们再创建一个渲染管线,
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
//这几行不必多说
public class CustomRenderPipeline : RenderPipeline
{
    CameraRenderer renderer = new CameraRenderer();
    //创建一个渲染器,就是关于Camera的渲染器


    bool useDynamicBatching,useGPUInstancing;
    public CustomRenderPipeline(bool useDynamicBatching,bool useGPUInstancing,bool useSRPBatcher)
    {
        this.useDynamicBatching = useDynamicBatching;
        this.useGPUInstancing = useGPUInstancing;
        GraphicsSettings.useScriptableRenderPipelineBatching = useSRPBatcher;
    }
//然后自定义渲染管线设置,让我们的渲染管线拥有关于三个use变量的三种功能
    protected override void Render(
        ScriptableRenderContext context,Camera[] cameras)
    { 
        foreach(Camera camera in cameras)
        {
            renderer.Render(context,camera,useDynamicBatching,useGPUInstancing);
        }
    }
//创建一个render方法,来设置每个camera,这也是必须的
}
这个渲染管线就很多内容,一个一个看,现在看内部


现在来到我们的camerarender


using UnityEngine;
using UnityEngine.Rendering;

public partial class CameraRenderer
{
    ScriptableRenderContext context;
//上下文
    Camera camera;
//相机
    const string bufferName = "Render Camera";

    CullingResults cullingResults;
//指出是哪种阴影pass
    static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");


    CommandBuffer buffer = new CommandBuffer
    {
        name = bufferName
    };
//创建一个buffer,让buffer的name就等于先前的buffername
   public void Render(ScriptableRenderContext context, Camera camera,bool useDynamicBatching,bool useGPUInstancing)
    {
        this.context = context;
        this.camera = camera;
//先设置上下文和相机
        PrepareBuffer();    
        PrepareForSceneWindow();
//准备buffer和scenewindow的设置
        if (!Cull())
        {
            return;
        }
//如果被cull了就返回

        Setup();
//设定
        DrawVisibleGeometry(useDynamicBatching,useGPUInstancing);
//画出能看的间的Geometry
        DrawUnsupportedShader();
//draw不支持的shader
        DrawGizmos();
//
        Submit();
    }

    void DrawVisibleGeometry(bool useDynamicBatching,bool useGPUInstancing)
    {
        var sortingSettings = new SortingSettings(camera)//相机是传递正交还是透视
        {
            criteria = SortingCriteria.CommonOpaque
        };
        var drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings){//unlitshadertagid指出支持哪一种阴影
            enableDynamicBatching = useDynamicBatching,
            enableInstancing = useGPUInstancing
        };
        var filteringSettings = new FilteringSettings(RenderQueueRange.opaque);//设置渲染排序条件,现在这句是只有不透明的

        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);

        context.DrawSkybox(camera);

        //然后渲染透明的
        sortingSettings.criteria = SortingCriteria.CommonTransparent;
        drawingSettings.sortingSettings = sortingSettings;
        filteringSettings.renderQueueRange = RenderQueueRange.transparent;
        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
    }

    void Submit()
    {
        buffer.EndSample(SampleName);
        ExecuteBuffer(); 
        context.Submit();
    }

    void Setup()
    {
        context.SetupCameraProperties(camera);
        CameraClearFlags flags = camera.clearFlags;
        buffer.BeginSample(SampleName); 
        buffer.ClearRenderTarget(flags<=CameraClearFlags.Depth, flags <= CameraClearFlags.Color, flags ==CameraClearFlags.Color?camera.backgroundColor.linear: Color.clear);//��һ��������ʾʲôʱ�������ֵ������ѡ������ʱ�򣬳����һ��ʱ�򣬵ڶ�����ʾʲôʱ�������ɫ���壬����ѡ��ּ����ɫ��Ⱦ�������,��������ʾʲô������ɫ����Ϊ��������ʹ�õ���ɫģ�������Եģ�����ѡ��ת��Ϊ����
        ExecuteBuffer();
        context.SetupCameraProperties(camera);
    }
    void ExecuteBuffer()
    {
        context.ExecuteCommandBuffer(buffer);
        buffer.Clear();
    }
//跟踪多个相机和矩阵,然后设定cullingResult,成功就储存在字段中,失败就犯乎false
    bool Cull() 
    {

        if (camera.TryGetCullingParameters(out ScriptableCullingParameters p)) 
        {
            cullingResults = context.Cull(ref p); 
            return true;
        }
        return false;
    }
}
 

然后是只在编辑器中存在的
using UnityEditor;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;

partial class CameraRenderer
{
    partial void DrawGizmos();
    partial void DrawUnsupportedShader();
    partial void PrepareForSceneWindow();
    partial void PrepareBuffer();

#if UNITY_EDITOR

    string SampleName { get; set; }
    static Material errorMaterial;
//这个是旧的shader
    static ShaderTagId[] legacyShaderTagIds =
    {
        new ShaderTagId("Always"),
        new ShaderTagId("ForwardBase"),
        new ShaderTagId("PrepassBase"),
        new ShaderTagId("Vertex"),
        new ShaderTagId("VertexLMRGBM"),
        new ShaderTagId("VertexLM")
    };
//这个是画一些GIZMOS的
    partial void DrawGizmos()
    {
        if(Handles.ShouldRenderGizmos())
        {
            context.DrawGizmos(camera, GizmoSubset.PreImageEffects);
            context.DrawGizmos(camera,GizmoSubset.PostImageEffects);
        }
    }
//这个方法就是绘制一些不受支持的material,然后基于他们相同的报错红
    partial void DrawUnsupportedShader()
    {
        if(errorMaterial == null)
        {
            errorMaterial = new Material(Shader.Find("Hidden/InternalErrorShader"));
        }
        var drawingSettings = new DrawingSettings(
            legacyShaderTagIds[0], new SortingSettings(camera))
        { overrideMaterial = errorMaterial};
        for(int i = 1; i < legacyShaderTagIds.Length; i++)
        {
            drawingSettings.SetShaderPassName(i, legacyShaderTagIds[i]);
        }
        var filteringSettings = FilteringSettings.defaultValue;
        context.DrawRenderers(cullingResults,ref drawingSettings,ref filteringSettings);
    }

//这个是绘制UI
    partial void PrepareForSceneWindow()
    {
        if(camera.cameraType == CameraType.SceneView)
        {
            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
        }
    }
//这个是让缓冲区名称对应于相机的名称这样我们就可以清楚的辨别把缓冲区属于哪一个相机
    partial void PrepareBuffer()
    {
        Profiler.BeginSample("Editor Only");
        buffer.name = SampleName =camera.name;
        Profiler.EndSample();
    }
#else
    const string SampleName = bufferName;
#endif

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值