UnityShader20:CommandBuffer初见(上)

一、命令缓冲区 CommandBuffer

根据渲染模式的不同,Unity的渲染流水线如下:

其中蓝色的部分就是 CommandBuffer 可插入的部分,CommandBuffer 本质上就是做一个插入操作,以实现在 Unity 的某个渲染步骤完成后,执行你的额外操作

其中:

一个例子:如果你想将在天空盒渲染完后插入你的操作,那么对应的代码就是

var cam = Camera.current;
buf = new CommandBuffer();
buf.name = "bufName123";
//……
cam.AddCommandBuffer(CameraEvent.AfterSkybox, buf);

不过需要注意的是:针对 GPU 的不同,CommandBuffer 能插入的生命周期可能会有略微不同,部分可能不支持

二、Unity 生命周期渲染部分

Unity生命周期节选

渲染相关的生命周期介绍:

  • OnPreCull: 在相机剔除不可见对象前调用此函数
  • OnBecameVisible/OnBecameInvisible: 当挂有渲染组件的对象于相机可见/不可见时调用此函数(例如进入/离开摄像机视野)
  • OnWillRenderObject: 如果对象可见,在物体渲染之前会调用此函数
  • OnPreRender: 在相机开始渲染场景之前调用此函数
  • OnRenderObject: 在完成所有常规场景渲染后调用此函数,此时可使用 GL 类或 Graphics.DrawMeshNow 绘制自定义几何图形
  • OnPostRender: 在相机完成场景渲染后调用此函数
  • OnRenderImage:在相机完成渲染后调用此函数,可以在此修改摄影机的最终图像(后处理)
  • OnGUI: 响应 GUI 事件,如果一帧有多个 GUI 事件就会响应多次
  • OnDrawGizmos 用于在场景视图中绘制小图示(Gizmos)以实现可视化目的

为什么要讲这个,因为后面对于不同的效果实现,需要在正确的生命周期下完成 CommandBuffer 的相关操作

注意:部分生命周期需要专业版的 Unity 才提供

三、最简单的 CommandBuffer 例子

代码如下,其中 CommandBuffer 中使用的 Shader 输出纯绿色

using UnityEngine;
using UnityEngine.Rendering;

[ExecuteInEditMode]
//加上ExecuteInEditMode后,下面的代码在编辑模式中就会运行,无需每次测试都要play了
public class GreenCube: MonoBehaviour
{
    public Shader shader;
    private Material material;
    CommandBuffer buffer;
    private void OnEnable()
    {
        buffer = new CommandBuffer();
        material = new Material(shader);
        //CommandBuffer.DrawRenderer:使用指定的材质,绘制目标对象
        buffer.DrawRenderer(GetComponent<Renderer>(), material);
        Camera.main.AddCommandBuffer(CameraEvent.AfterForwardOpaque, buffer);
    }
    public void OnDisable()
	{
        if (Camera.main)
            Camera.main.RemoveCommandBuffer(CameraEvent.AfterForwardOpaque, buffer);
        Object.DestroyImmediate(material);
	}
}

这个脚本挂在你要渲染的 Cube 下,这个 Cube 就会额外执行你的渲染指令:

可以看到,Game视图中的正方体已经是绿的了

在 FrameDebug 中也可以看到:Cube 被渲染了两次,第二次就是 CommandBuffer 中我们自己的额外渲染命令

参考资料:

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/113762562