Unity6 自定义渲染管线--可见对象的渲染

0 阅读2分钟

www.bilibili.com/video/BV1pZ…

可见对象的渲染

前提

目前在场景中添加任何对象都无法显示

image.png

此时的渲染对象使用的是默认材质,也就是 Built-in 默认管线下的材质与 Shader。

创建与管线匹配的材质与Shaders

在 LiteRP 目录下创建 Materials 和 Shaders 文件夹。

在 Shaders 目录下创建 Unlit.Shader

Shader "LiteRP/Unlit"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _Color;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv) * _Color;
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

在 Materials 文件夹下创建 LiteRP-Default 材质,并指向 Unlit.Shader。

image.png

指定纹理为编辑器下默认纹理。

并将 Cube 的材质进行替换。

image.png

清理渲染目标

cmd.ClearRenderTarget(true, true, camera.backgroundColor);

image.png

image.png

与 Camera 实际的 Background 颜色不一致。

这是因为 srp 管线与 Built-in 管线颜色空间不一致导致的。

srp 颜色管线使用的是线性空间:

image.png

cmd.ClearRenderTarget(true, true, CoreUtils.ConvertSRGBToActiveColorSpace(camera.backgroundColor));

image.png

创建渲染列表

// 指定渲染排序设置 SortSettings
var sortSettings = new SortingSettings(camera);
// 指定渲染状态设置 DrawSettings
var drawSettings = new DrawingSettings(new ShaderTagId("SRPDefaultUnlit"), sortSettings);
// 指定渲染过滤设置 FilterSettings
var filterSettings = new FilteringSettings(RenderQueueRange.opaque);
// 创建渲染列表
var rendererListParams = new RendererListParams(cullingResults, drawSettings, filterSettings);
var rendererList = context.CreateRendererList(ref rendererListParams);
// 绘制渲染列表
cmd.DrawRendererList(rendererList);

image.png

image.png

增加不透明和半透明

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

namespace LiteRP
{
    public class LiteRenderPipeline : RenderPipeline
    {
        private readonly static ShaderTagId s_ShaderTagId = new ShaderTagId("SRPDefaultUnlit");

        // 老版本
        protected override void Render(ScriptableRenderContext context, Camera[] cameras)
        {
            // 不实现
        }

        // 新版本
        protected override void Render(ScriptableRenderContext context, List<Camera> cameras)
        {
            // 开始渲染上下文
            BeginContextRendering(context, cameras);

            // 渲染相机
            for(int i = 0; i < cameras.Count; ++i)
            {
                Camera camera = cameras[i];
                RenderCamera(context, camera);
            }

            // 结束渲染上下文
            EndContextRendering(context, cameras);
        }

        private void RenderCamera(ScriptableRenderContext context, Camera camera)
        {
            // 开始渲染相机
            BeginCameraRendering(context, camera);
            // 获取相机剔除参数,并进行剔除
            ScriptableCullingParameters cullingParameters;
            if (!camera.TryGetCullingParameters(out cullingParameters))
                return;
            CullingResults cullingResults = context.Cull(ref cullingParameters);

            // 为相机创建 CommandBuffer
            CommandBuffer cmd = CommandBufferPool.Get(camera.name);
            // 设置相机属性参数
            context.SetupCameraProperties(camera);
            
            // 清理渲染目标
            cmd.ClearRenderTarget(true, true, CoreUtils.ConvertSRGBToActiveColorSpace(camera.backgroundColor));

            // 指定渲染排序设置 SortSettings
            var sortSettings = new SortingSettings(camera);
            // 指定渲染状态设置 DrawSettings
            var drawSettings = new DrawingSettings(s_ShaderTagId, sortSettings);

            // 绘制不透明物体
            sortSettings.criteria = SortingCriteria.CommonOpaque;
            // 指定渲染过滤设置 FilterSettings
            var filterSettings = new FilteringSettings(RenderQueueRange.opaque);
            // 创建渲染列表
            var rendererListParams = new RendererListParams(cullingResults, drawSettings, filterSettings);
            var rendererList = context.CreateRendererList(ref rendererListParams);
            // 绘制渲染列表
            cmd.DrawRendererList(rendererList);

            // 绘制半透明物体
            sortSettings.criteria = SortingCriteria.CommonTransparent;
            // 指定渲染过滤设置 FilterSettings
            filterSettings = new FilteringSettings(RenderQueueRange.transparent);
            // 创建渲染列表
            rendererListParams = new RendererListParams(cullingResults, drawSettings, filterSettings);
            rendererList = context.CreateRendererList(ref rendererListParams);
            // 绘制渲染列表
            cmd.DrawRendererList(rendererList);

            // 提交命令缓冲区
            context.ExecuteCommandBuffer(cmd);
            // 释放命令缓冲区
            cmd.Clear();
            CommandBufferPool.Release(cmd);
            // 提交渲染上下文
            context.Submit();
            // 结束渲染相机
            EndCameraRendering(context, camera);
        }
    }
}

绘制天空盒

// 设置相机属性参数
context.SetupCameraProperties(camera);

bool clearSkybox = camera.clearFlags == CameraClearFlags.Skybox;
bool clearDepth = camera.clearFlags != CameraClearFlags.Nothing;
bool clearColor = camera.clearFlags == CameraClearFlags.Color;

// 清理渲染目标
cmd.ClearRenderTarget(true, true, CoreUtils.ConvertSRGBToActiveColorSpace(camera.backgroundColor));

// 绘制天空盒
var skyboxRendererList = context.CreateSkyboxRendererList(camera);
cmd.DrawRendererList(skyboxRendererList);

image.png