I’ve run into a brick wall.
I’ve got 80 gems of different sizes and colours.
Rendering on my iPod touch I get < 10fps. unsurprising, Unity reports 80+ draw calls are being made.
Doc says that each material means another draw call, and fiddling a material’s properties creates a clone of that material. So this code in the Update() of each gem:
T_gem.renderer.material.color = C_gem;
T_gem.renderer.material.SetFloat( "_Glow", glowIntensity / 2f );
was doing that.
So, I eliminate this by combining RGB colour and glow into a single RGBA and adding this as a color32 to each vertex:
void LateUpdate()
{
if( glowIntensity < 0.03f )
return;
Color C_gem = color; // doGlow ? Color.Lerp( color, Color.grey, glowIntensity / 2f ) : color;
Mesh mesh = T_gem.GetComponent<MeshFilter>().mesh;
Color32[] colors32 = new Color32[ mesh.vertices.Length ];
C_gem.a = glowIntensity;
for (int i = 0; i < mesh.vertices.Length; i++)
// http://docs.unity3d.com/Documentation/ScriptReference/Color32-operator_Color.html
// Color32 can be implicitly converted to and from Color.
colors32[ i ] = C_gem;
mesh.colors32 = colors32;
}
Note that I’m doing it in LateUpdate. This means that all of the meshes get recalculated AFTER this frame has drawn, but BEFORE the next frame has drawn.
Of course I have to fiddle the shader to no longer receive colour and glow as properties, which I’ve done successfully:
Shader "FX/Piamond"
{
Properties {
// _Color ("Color", Color) = (1,1,1,1)
// _Glow("Glow",Range(0,1)) = 0.5
_ReflectTex ("Reflection Texture", Cube) = "dummy.jpg" {
TexGen CubeReflect
}
_RefractTex ("Refraction Texture", Cube) = "dummy.jpg" {
TexGen CubeReflect
}
}
SubShader {
Tags {
"Queue" = "Transparent"
}
// if I don't have all of these, it goes wonky
BindChannels {
Bind "Vertex", vertex
Bind "Normal", normal
Bind "Color", color
Bind "texcoord", texcoord0
Bind "texcoord1", texcoord
}
.... etc
Still 80+ draw calls!
Now each gem has about 600 vertices: Unity - Manual: Draw call batching says something about a magic limit of 900 that reduces to 600 or 300 if vertices have colour / texture components. I don’t understand that. But anyway, I have tried replacing them with cubes, and exactly the same thing happens.
Still 80+ draw calls!
Now I’m not 100% sure that all these clones are sharing the same material; only reason I’m not sure if that there is a property called sharedMaterial, and I’m not using it. So I try and use it:
public Material gemMaterial;
// Use this for initialization
void Start ()
{
for( int noteIndex = 0; noteIndex < numNotes; noteIndex++ )
{
Transform T_Clone = (Transform)Instantiate( T_GemContainer_Prefab, Vector3.zero, Quaternion.identity );
GemContainer G = allGems[ noteIndex ] = T_Clone.transform.GetComponent< GemContainer >( );
G.SetMaterial( gemMaterial );
and
public void SetMaterial( Material m )
{
T_gem.renderer.sharedMaterial = m;
//T_gem.renderer.material = null;
}
Still doesn’t work. Still 80+ draw calls!!!
Dynamic Batching and Instantiating - Questions & Answers - Unity Discussions this question here has a very good answer, which says this only works if all of the clones have the same transform.scale
So I try removing the line of code that changes the transform.scale for a clone.
transform.localScale = uberSize * animSize * ( 1f + gemSize ) * Vector3.one;
Still 80+ draw calls!!!
Please could someone have a look at this?