(七)Graphics DrawMesh


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; } } return triangles; } } protected Vector2[] Uvs { get { Vector2[] uvs = new Vector2[triCount + 1]; uvs[0] = new Vector2(0.5f, 0.5f); float angleDelta = 2 * Mathf.PI / triCount; for (int i = 0; i < triCount; i++) { float angle = angleDelta * i; float x = Mathf.Cos(angle) * 0.5f + 0.5f; float y = Mathf.Sin(angle) * 0.5f + 0.5f; uvs[i + 1] = new Vector2(x, y); } return uvs; } } } 

3.2 示例代碼

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; public class Graphics07DrawMeshToTarget : MonoBehaviour { public DrawLocation location = DrawLocation.ONGUI; public bool toTarget = false; public Color clearColor = Color.blue; public Material mat; public RenderTexture target; public int triCount = 10; public float radius = 20; CommandBuffer drawBuffer; void Draw() { if (toTarget) { DrawToTarget(); } else { DrawToScreen(); } } 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); } 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(); } private void Start() { drawBuffer = new CommandBuffer() { name = "DrawMesh buffer" }; } private void OnGUI() { if (location != DrawLocation.ONGUI) return; if (Event.current.type.Equals(EventType.Repaint)) { Draw(); } } private void Update() { if (location != DrawLocation.UPDATE) return; Draw(); } private void OnPostRender() { if (location != DrawLocation.POSTRENDER) return; Draw(); } } 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM