资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 游戏开发 > 其他

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

其他 更新时间: 发布时间: 计算机考试归档 最新发布

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

}

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/901251.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【unity渲染管线笔记1,创建自定义渲染管线(自用)】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2