CameraRenderer.cs 4.8 KB
Newer Older
timchen1002's avatar
timchen1002 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
using UnityEngine;
using UnityEngine.Rendering;

/// <summary>
/// 相机渲染管理类:单独控制每个相机的渲染
/// </summary>
public partial class CameraRenderer
{
    ScriptableRenderContext context;
    Camera camera;

    const string bufferName = "Render Camera";

    // 创建缓冲区
    CommandBuffer buffer = new CommandBuffer
    {
        name = bufferName
    };

    // 存储相机剔除后的结果
    CullingResults cullingResults;

    // 着色器标记ID
    static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");
    static ShaderTagId litShaderTagId = new ShaderTagId("CustomLit");

    Lighting lighting = new Lighting();

    /// <summary>
    /// 相机渲染
    /// </summary>
    /// <param name="context"></param>
    /// <param name="camera"></param>
    /// <param name="useDynamicBatching"></param>
    /// <param name="useGPUInstancing"></param>
    /// <param name="shadowSettings"></param>
    public void Render(ScriptableRenderContext context, Camera camera, bool useDynamicBatching, bool useGPUInstancing, ShadowSettings shadowSettings)
    {
        this.context = context;
        this.camera = camera;
        // 设置buffer缓冲区的名字
        PrepareBuffer();
        // 在Game视图绘制的几何体也绘制到Scene视图中
        PrepareForSceneWindow();
        if (!Cull(shadowSettings.maxDistance))
        {
            return;
        }


        buffer.BeginSample(sampleName);
        ExecuteBuffer();
        lighting.Setup(context, cullingResults, shadowSettings);
        buffer.EndSample(sampleName);
        Setup();

        // 绘制可见几何体
        DrawVisibleGeometry(useDynamicBatching, useGPUInstancing);
        // 绘制SRP不支持的内置shader类型
        DrawUnsupportedShaders();
        // 绘制Gizmos
        DrawGizmos();
        // 释放申请的RT内存空间
        lighting.Cleanup();
        // 提交缓冲区
        Submit();
    }

    /// <summary>
    /// 剔除
    /// </summary>
    /// <returns></returns>
    bool Cull(float maxShadowDistance)
    {
        if (camera.TryGetCullingParameters(out ScriptableCullingParameters p))
        {
            p.shadowDistance = Mathf.Min(maxShadowDistance, camera.farClipPlane);
            cullingResults = context.Cull(ref p);
            return true;
        }
        return false;
    }

    /// <summary>
    /// 设置相机的属性和矩阵,在着色器中被称为unity_matrixvp
    /// </summary>
    void Setup()
    {
        context.SetupCameraProperties(camera);
        // 得到相机的clearflags
        CameraClearFlags flags = camera.clearFlags;
        // 设置相机清除状态
        buffer.ClearRenderTarget(flags <= CameraClearFlags.Depth, flags == CameraClearFlags.Color, flags == CameraClearFlags.Color ? camera.backgroundColor.linear : Color.clear);
        buffer.BeginSample(sampleName);
        ExecuteBuffer();
    }

    /// <summary>
    /// 提交缓冲区命令
    /// </summary>
    void Submit()
    {
        buffer.EndSample(sampleName);
        ExecuteBuffer();
        context.Submit();
    }

    /// <summary>
    /// 执行缓冲区命令
    /// </summary>
    void ExecuteBuffer()
    {
        context.ExecuteCommandBuffer(buffer);
        buffer.Clear();
    }

    /// <summary>
    /// 绘制可见几何体,顺序:不透明物体->天空盒->透明物体
    /// </summary>
    void DrawVisibleGeometry(bool useDynamicBatching, bool useGPUInstancing)
    {
        // 设置绘制顺序和指定渲染相机
        var sortingSettings = new SortingSettings(camera)
        {
            criteria = SortingCriteria.CommonOpaque
        };
        // 设置渲染的shader pass和渲染顺序
        var drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings)
        {
            enableDynamicBatching = useDynamicBatching,
            enableInstancing = useGPUInstancing,
timchen1002's avatar
udpate  
timchen1002 已提交
132
            perObjectData = PerObjectData.Lightmaps | PerObjectData.ShadowMask | PerObjectData.LightProbe | PerObjectData.LightProbeProxyVolume,
timchen1002's avatar
timchen1002 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
        };
        // 渲染CustomLit表示的pass块
        drawingSettings.SetShaderPassName(1, litShaderTagId);

        // 只绘制RenderQueue为opaque不透明物体
        var filteringSettings = new FilteringSettings(RenderQueueRange.opaque);

        // 绘制不透明物体
        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
        // 绘制天空盒
        context.DrawSkybox(camera);
        sortingSettings.criteria = SortingCriteria.CommonTransparent;
        drawingSettings.sortingSettings = sortingSettings;
        // 只绘制RenderQueue为transparent透明的物体
        filteringSettings.renderQueueRange = RenderQueueRange.transparent;
        // 绘制透明物体
        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
    }
}