对于GL绘制,如果要设置material材质的属性(比如说颜色),应该在材质的SetPass方法之前进行设置,否则可能出问题,感觉是如果设置属性在SetPass之后的话,其属性会在下一帧起作用,这可能导致这些属性在你意向不到的物体上起作用了,哈哈哈。
别的不说了,先上代码:
using UnityEngine;
using UnityEngine.Rendering;
[RequireComponent(typeof(MeshFilter))]
public class GLWireRenderer : MonoBehaviour
{
Material mat;
public Material material { get { return mat; } }
public void SetMaterial(Material mat)
{
this.mat = mat;
}
int[] ts;
Vector3[] vs;
Vector3[] ns;
void OnEnable()
{
MeshFilter filter = GetComponent<MeshFilter>();
if (!filter) return;
Mesh mesh = filter.sharedMesh;
if (!mesh) return;
vs = mesh.vertices;
ns = mesh.normals;
ts = mesh.triangles;
RenderPipelineManager.endCameraRendering += EndCameraRendering;
}
void OnDisable()
{
RenderPipelineManager.endCameraRendering -= EndCameraRendering;
}
void EndCameraRendering(ScriptableRenderContext context, Camera camera)
{
if (!mat) return;
Vector3 normalCam = transform.InverseTransformDirection(Camera.main.transform.forward);
mat.SetPass(0);
GL.MultMatrix(transform.localToWorldMatrix);
GL.Begin(GL.LINES);
for (int i = 0; i < ts.Length; i += 3)
{
if (Vector3.Dot(ns[ts[i]], normalCam) > 0) continue;
GL.Vertex(vs[ts[i]]);
GL.Vertex(vs[ts[i + 1]]);
GL.Vertex(vs[ts[i]]);
GL.Vertex(vs[ts[i + 2]]);
GL.Vertex(vs[ts[i + 2]]);
GL.Vertex(vs[ts[i + 1]]);
}
GL.End();
}
}
需要补充一点的是,由于GLWire作为组件分布在不同的物体上,当多个物体上同时有GLWire组件的时候,RenderPipelineManager.endCameraRendering += EndCameraRendering;和RenderPipelineManager.endCameraRendering -= EndCameraRendering;这种操作会频繁发生,感觉上对速度还是有影响的,最好是把渲染统一到一个专门的绘制脚本中,每个GLWire只是负责把对应的Mesh数据传过去,由专门的绘制脚本统一渲染,这样速度感觉上似乎是快了一些。
Shader参考: