unity-CommandBuffer使用

unity-CommandBuffer使用


前篇

CommandBuffer最主要的功能是可以预定义一些列的渲染指令,然后将这些指令在我们想要的时机进行执行。


渲染到 RenderTexture

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
targetRenderer = targetObject.GetComponentInChildren<Renderer>(); // 需要渲染到RT上的目标渲染器
//申请RT
renderTexture = RenderTexture.GetTemporary(512, 512, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, 4);
commandBuffer = new CommandBuffer();
//设置Command Buffer渲染目标为申请的RT
commandBuffer.SetRenderTarget(renderTexture);
//初始颜色设置为灰色
commandBuffer.ClearRenderTarget(true, true, Color.gray);

//绘制目标对象时, commandBuffer允许指定别的材质球 ,如果没有替换材质,就用自己的材质
Material mat = replaceMaterial == null ? targetRenderer.sharedMaterial : replaceMaterial;
commandBuffer.DrawRenderer(targetRenderer, mat);

if (_Material)
{
//这是个比较危险的写法,一张RT即作为输入又作为输出,在某些显卡上可能不支持,如果不像我这么懒的话...还是额外申请一张RT
commandBuffer.Blit(renderTexture, renderTexture, _Material); // 和后处理的 Graphics.Blit 是一个意思, 可以将指定材质将rt1渲染到rt2中
}
//直接加入相机的CommandBuffer事件队列中, 决定在哪个时机调用这个 commandBuffer 绘制
Camera.main.AddCommandBuffer(CameraEvent.BeforeForwardOpaque, commandBuffer);

//最后就是拿这个 renderTexture 来用了, 比如丢到某个球上作为贴图.
this.GetComponent<Renderer>().sharedMaterial.mainTexture = renderTexture;

使用场景

  1. 除 主角 之外的背景做特效 ( 比如 模糊, 扭曲 ).

    如果使用 景深 的方式去处理, 会有很大渲染消耗, 因为需要用到深度图, 渲染批次几乎直接就是翻倍, 而且不太好控制背景, 和主角处于同一深度的做不了效果.

    如果使用 CommandBuffer, 这个就很简单而且效率高. 主相机渲染除 主角 之外的所有对象, 然后对主相机进行 后处理 , 然后在用 CommandBuffer 渲染主角

    参考 : https://blog.csdn.net/puppet_master/article/details/72669977