1.前言
本文承接上一节,主要讲一下如何用graphics绘制一个Mesh以及将绘制结果绘制到一个RenderTexture上。代码在文末。
2.Graphics DrawMesh
代码中所用材质shader为Unlit/Texture。
2.1 ToScreen
以下为绘制到屏幕上的示例代码:
private void DrawToScreen() { drawBuffer.Clear(); drawBuffer.ClearRenderTarget(true, true, clearColor); Graphics.ExecuteCommandBuffer(drawBuffer); drawBuffer.DrawMesh(Graphics00Mesh.Instance.GetMesh(triCount, radius), Matrix4x4.identity, mat); Graphics.ExecuteCommandBuffer(drawBuffer); }
此时方法只能在OnPostRender中调用,所以网格顶点数据即为实际数据。在OnpostRender中调用时,相当于在借助Camera在渲染流程中进行渲染Mesh,所以坐标点就是真是位置。如果看不到效果,可能是因为绘制的Mesh不在Camera的视锥体内,尝试调节mesh的位置,可以找到。此方法与这一篇方法类似。
2.2 ToTarget
此节将Mesh绘制到一个RenderTexture上。示例代码如下:
private void DrawToTarget() { GL.PushMatrix(); Graphics.SetRenderTarget(target); GL.LoadPixelMatrix(0, target.width, 0, target.height); drawBuffer.Clear(); drawBuffer.ClearRenderTarget(true, true, clearColor); Graphics.ExecuteCommandBuffer(drawBuffer); drawBuffer.DrawMesh(Graphics00Mesh.Instance.GetMesh(triCount, radius), Matrix4x4.identity, mat); Graphics.ExecuteCommandBuffer(drawBuffer); GL.PopMatrix(); }
此方法可以在update中使用。
2.2.1 注意事项一
由于此方法是直接绘制到二维RenderTexture上,所以要进行坐标变换,且要先设置Target后LoadPixelMatrix。
2.2.2 注意事项二
由于坐标要转换到像素坐标,所以mesh顶点只显示大于0的部分,本例中Mesh的中心是(0,0,0),所以会只显示四分之一,跟这一篇2.3节一样。
而且如果Mesh的顶点数据过小,可能看不到。以本例圆形mesh为例,如果半径为1,那么在屏幕上只有一个像素大小,所以是看不到的,此时可以设置为100或者更大。
3.完整代码
3.1 Mesh代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Graphics00Mesh { [Range(3, 100)] public int triCount = 6; public float radius = 5; public bool showHalf = false; private static Graphics00Mesh instance; public static Graphics00Mesh Instance { get { if (instance == null) { instance = new Graphics00Mesh(); } return instance; } } public Mesh GetMesh(int triCount,float radius) { this.triCount = triCount; this.radius = radius; Mesh mesh = new Mesh(); mesh.name = MeshName; mesh.vertices = Vertices; mesh.triangles = Triangles; mesh.uv = Uvs; return mesh; } protected string MeshName { get { return "Circle Mesh"; } } protected Vector3[] Vertices { get { Vector3[] vertices = new Vector3[triCount + 1]; vertices[0] = Vector3.zero; float angleDelta = 2 * Mathf.PI / triCount; for (int i = 0; i < triCount; i++) { float angle = angleDelta * i; float x = radius * Mathf.Cos(angle); float y = radius * Mathf.Sin(angle); vertices[i + 1] = new Vector3(x, y, 0); } return vertices; } } protected int[] Triangles { get { int[] triangles = new int[triCount * 3]; for (int i = 0; i < triCount; i++) { if (showHalf) { if (i % 2 == 0) continue; } triangles[i * 3] = 0; triangles[i * 3 + 2] = i + 1; if (i + 2 > triCount) { triangles[i * 3 + 1] = 1; } else { triangles[i * 3 + 1] = i + 2; } }