Drawing with GL on SceneView bad performance
I've search the forums and in here also but nothing has help me so far.
I'm drawing a simple grid with GL on the Editor SceneView with a size of 100x100 and it's really laggy I'm guessing there's something wrong with my code but I can't find what, I would appreciate any help.
Here's the code
Material lineMaterial;
void CreateLineMaterial()
{
if (!lineMaterial)
{
// Unity has a built-in shader that is useful for drawing
// simple colored things.
var shader = Shader.Find("Hidden/Internal-Colored");
lineMaterial = new Material(shader);
lineMaterial.hideFlags = HideFlags.HideAndDontSave;
// Turn on alpha blending
lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
// Turn backface culling off
lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
// Turn off depth writes
lineMaterial.SetInt("_ZWrite", 0);
}
}
protected void DrawGrid()
{
// Tile size
float size = positionSnap;
// Grid Size
int gridSizeX = 100;
int gridSizeZ = 100;
// Half Size
float halfSizeX = (gridSizeX * 0.5f) * size;
float halfSizeZ = (gridSizeZ * 0.5f) * size;
float offset = positionSnap * 0.5f;
halfSizeX -= offset;
halfSizeZ -= offset;
GL.PushMatrix();
lineMaterial.SetPass(0);
GL.Begin(GL.LINES);
GL.Color(Color.grey);
for(int x = 0; x < gridSizeX + 1; x++)
{
for(int z = 0; z < gridSizeZ + 1; z++)
{
// X
Vector3 start = new Vector3(x * size, height, z * size);
Vector3 end = new Vector3(gridSizeX, height, z * size);
start += Vector3.left * halfSizeX;
end += Vector3.left * halfSizeX;
start += Vector3.back * halfSizeZ;
end += Vector3.back * halfSizeZ;
GL.Vertex3(start.x, start.y, start.z);
GL.Vertex3(end.x, end.y, end.z);
// Z
start = new Vector3(x * size, height, z * size);
end = new Vector3(x * size, height, gridSizeZ);
start += Vector3.left * halfSizeX;
end += Vector3.left * halfSizeX;
start += Vector3.back * halfSizeZ;
end += Vector3.back * halfSizeZ;
GL.Vertex3(start.x, start.y, start.z);
GL.Vertex3(end.x, end.y, end.z);
}
}
GL.End();
GL.PopMatrix();
}
Answer by Okari-Draconis · Oct 25, 2017 at 03:30 AM
The main issue is the way you are drawing the grid... in your code example you are pushing 10,000+ Vertexes when you only need to push like 404..
Also.. You are making 4 new vectors inside of each iteration.. this is generally a bad idea, and its better to re-use vectors having them be outside the loop.
Finally to move something to the Left... its WAY cheaper to do:
start.x -= halfSizeX
than this:
start += Vector3.left * halfSizeX
because the above is the same as doing the below:
Vector3 leftVector = new Vector3(-1,0,0);
leftVector.x *= halfSizeX;
leftVector.y *= halfSizeX;
leftVector.z *= halfSizeX;
start.x += leftVector.x;
start.y += leftVector.y;
start.z += leftVector.z;
As you can see.. a lot of useless calculations wasting CPU time... Normally not an issue.. but remember your doing the above basically 80,000+ times...
Anyways I made your code more efficient, I think it should do same as above.
protected void DrawGrid()
{
float tileSize = 0.25f;
int gridSizeX = 100;
int gridSizeZ = 100;
// Half Size
float halfGridSizeX = gridSizeX * 0.5f * tileSize;
float halfGridSizeZ = gridSizeZ * 0.5f * tileSize;
GL.PushMatrix();
lineMaterial.SetPass(0);
GL.Begin(GL.LINES);
GL.Color(Color.grey);
int i;
Vector3 start = new Vector3(-halfGridSizeX, 0, -halfGridSizeZ);
Vector3 end = new Vector3(-halfGridSizeX, 0, halfGridSizeZ);
for (i = 0; i < gridSizeX + 1; i++)
{
GL.Vertex(start);
GL.Vertex(end);
end.x = start.x = start.x + tileSize;
}
start.x = -halfGridSizeX;
end.x = halfGridSizeX;
end.z = start.z = -halfGridSizeZ;
for (i = 0; i < gridSizeZ + 1; i++)
{
GL.Vertex(start);
GL.Vertex(end);
end.z = start.z = start.z + tileSize;
}
GL.End();
GL.PopMatrix();
}