@daaoling
2017-02-17T13:49:30.000000Z
字数 2613
阅读 2949
Unity
之前项目如果使用Ngui做飘血功能,一旦同屏超过几百个飘血就开始卡了, 采用了对象池也没有很好的好转, 查看了一下源码主要是两点
1.ngui在对动态的物体的时候都会有重新绘制drawcall
2.每一帧对物体进行插值计算消耗了大量cpu时间
思考了一下 针对以上缺陷,我图集还是采用ngui的, 因为要控制drawcall, 但是考虑自己使用自定义重构mesh生成, 然后根据曲线插值位置, 缩放和alpha, 那么我就不需要每次变动重新绘制drawcall了, 可是这样一来, 在unity4.7 版本上会出现dynamic batch 失效的情况, 导致还不如ngui的性能, 最严重的时候甚至到了 5 fps
我思考可能不同时期缩放不一样导致的
Generally, objects should be using the same transform scale.
The exception is non-uniform scaled objects; if several objects all have different non-uniform scale then they can still be batched.
那么我就想到了顶点动画才进行插值运动,运用vertex的别的通道来存储其动画信息。
但是本身的话如果一个pop 建立一个mesh的话drawcall控制不住。那么我采用 update 放入当前这一帧所需要绘制的所有 pop mesh的顶点信息, 在lateupdate把这一帧的所有顶点信息用一个mesh绘制。
有人问为什么不在材质上设置参数呢? 这样一来不就一个 pop 对应一个材质了嘛,drawcall 不就上去了?
这样一来就解决了以上两个问题,不用cpu插值, 动态物体drawcall只有一次
思路来自于此 http://www.cnblogs.com/lxzCode/p/4780360.html
哈哈,是不是很眼熟
if (mFilter == null) mFilter = gameObject.GetComponent<MeshFilter>();
if (mFilter == null) mFilter = gameObject.AddComponent<MeshFilter>();
// Create the mesh
if (mMesh == null)
{
mMesh = new Mesh();
mMesh.hideFlags = HideFlags.DontSave;
mMesh.name = "Mesh";
mMesh.MarkDynamic();
}
mMesh.Clear();
mMesh.vertices = verts.ToArray();
mMesh.uv = uvs.ToArray();
mMesh.colors32 = cols.ToArray();
mMesh.normals = vertex1.ToArray();
mMesh.tangents = vertex2.ToArray();
mMesh.uv1 = vertex3.ToArray();
int triangleCount = (vertex_count >> 1) * 3;
mMesh.triangles = GenerateCachedIndexBuffer(vertex_count, triangleCount);
mFilter.mesh = mMesh;
if (mRenderer == null) mRenderer = gameObject.GetComponent<MeshRenderer>();
if (mRenderer == null) mRenderer = gameObject.AddComponent<MeshRenderer>();
struct appdata_m
{
float4 vertex : POSITION;
float3 vertex1 : NORMAL; ///这里记录第二帧的位置信息
float4 vertex2 : TANGENT;///这里记录第三帧的位置信息
float2 vertex3 : TEXCOORD1;///这里记录第四帧的位置信息
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
v2f_m vert (appdata_m v)
{
v2f_m o;
_CurTime = _Time.y - _StartTime;
if(_CurTime <= v.vertex1.z) {
_vertex1 = float3(v.vertex1.x, v.vertex1.y, 0);
_Factor = _CurTime / v.vertex1.z;
_vec = lerp(v.vertex.xyz, _vertex1, _Factor);
_alpha = lerp(v.color.a, v.color.r, _Factor);
}
else if (_CurTime <= v.vertex2.z) {
_vertex1 = float3(v.vertex1.x, v.vertex1.y, 0);
_vertex2 = float3(v.vertex2.x, v.vertex2.y, 0);
_Factor = (_CurTime - v.vertex1.z) / (v.vertex2.z - v.vertex1.z);
_vec = lerp(_vertex1, _vertex2, _Factor);
_alpha = lerp(v.color.r, v.color.g, _Factor);
}
else {
_vertex2 = float3(v.vertex2.x, v.vertex2.y, 0);
_vertex3 = float3(v.vertex2.w, v.vertex3.x, 0);
_Factor = (_CurTime - v.vertex2.z) / (v.vertex3.y - v.vertex2.z);
_vec = lerp(_vertex2, _vertex3, _Factor);
_alpha = lerp(v.color.g, v.color.b, _Factor);
}
...
return o;
}
接下来只要mesh给予带运动轨迹的顶点信息,采用VertexAnimation Shader即可
魅族测试
源码
https://git.oschina.net/daao/Vertex_HUD
or
https://github.com/daaoling/Vertex_HUD