入门图形学:CommandBuffer

    unity提供给我们的commandbuffer可是个好东西,最近我正好用上了,所以来学习理解一下。

    unity commandbuffer manual 按惯例先上官方介绍。

    command buffer包含一系列渲染命令,类似于opengl的gl.xxx渲染命令函数但也不尽相同,最重要可以渲染开发者指定的object到延迟渲染的gbuffer中,在场景渲染后进行渲染。

    那么我们就可以通过command buffer去特定渲染一些物体,特别是在延迟渲染等后处理中操作。

    先来使用一下command buffer看下效果:

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

public class CbufferObject : MonoBehaviour
{
    private MeshRenderer render;
    private Material material;

    private CommandBuffer cmdBuffer;

    private void Awake()
    {
        render = GetComponent<MeshRenderer>();
        material = new Material(Shader.Find("CmdBuffer/PureColorShader"));
        material.SetColor("_MainColor", Color.green);
    }

    void Start()
    {
        
    }

    private void OnEnable()
    {
        cmdBuffer = new CommandBuffer();
        cmdBuffer.DrawRenderer(render, material);
        Camera.main.AddCommandBuffer(CameraEvent.AfterImageEffects, cmdBuffer);
    }

    private void OnDisable()
    {
        if (Camera.main != null)
        {
            Camera.main.RemoveCommandBuffer(CameraEvent.AfterImageEffects, cmdBuffer);
        }
    }
}

       cmdBuffer.DrawRenderer(render, material);

       Camera.main.AddCommandBuffer(CameraEvent.AfterImageEffects, cmdBuffer);

       上面的代码将一个renderer和material提交到主camera的commandbuffer列表进行绘制渲染,代码比较好理解,render的网格几何数据加上material的shader渲染命令,就相当于提交drawcall了。

Shader "CmdBuffer/PureColorShader"
{
    Properties
    {
        _MainColor("Main Color",Color) = (1,1,1,1)
        _MainAlpha("Main Alpha",Range(0,1)) = 0.3
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100

        Pass
        { 
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            float4 _MainColor;
            float _MainAlpha;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = _MainColor;
                col.a = _MainAlpha;
                return col;
            }
            ENDCG
        }
    }
}

       shader就是单纯在frag函数中返回带透明度的单色,效果如下:

 

       有点类似OnImageRender做屏幕后期特效一样,原本standard材质的sphere渲染出来的texture叠加了purecolor材质,附带上了半透明绿色,这里我觉得OnImageRender只是Command Buffer的一种子类应用而已。

       这里想起以前做游戏常见的一个功能,就是使用一个特定的Camera和Layer,Camera的CullMask指定渲染该Layer,然后将Camera渲染出的RenderTexture附着在UI rawimage上进行UI窗口的3D角色展示。当然CommandBuffer可比这种效率高多了,同时功能性更强。

       CommandBuffer提供给我们一种扩展unity自身渲染管线的能力,给我们提供了开放性的渲染定制化功能。

       后面再聊一聊我之前为什么只能用CommandBuffer才能实现的效果。

 

            

Guess you like

Origin blog.csdn.net/yinhun2012/article/details/106590946