再谈 unity的CommandBuffer——将rt绘制到屏幕上的两种方法

实验:为主相机添加一个事件:CameraEvent.AfterForwardOpaque
用于画一个立方体在rt中。

实验代码:

using UnityEngine;
using UnityEngine.Rendering;

public class TestCommandBuffer : MonoBehaviour
{
    public RenderTexture rt;
    public Camera m_camera;
    public GameObject cube;
    public Shader cubeShader;
    private CommandBuffer cb;
    void Start()
    {
        cb = new CommandBuffer();
        cb.name = "testCb";
        rt = new RenderTexture(m_camera.pixelWidth, m_camera.pixelHeight, 24);
        cb.SetRenderTarget(rt);
        cb.ClearRenderTarget(true, true, Color.black);
        MeshFilter mf = cube.GetComponent<MeshFilter>();
        Material mat = new Material(cubeShader);
        Matrix4x4 m = Matrix4x4.identity;
        m.SetTRS(new Vector3(0, 0, 10), Quaternion.identity, Vector3.one);
        cb.DrawMesh(mf.mesh, m, mat);
        m_camera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, cb);
    }
}

实验小节:
这里要注意的是基本的步骤,when,what,where,how
什么时候画,画什么,在哪里画,怎么画。
什么时候画:在相机的某个时间点,如上面的:CameraEvent.AfterForwardOpaque
画什么:我们想画一个立方体,这里立方体可以事先在unity的层级视图中创建,并且隐藏,我们只想用其mesh即可。
在哪里画:这里有两个问题,在相机的什么位置画,才能保证物体被看到,就上面代码的m.SetTRS这个函数的调用。此时要注意到相机和物体的位置,保证物体能被摄像机看到即可。第二个,画在哪里,我们是想将画的结果存储在一个rt上,所以要开辟一个rt才行。
怎么画:这个是调用函数commandbuffer的DrawMesh的方法,传入要画的mesh,位置,材质球即可。

上面的问题搞清楚之后,我们还要注意到,在一开始画的时候,将rt清空,可以用一个颜色进行清空,比如上面的用的是黑色。下面我们看到帧调试器中的结果:
在这里插入图片描述
这样就得到了一个rt喽。

下面我们想将,这个rt画到屏幕上去,怎么做呢?
这里我有两个方法:

  1. 使用最简单的OnRenderImage方法:
public void OnRenderImage(RenderTexture source, RenderTexture destination)
{
    Graphics.Blit(rt, destination);
}

这样就将rt绘制到了屏幕上。
在这里插入图片描述
2. 第二个方法是,手动绘制一个四边形的方法

using UnityEngine;
using UnityEngine.Rendering;

public class TestCommandBuffer : MonoBehaviour
{
    public RenderTexture rt;
    public Camera m_camera;
    public GameObject cube;
    public Shader cubeShader;
    public Shader sampleShader;
    private CommandBuffer cb;

    private Mesh quad;
    void Start()
    {
        cb = new CommandBuffer();
        cb.name = "testCb";
        rt = new RenderTexture(m_camera.pixelWidth, m_camera.pixelHeight, 24);
        cb.SetRenderTarget(rt);
        cb.ClearRenderTarget(true, true, Color.black);
        MeshFilter mf = cube.GetComponent<MeshFilter>();
        Material mat = new Material(cubeShader);
        Matrix4x4 m = Matrix4x4.identity;
        m.SetTRS(new Vector3(0, 0, 10), Quaternion.identity, Vector3.one);
        cb.DrawMesh(mf.mesh, Matrix4x4.identity, mat);
        m_camera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, cb);


        quad = new Mesh();
        Vector3[] vertices = new Vector3[4];
        vertices[0] = m_camera.ScreenToWorldPoint(new Vector3(0, 0, 10));
        vertices[1] = m_camera.ScreenToWorldPoint(new Vector3(0, m_camera.pixelHeight, 10));
        vertices[2] = m_camera.ScreenToWorldPoint(new Vector3(m_camera.pixelWidth, m_camera.pixelHeight, 10));
        vertices[3] = m_camera.ScreenToWorldPoint(new Vector3(m_camera.pixelWidth, 0, 10));

        Vector2[] uvs = new Vector2[4];
        uvs[0] = new Vector2(0, 0);
        uvs[1] = new Vector2(0, 1);
        uvs[2] = new Vector2(1, 1);
        uvs[3] = new Vector2(1, 0);
        quad.vertices = vertices;
        quad.uv = uvs;

        int[] ids = new int[6];
        ids[0] = 0;
        ids[1] = 1;
        ids[2] = 2;
        ids[3] = 2;
        ids[4] = 3;
        ids[5] = 0;

        quad.triangles = ids;
        CommandBuffer cb2 = new CommandBuffer();
        cb2.name = "drawScreen";
        Material material = new Material(sampleShader);
        material.SetTexture("_MainTex", rt);
        cb2.DrawMesh(quad, Matrix4x4.identity, material);
        m_camera.AddCommandBuffer(CameraEvent.AfterImageEffects, cb2);
    }
}

在这里插入图片描述
这里同样要注意到这个四边形的位置,我们的相机是在(0,0,0)位置,quad的z坐标为10,所以能看到。
谈到这里我们就基本完成了对commandbuffer的认识了。后面会在进行详细的扩展。

问题1:我们如何将深度图绘制到屏幕上呢?

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值