Unity SRP 工作方式

安装 Universal RP 包(Universal: 通用)

定制 RenderPipelineAsset

[CreateAssetMenu(menuName = "Rendering/Custom Render Pipeline")]
public class CustomRenderPipelineAsset : RenderPipelineAsset
{
    public bool useSRPBatcher
    {
        get { return m_UseSRPBatcher; }
        set { m_UseSRPBatcher = value; }
    }

    [SerializeField] bool m_UseSRPBatcher = true;

    protected override RenderPipeline CreatePipeline()
    {
        return new CustomRenderPipeline();
    }
}

定制 RenderPipeline

public class CustomRenderPipeline : RenderPipeline
{
    private CameraRenderer renderer = new CameraRenderer();

    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        foreach (var camera in cameras)
        {
            renderer.Render(context, camera);
        }
    }
}

负责具体渲染事宜的工作Render

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

public partial class CameraRenderer {

    static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");


    const string bufferName = "Render Camera";
    CommandBuffer buffer = new CommandBuffer() { name = bufferName };

    private ScriptableRenderContext context;
    private Camera camera;

    CullingResults cullingResults;

    public void Render(ScriptableRenderContext context, Camera camera)
    {
        this.context = context;
        this.camera = camera;

        PrepareBuffer();
        PrepareForSceneWindow();

        if (!Cull())
        {
            return;
        }

        Setup();
        DrawVisibleGeometry();
        DrawUnsupportedShaders();
        DrawGizmos();
        Submit();
    }

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

        return false;
    }


    private void Setup()
    {
        context.SetupCameraProperties(camera);
        CameraClearFlags flags = camera.clearFlags;
        buffer.ClearRenderTarget(flags <= CameraClearFlags.Depth
            , flags == CameraClearFlags.Color
            , flags == CameraClearFlags.Color? camera.backgroundColor.linear: Color.clear);
        buffer.BeginSample(SampleName);
        ExecuteBuffer();
    }
    private void DrawVisibleGeometry()
    {
        var sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque };
        var drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings);

        var filteringSettings = new FilteringSettings(RenderQueueRange.opaque);

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

        if (drawingSettings.mainLightIndex >= 0)
        {
            ShadowDrawingSettings shadowDrawingSettings = new ShadowDrawingSettings(cullingResults, drawingSettings.mainLightIndex);
            context.DrawShadows(ref shadowDrawingSettings);
        }


        //context.DrawSkybox(camera);
        if (camera.clearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null)
        {
            context.DrawSkybox(camera);
        }

        sortingSettings.criteria = SortingCriteria.CommonTransparent;
        drawingSettings.sortingSettings = sortingSettings;
        filteringSettings.renderQueueRange = RenderQueueRange.transparent;

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

    }

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

    private void ExecuteBuffer()
    {
        context.ExecuteCommandBuffer(buffer);
        buffer.Clear();
    }
}

设置

  1. 创建.asset作为资源的形式赋值给ProjectSettings->GraphicsScriptable Render Pipeline Settings

  2. 代码形式 GraphicsSettings.renderPipelineAsset = asset;


文章作者: Yonggang Long
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yonggang Long !
 上一篇
2022-08-10 Yonggang Long
下一篇 
2022-08-10 Yonggang Long
  目录