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();
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才能实现的效果。