再谈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, );
cb.sh, 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, );
cb.sh, 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;
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:我们如何将深度图绘制到屏幕上呢?