private void ReleaseBuffer() { #if USE_CONSTANT_BUFFER #else foreach (var obj in vertexCachePool) { VertexCache vertexCache = obj.Value; vertexCache.bufVertex.Release(); vertexCache.bufVertex = null; if (vertexCache.bufInstance != null) { vertexCache.bufInstance.Release(); vertexCache.bufInstance = null; } foreach (var buf in vertexCache.bufArgs) { buf.Release(); } vertexCache.bufArgs = null; } #endif if (vertexCachePool != null) { vertexCachePool.Clear(); } }
private void Render() { foreach (var obj in vertexCachePool) { VertexCache vertexCache = obj.Value; for (int k = 0; k != vertexCache.packageList.Length; ++k) { for (int i = 0; i != vertexCache.packageList[k].Count; ++i) { VertexCache.InstancingPackage package = vertexCache.packageList[k][i]; if (package.instancingCount == 0) { continue; } for (int j = 0; j != package.subMeshCount; ++j) { if (UseInstancing) { #if UNITY_EDITOR PreparePackageMaterial(package, vertexCache, k); #endif package.propertyBlock.SetFloatArray("frameIndex", vertexCache.instanceData.FrameIndex[k][i]); package.propertyBlock.SetFloatArray("preFrameIndex", vertexCache.instanceData.PreFrameIndex[k][i]); package.propertyBlock.SetFloatArray("transitionProgress", vertexCache.instanceData.TransitionProgress[k][i]); Graphics.DrawMeshInstanced(vertexCache.mesh, j, package.material[j], vertexCache.instanceData.WorldMatrix[k][i], package.instancingCount, package.propertyBlock, ShadowCastingMode.On, true, 0); } else { package.material[j].SetFloat("frameIndex", vertexCache.instanceData.FrameIndex[k][i][0]); package.material[j].SetFloat("preFrameIndex", vertexCache.instanceData.PreFrameIndex[k][i][0]); package.material[j].SetFloat("transitionProgress", vertexCache.instanceData.TransitionProgress[k][i][0]); Graphics.DrawMesh(vertexCache.mesh, vertexCache.instanceData.WorldMatrix[k][i][0], package.material[j], 0, null, j); } } package.instancingCount = 0; } vertexCache.runtimePackageIndex[k] = 0; } } }
protected internal override void Draw(int X, int Y) { if (this.m_Invalidated) { this.Refresh(); } if (!this.m_Draw) { return; } Renderer.PushAlpha(this.m_fAlpha); if (!this.m_Clip) { if (this.m_vCache == null) { this.m_vCache = this.VCPool.GetInstance(); } this.m_vCache.Draw(this.m_Image, X, Y); } else if (!this.m_Relative) { this.m_Image.DrawClipped(X, Y, this.m_Clipper); } else { this.m_Image.DrawClipped(X, Y, Clipper.TemporaryInstance(X + this.m_xClipOffset, Y + this.m_yClipOffset, this.m_xClipWidth, this.m_yClipHeight)); } Renderer.PopAlpha(); }
public VertexCache FindVertexCache(int renderName) { VertexCache cache = null; vertexCachePool.TryGetValue(renderName, out cache); return(cache); }
protected internal override void Draw(int x, int y) { if (this.m_Invalidated) { this.Refresh(); } if (!this.m_Draw) { return; } Renderer.PushAlpha(this.m_fAlpha); if (this.m_Clipper == null) { if (this.m_vCache == null) { this.m_vCache = this.VCPool.GetInstance(); } this.m_vCache.Draw(this.m_Image, x, y); } else { this.m_Image.DrawClipped(x, y, this.m_Clipper); } Renderer.PopAlpha(); }
public override void OnStop() { this.VCPool.ReleaseInstance(this.m_vCache); this.m_vCache = (VertexCache)null; this.VCPool.ReleaseInstance(this.m_vCache); this.m_vCacheDouble = (VertexCache)null; }
public void BindAttachment(VertexCache parentCache, VertexCache attachmentCache, Mesh sharedMesh, int boneIndex) { Matrix4x4 mat = parentCache.bindPose[boneIndex].inverse; attachmentCache.mesh = Instantiate(sharedMesh); Vector3 offset = mat.GetColumn(3); Quaternion q = RuntimeHelper.QuaternionFromMatrix(mat); Vector3[] vertices = attachmentCache.mesh.vertices; for (int k = 0; k != attachmentCache.mesh.vertexCount; ++k) { vertices[k] = q * vertices[k]; vertices[k] = vertices[k] + offset; } attachmentCache.mesh.vertices = vertices; for (int j = 0; j != attachmentCache.mesh.vertexCount; ++j) { attachmentCache.weight[j].x = 1.0f; attachmentCache.weight[j].y = -0.1f; attachmentCache.weight[j].z = -0.1f; attachmentCache.weight[j].w = -0.1f; attachmentCache.boneIndex[j].x = boneIndex; } }
private VertexCache CreateVertexCache(string prefabName, int renderName, int alias, Mesh mesh) { VertexCache vertexCache = new VertexCache(); int cacheName = renderName + alias; vertexCachePool[cacheName] = vertexCache; vertexCache.nameCode = cacheName; vertexCache.mesh = mesh; vertexCache.boneTextureIndex = FindTexture_internal( prefabName); //因为Texture不是从AnimationInfo读进来的,而是作为BoneInfo读入,所以需要在这里通过prefabName将boneTexture和vertexCache连起来。 vertexCache.weight = new Vector4[mesh.vertexCount]; vertexCache.boneIndex = new Vector4[mesh.vertexCount]; int packageCount = 1; if (vertexCache.boneTextureIndex >= 0) //如果找到了boneTexture,那么packageCount装载为该prefab的BoneTexture数。 { BoneTextureInfo texture = _boneTextrueInfo[vertexCache.boneTextureIndex]; packageCount = texture.BoneTexture.Length; } //建立了packageList,也是空的。 vertexCache.packageList = new List <VertexCache.InstancingPackage> [packageCount]; for (int i = 0; i != vertexCache.packageList.Length; ++i) { vertexCache.packageList[i] = new List <VertexCache.InstancingPackage>(); } vertexCache.runtimePackageIndex = new int[packageCount]; InstanceData data = null; int instanceName = prefabName.GetHashCode() + alias; //这里往instanceDataPool里面加入了一个空的data,只有Instancename。,并且创建只进行到List<float[]>[]的List层次,往List里面注入float[]在CreatPackage里面完成。 if (!instanceDataPool.TryGetValue(instanceName, out data)) { data = new InstanceData(); data.WorldMatrix = new List <Matrix4x4[]> [packageCount]; data.FrameIndex = new List <float[]> [packageCount]; data.PreFrameIndex = new List <float[]> [packageCount]; data.TransitionProgress = new List <float[]> [packageCount]; for (int i = 0; i != packageCount; ++i) { data.WorldMatrix[i] = new List <Matrix4x4[]>(); data.FrameIndex[i] = new List <float[]>(); data.PreFrameIndex[i] = new List <float[]>(); data.TransitionProgress[i] = new List <float[]>(); } instanceDataPool.Add(instanceName, data); } vertexCache.instanceData = data; return(vertexCache); }
int GetPackageCount(VertexCache vertexCache) { int packageCount = 1; if (vertexCache.boneTextureIndex >= 0) { AnimationTexture texture = animationTextureList[vertexCache.boneTextureIndex]; packageCount = texture.boneTexture.Length; } return(packageCount); }
private void SetupVertexCache(VertexCache vertexCache, MeshRenderer render, Mesh mesh, Transform[] boneTransform, int bonePerVertex) { int boneIndex = -1; if (boneTransform != null) { for (int k = 0; k != boneTransform.Length; ++k) { if (render.transform.parent.name.GetHashCode() == boneTransform[k].name.GetHashCode()) { boneIndex = k; break; } } } #if USE_CONSTANT_BUFFER if (boneIndex >= 0) { BindAttachment(vertexCache, vertexCache.mesh, boneIndex); } #else for (int j = 0; j != mesh.vertexCount; ++j) { vertexCache.vertex[j].weight.x = 1.0f; vertexCache.vertex[j].weight.y = -0.1f; vertexCache.vertex[j].weight.z = -0.1f; vertexCache.vertex[j].weight.w = -0.1f; vertexCache.vertex[j].boneIndex1 = boneIndex[0]; } #endif if (vertexCache.materials == null) { vertexCache.materials = render.materials; } #if USE_CONSTANT_BUFFER SetupAdditionalData(vertexCache); for (int i = 0; i != vertexCache.packageList.Length; ++i) { VertexCache.InstancingPackage package = CreatePackage(vertexCache.instanceData, vertexCache.mesh, render.materials, i); vertexCache.packageList[i].Add(package); PreparePackageMaterial(package, vertexCache, i); } #else vertexCache.bufVertex = new ComputeBuffer(vertexCache.vertex.Length, 16 + 16); vertexCache.bufVertex.SetData(vertexCache.vertex); #endif }
/// <summary> /// Finalize arrays for vertices and polygons /// by linking to cached versions /// </summary> public void FinalizePVArrays() { for (var i = 0; i < VertexArray.Vertices.Count; i++) { VertexArray.Vertices[i] = VertexCache.Get(VertexArray.Vertices[i]); } for (var i = 0; i < Polygons.Count; i++) { Polygons[i] = PolygonCache.Get(Polygons[i]); } }
public GItemArt(int x, int y, int itemID, IHue hue) : base(x, y) { this.m_vCache = new VertexCache(); this.m_Hue = hue; this.m_ItemID = itemID; this.m_Image = hue.GetItem(itemID); if (this.m_Image == null || this.m_Image.IsEmpty()) { return; } this.m_Width = this.m_Image.Width; this.m_Height = this.m_Image.Height; this.m_Draw = true; }
public int WriteVertex(byte[] vertexData, int posIdx, Vector2 texCoord) { if (_vertices[posIdx] == null) { _vertices[posIdx] = new List <VertexCache>(); _taken[posIdx] = true; } VertexCache vc = new VertexCache(posIdx, texCoord, _count); _vertices[posIdx].Add(vc); _vertexBufferData.Write(vertexData, 0, vertexData.Length); _count++; return(vc.VertexBufferIndex); }
/// <summary> /// 设置anim_ins鱼类的效果 /// </summary> /// <param name="go"></param> /// <param name="val"></param> public void SetInnerEffectState(GameObject go, int val) { AnimationInstancing.LodInfo[] lodinfo = go.GetComponentInChildren <AnimationInstancing>().lodInfo; for (int i = 0; i < lodinfo.Length; i++) { AnimationInstancing.LodInfo lod = lodinfo[i]; for (int h = 0; h < lod.vertexCacheList.Length; h++) { VertexCache cache = lod.vertexCacheList[h]; foreach (var block in cache.instanceBlockList) { block.Value.instanceData.isshowInner = val; } } } }
/// <summary> /// Constructs a polygon from the DAT file /// </summary> public Polygon(DatLoader.Entity.Polygon polygon, DatLoader.Entity.CVertexArray vertexArray) { NegSurface = polygon.NegSurface; //NegUVIndices = polygon.NegUVIndices; PosSurface = polygon.PosSurface; //PosUVIndices = polygon.PosUVIndices; SidesType = polygon.SidesType; Stippling = polygon.Stippling; VertexIDs = polygon.VertexIds; Vertices = new List <Vertex>(); foreach (var vertexIdx in VertexIDs) { Vertices.Add(VertexCache.Get(vertexArray.Vertices[(ushort)vertexIdx])); } make_plane(); }
public void PreparePackageMaterial(InstancingPackage package, VertexCache vertexCache, int aniTextureIndex) { if (vertexCache.boneTextureIndex < 0) { return; } for (int i = 0; i != package.subMeshCount; ++i) { AnimationTexture texture = animationTextureList[vertexCache.boneTextureIndex]; package.material[i].SetTexture("_boneTexture", texture.boneTexture[aniTextureIndex]); package.material[i].SetInt("_boneTextureWidth", texture.boneTexture[aniTextureIndex].width); package.material[i].SetInt("_boneTextureHeight", texture.boneTexture[aniTextureIndex].height); package.material[i].SetInt("_boneTextureBlockWidth", texture.blockWidth); package.material[i].SetInt("_boneTextureBlockHeight", texture.blockHeight); } }
void RefreshMaterial() { if (vertexCachePool == null) { return; } foreach (var obj in vertexCachePool) { VertexCache cache = obj.Value; for (int j = 0; j != cache.packageList.Length; ++j) { for (int k = 0; k != cache.packageList[j].Count; ++k) { VertexCache.InstancingPackage package = cache.packageList[j][k]; PreparePackageMaterial(package, cache, j); } } } }
//SetupVertexCache(vertexCache, lod.meshRenderer[i], m, bones, bonePerVertex); private void SetupVertexCache(VertexCache vertexCache, MeshRenderer render, Mesh mesh, Transform[] boneTransform, int bonePerVertex) { int boneIndex = -1; if (boneTransform != null) { for (int k = 0; k != boneTransform.Length; ++k) { //找到vertexCache对应render的parent在boneTransform中的对应序号。 if (render.transform.parent.name.GetHashCode() == boneTransform[k].name.GetHashCode()) { boneIndex = k; break; } } } if (boneIndex >= 0) { BindAttachment(vertexCache, vertexCache.mesh, boneIndex); } if (vertexCache.materials == null) { vertexCache.materials = render.sharedMaterials; //材质从render.sharedMaterials里面获得,来自于prefab的materials,故需要在prefab中就对Materials更改为InstacingShader。 } SetupAdditionalData(vertexCache); for (int i = 0; i != vertexCache.packageList.Length; ++i) { VertexCache.InstancingPackage package = CreatePackage(vertexCache.instanceData, vertexCache.mesh, render.sharedMaterials, i); vertexCache.packageList[i].Add(package); PreparePackageMaterial(package, vertexCache, i); } }
public void Draw(int x, int y) { if (!this.m_Draw) { return; } x += this.m_X; y += this.m_Y; if (this.m_Tile) { this.m_Image.Draw(x, y, this.m_Width, this.m_Height, 16777215); } else { if (this.m_vCache == null) { this.m_vCache = new VertexCache(); } this.m_vCache.Draw(this.m_Image, x, y); } }
public void SetupAdditionalData(VertexCache vertexCache) { Color[] colors = new Color[vertexCache.weight.Length]; for (int i = 0; i != colors.Length; ++i) { colors[i].r = vertexCache.weight[i].x; colors[i].g = vertexCache.weight[i].y; colors[i].b = vertexCache.weight[i].z; colors[i].a = vertexCache.weight[i].w; } vertexCache.mesh.colors = colors; List <Vector4> uv2 = new List <Vector4>(vertexCache.boneIndex.Length); for (int i = 0; i != vertexCache.boneIndex.Length; ++i) { uv2.Add(vertexCache.boneIndex[i]); } vertexCache.mesh.SetUVs(2, uv2); vertexCache.mesh.UploadMeshData(false); }
MaterialBlock CreateBlock(VertexCache cache, Material[] materials) { MaterialBlock block = new MaterialBlock(); int packageCount = GetPackageCount(cache); block.instanceData = CreateInstanceData(packageCount); block.packageList = new List <InstancingPackage> [packageCount]; for (int i = 0; i != block.packageList.Length; ++i) { block.packageList[i] = new List <InstancingPackage>(); InstancingPackage package = CreatePackage(block.instanceData, cache.mesh, materials, i); block.packageList[i].Add(package); PreparePackageMaterial(package, cache, i); package.instancingCount = 1; } block.runtimePackageIndex = new int[packageCount]; return(block); }
public int WriteVertex(byte[] vertexData, int posIdx, int normalIdx, int texCoordIdx) { _taken[posIdx] = true; if (_vertices[posIdx] == null) { _vertices[posIdx] = new List <VertexCache>(); } VertexCache vc = new VertexCache { PosIndex = posIdx, NormalIndex = normalIdx, TexCoordIndex = texCoordIdx, VertexBufferIndex = _count }; _vertices[posIdx].Add(vc); _vertexBufferData.Write(vertexData, 0, vertexData.Length); _count++; return(vc.VertexBufferIndex); }
private VertexCache CreateVertexCache(string prefabName, int renderName, int alias, Mesh mesh) { VertexCache vertexCache = new VertexCache(); int cacheName = renderName + alias; vertexCachePool[cacheName] = vertexCache; vertexCache.nameCode = cacheName; vertexCache.mesh = mesh; vertexCache.boneTextureIndex = FindTexture_internal(prefabName); vertexCache.weight = new Vector4[mesh.vertexCount]; vertexCache.boneIndex = new Vector4[mesh.vertexCount]; int packageCount = GetPackageCount(vertexCache); InstanceData data = null; int instanceName = prefabName.GetHashCode() + alias; if (!instanceDataPool.TryGetValue(instanceName, out data)) { data = CreateInstanceData(packageCount); instanceDataPool.Add(instanceName, data); } vertexCache.instanceBlockList = new Dictionary <int, MaterialBlock>(); return(vertexCache); }
private void SetupVertexCache(VertexCache vertexCache, MaterialBlock block, MeshRenderer render, Mesh mesh, Transform[] boneTransform, int bonePerVertex) { int boneIndex = -1; if (boneTransform != null) { for (int k = 0; k != boneTransform.Length; ++k) { if (render.transform.parent.name.GetHashCode() == boneTransform[k].name.GetHashCode()) { boneIndex = k; break; } } } if (boneIndex >= 0) { //todo BindAttachment(vertexCache, vertexCache, vertexCache.mesh, boneIndex); } if (vertexCache.materials == null) { vertexCache.materials = render.sharedMaterials; } SetupAdditionalData(vertexCache); for (int i = 0; i != block.packageList.Length; ++i) { InstancingPackage package = CreatePackage(block.instanceData, vertexCache.mesh, render.sharedMaterials, i); block.packageList[i].Add(package); PreparePackageMaterial(package, vertexCache, i); } }
// alias is to use for attachment, it's usually a bone name public void AddMeshVertex(string prefabName, AnimationInstancing.LodInfo[] lodInfo, Transform[] bones, List <Matrix4x4> bindPose, int bonePerVertex, string alias = null) { UnityEngine.Profiling.Profiler.BeginSample("AddMeshVertex()"); for (int x = 0; x != lodInfo.Length; ++x) { AnimationInstancing.LodInfo lod = lodInfo[x]; for (int i = 0; i != lod.skinnedMeshRenderer.Length; ++i) { Mesh m = lod.skinnedMeshRenderer[i].sharedMesh; if (m == null) { continue; } int nameCode = lod.skinnedMeshRenderer[i].name.GetHashCode(); VertexCache cache = null; if (vertexCachePool.TryGetValue(nameCode, out cache)) { lod.vertexCacheList[i] = cache; #if !USE_CONSTANT_BUFFER ++cache.instancingCount; #endif continue; } VertexCache vertexCache = CreateVertexCache(prefabName, nameCode, 0, m); vertexCache.bindPose = bindPose.ToArray(); lod.vertexCacheList[i] = vertexCache; SetupVertexCache(vertexCache, lod.skinnedMeshRenderer[i], bones, bonePerVertex); } for (int i = 0, j = lod.skinnedMeshRenderer.Length; i != lod.meshRenderer.Length; ++i, ++j) { Mesh m = lod.meshFilter[i].sharedMesh; if (m == null) { continue; } int renderName = lod.meshRenderer[i].name.GetHashCode(); int aliasName = (alias != null ? alias.GetHashCode() : 0); VertexCache cache = null; if (vertexCachePool.TryGetValue(renderName + aliasName, out cache)) { lod.vertexCacheList[j] = cache; #if !USE_CONSTANT_BUFFER ++cache.instancingCount; #endif continue; } VertexCache vertexCache = CreateVertexCache(prefabName, renderName, aliasName, m); if (bindPose != null) { vertexCache.bindPose = bindPose.ToArray(); } lod.vertexCacheList[lod.skinnedMeshRenderer.Length + i] = vertexCache; SetupVertexCache(vertexCache, lod.meshRenderer[i], m, bones, bonePerVertex); } #if !USE_CONSTANT_BUFFER foreach (var obj in vertexCachePool) { VertexCache vertexCache = obj.Value; for (int j = 0; j != vertexCache.subMeshCount; ++j) { Material material = vertexCache.instanceMaterial[j]; material.SetBuffer("buf_Vertex", vertexCache.bufVertex); } } #endif } UnityEngine.Profiling.Profiler.EndSample(); }
private void SetupVertexCache(VertexCache vertexCache, MaterialBlock block, SkinnedMeshRenderer render, Transform[] boneTransform, int bonePerVertex) { int[] boneIndex = null; if (render.bones.Length != boneTransform.Length) { if (render.bones.Length == 0) { boneIndex = new int[1]; int hashRenderParentName = render.transform.parent.name.GetHashCode(); for (int k = 0; k != boneTransform.Length; ++k) { if (hashRenderParentName == boneTransform[k].name.GetHashCode()) { boneIndex[0] = k; break; } } } else { boneIndex = new int[render.bones.Length]; for (int j = 0; j != render.bones.Length; ++j) { boneIndex[j] = -1; Transform trans = render.bones[j]; int hashTransformName = trans.name.GetHashCode(); for (int k = 0; k != boneTransform.Length; ++k) { if (hashTransformName == boneTransform[k].name.GetHashCode()) { boneIndex[j] = k; break; } } } if (boneIndex.Length == 0) { boneIndex = null; } } } UnityEngine.Profiling.Profiler.BeginSample("Copy the vertex data in SetupVertexCache()"); Mesh m = render.sharedMesh; BoneWeight[] boneWeights = m.boneWeights; Debug.Assert(boneWeights.Length > 0); for (int j = 0; j != m.vertexCount; ++j) { vertexCache.weight[j].x = boneWeights[j].weight0; Debug.Assert(vertexCache.weight[j].x > 0.0f); vertexCache.weight[j].y = boneWeights[j].weight1; vertexCache.weight[j].z = boneWeights[j].weight2; vertexCache.weight[j].w = boneWeights[j].weight3; vertexCache.boneIndex[j].x = boneIndex == null ? boneWeights[j].boneIndex0 : boneIndex[boneWeights[j].boneIndex0]; vertexCache.boneIndex[j].y = boneIndex == null ? boneWeights[j].boneIndex1 : boneIndex[boneWeights[j].boneIndex1]; vertexCache.boneIndex[j].z = boneIndex == null ? boneWeights[j].boneIndex2 : boneIndex[boneWeights[j].boneIndex2]; vertexCache.boneIndex[j].w = boneIndex == null ? boneWeights[j].boneIndex3 : boneIndex[boneWeights[j].boneIndex3]; Debug.Assert(vertexCache.boneIndex[j].x >= 0); if (bonePerVertex == 3) { float rate = 1.0f / (vertexCache.weight[j].x + vertexCache.weight[j].y + vertexCache.weight[j].z); vertexCache.weight[j].x = vertexCache.weight[j].x * rate; vertexCache.weight[j].y = vertexCache.weight[j].y * rate; vertexCache.weight[j].z = vertexCache.weight[j].z * rate; vertexCache.weight[j].w = -0.1f; } else if (bonePerVertex == 2) { float rate = 1.0f / (vertexCache.weight[j].x + vertexCache.weight[j].y); vertexCache.weight[j].x = vertexCache.weight[j].x * rate; vertexCache.weight[j].y = vertexCache.weight[j].y * rate; vertexCache.weight[j].z = -0.1f; vertexCache.weight[j].w = -0.1f; } else if (bonePerVertex == 1) { vertexCache.weight[j].x = 1.0f; vertexCache.weight[j].y = -0.1f; vertexCache.weight[j].z = -0.1f; vertexCache.weight[j].w = -0.1f; } } UnityEngine.Profiling.Profiler.EndSample(); if (vertexCache.materials == null) { vertexCache.materials = render.sharedMaterials; } SetupAdditionalData(vertexCache); for (int i = 0; i != block.packageList.Length; ++i) { InstancingPackage package = CreatePackage(block.instanceData, vertexCache.mesh, render.sharedMaterials, i); block.packageList[i].Add(package); //vertexCache.packageList[i].Add(package); PreparePackageMaterial(package, vertexCache, i); } }
// alias is to use for attachment, it should be a bone name public void AddMeshVertex(string prefabName, AnimationInstancing.LodInfo[] lodInfo, Transform[] bones, List <Matrix4x4> bindPose, int bonePerVertex, string alias = null) { UnityEngine.Profiling.Profiler.BeginSample("AddMeshVertex()"); for (int x = 0; x != lodInfo.Length; ++x) { AnimationInstancing.LodInfo lod = lodInfo[x]; for (int i = 0; i != lod.skinnedMeshRenderer.Length; ++i) { Mesh m = lod.skinnedMeshRenderer[i].sharedMesh; if (m == null) { continue; } int nameCode = lod.skinnedMeshRenderer[i].name.GetHashCode(); int identify = GetIdentify(lod.skinnedMeshRenderer[i].sharedMaterials); VertexCache cache = null; if (vertexCachePool.TryGetValue(nameCode, out cache)) { MaterialBlock block = null; if (!cache.instanceBlockList.TryGetValue(identify, out block)) { block = CreateBlock(cache, lod.skinnedMeshRenderer[i].sharedMaterials); cache.instanceBlockList.Add(identify, block); } lod.vertexCacheList[i] = cache; lod.materialBlockList[i] = block; continue; } VertexCache vertexCache = CreateVertexCache(prefabName, nameCode, 0, m); vertexCache.bindPose = bindPose.ToArray(); MaterialBlock matBlock = CreateBlock(vertexCache, lod.skinnedMeshRenderer[i].sharedMaterials); vertexCache.instanceBlockList.Add(identify, matBlock); SetupVertexCache(vertexCache, matBlock, lod.skinnedMeshRenderer[i], bones, bonePerVertex); lod.vertexCacheList[i] = vertexCache; lod.materialBlockList[i] = matBlock; } for (int i = 0, j = lod.skinnedMeshRenderer.Length; i != lod.meshRenderer.Length; ++i, ++j) { Mesh m = lod.meshFilter[i].sharedMesh; if (m == null) { continue; } int renderName = lod.meshRenderer[i].name.GetHashCode(); int aliasName = (alias != null ? alias.GetHashCode() : 0); int identify = GetIdentify(lod.meshRenderer[i].sharedMaterials); VertexCache cache = null; if (vertexCachePool.TryGetValue(renderName + aliasName, out cache)) { MaterialBlock block = null; if (!cache.instanceBlockList.TryGetValue(identify, out block)) { block = CreateBlock(cache, lod.meshRenderer[i].sharedMaterials); cache.instanceBlockList.Add(identify, block); } lod.vertexCacheList[j] = cache; lod.materialBlockList[j] = block; continue; } VertexCache vertexCache = CreateVertexCache(prefabName, renderName, aliasName, m); if (bindPose != null) { vertexCache.bindPose = bindPose.ToArray(); } MaterialBlock matBlock = CreateBlock(vertexCache, lod.meshRenderer[i].sharedMaterials); vertexCache.instanceBlockList.Add(identify, matBlock); SetupVertexCache(vertexCache, matBlock, lod.meshRenderer[i], m, bones, bonePerVertex); lod.vertexCacheList[lod.skinnedMeshRenderer.Length + i] = vertexCache; lod.materialBlockList[lod.skinnedMeshRenderer.Length + i] = matBlock; } } UnityEngine.Profiling.Profiler.EndSample(); }
void ApplyBoneMatrix() { Vector3 cameraPosition = cameraTransform.position; for (int i = 0; i != aniInstancingList.Count; ++i) { AnimationInstancing instance = aniInstancingList[i]; if (!instance.IsPlaying()) { continue; } if (instance.aniIndex < 0 && instance.parentInstance == null) { continue; } if (instance.applyRootMotion) { ApplyRootMotion(instance); } instance.UpdateAnimation(); instance.boundingSpere.position = instance.transform.position; boundingSphere[i] = instance.boundingSpere; if (!instance.visible) { continue; } instance.UpdateLod(cameraPosition); AnimationInstancing.LodInfo lod = instance.lodInfo[instance.lodLevel]; int aniTextureIndex = -1; if (instance.parentInstance != null) { aniTextureIndex = instance.parentInstance.aniTextureIndex; } else { aniTextureIndex = instance.aniTextureIndex; } for (int j = 0; j != lod.vertexCacheList.Length; ++j) { VertexCache cache = lod.vertexCacheList[j]; MaterialBlock block = lod.materialBlockList[j]; Debug.Assert(block != null); int packageIndex = block.runtimePackageIndex[aniTextureIndex]; Debug.Assert(packageIndex < block.packageList[aniTextureIndex].Count); InstancingPackage package = block.packageList[aniTextureIndex][packageIndex]; if (package.instancingCount + 1 > instancingPackageSize) { ++block.runtimePackageIndex[aniTextureIndex]; packageIndex = block.runtimePackageIndex[aniTextureIndex]; if (packageIndex >= block.packageList[aniTextureIndex].Count) { InstancingPackage newPackage = CreatePackage(block.instanceData, cache.mesh, cache.materials, aniTextureIndex); block.packageList[aniTextureIndex].Add(newPackage); PreparePackageMaterial(newPackage, cache, aniTextureIndex); newPackage.instancingCount = 1; } block.packageList[aniTextureIndex][packageIndex].instancingCount = 1; } else { ++package.instancingCount; } { VertexCache vertexCache = cache; InstanceData data = block.instanceData; int index = block.runtimePackageIndex[aniTextureIndex]; InstancingPackage pkg = block.packageList[aniTextureIndex][index]; int count = pkg.instancingCount - 1; if (count >= 0) { Matrix4x4 worldMat = instance.worldTransform.localToWorldMatrix; Matrix4x4[] arrayMat = data.worldMatrix[aniTextureIndex][index]; arrayMat[count].m00 = worldMat.m00; arrayMat[count].m01 = worldMat.m01; arrayMat[count].m02 = worldMat.m02; arrayMat[count].m03 = worldMat.m03; arrayMat[count].m10 = worldMat.m10; arrayMat[count].m11 = worldMat.m11; arrayMat[count].m12 = worldMat.m12; arrayMat[count].m13 = worldMat.m13; arrayMat[count].m20 = worldMat.m20; arrayMat[count].m21 = worldMat.m21; arrayMat[count].m22 = worldMat.m22; arrayMat[count].m23 = worldMat.m23; arrayMat[count].m30 = worldMat.m30; arrayMat[count].m31 = worldMat.m31; arrayMat[count].m32 = worldMat.m32; arrayMat[count].m33 = worldMat.m33; float frameIndex = 0, preFrameIndex = -1, transition = 0f; if (instance.parentInstance != null) { frameIndex = instance.parentInstance.aniInfo[instance.parentInstance.aniIndex].animationIndex + instance.parentInstance.curFrame; if (instance.parentInstance.preAniIndex >= 0) { preFrameIndex = instance.parentInstance.aniInfo[instance.parentInstance.preAniIndex].animationIndex + instance.parentInstance.preAniFrame; } transition = instance.parentInstance.transitionProgress; } else { frameIndex = instance.aniInfo[instance.aniIndex].animationIndex + instance.curFrame; if (instance.preAniIndex >= 0) { preFrameIndex = instance.aniInfo[instance.preAniIndex].animationIndex + instance.preAniFrame; } transition = instance.transitionProgress; } data.frameIndex[aniTextureIndex][index][count] = frameIndex; data.preFrameIndex[aniTextureIndex][index][count] = preFrameIndex; data.transitionProgress[aniTextureIndex][index][count] = transition; } } } } }
private void Render() { foreach (var obj in vertexCachePool) { VertexCache vertexCache = obj.Value; foreach (var block in vertexCache.instanceBlockList) { List <InstancingPackage>[] packageList = block.Value.packageList; for (int k = 0; k != packageList.Length; ++k) { for (int i = 0; i != packageList[k].Count; ++i) { InstancingPackage package = packageList[k][i]; if (package.instancingCount == 0) { continue; } for (int j = 0; j != package.subMeshCount; ++j) { InstanceData data = block.Value.instanceData; if (useInstancing) { #if UNITY_EDITOR PreparePackageMaterial(package, vertexCache, k); #endif package.propertyBlock.SetFloatArray("frameIndex", data.frameIndex[k][i]); package.propertyBlock.SetFloatArray("preFrameIndex", data.preFrameIndex[k][i]); package.propertyBlock.SetFloatArray("transitionProgress", data.transitionProgress[k][i]); Graphics.DrawMeshInstanced(vertexCache.mesh, j, package.material[j], data.worldMatrix[k][i], package.instancingCount, package.propertyBlock, vertexCache.shadowcastingMode, vertexCache.receiveShadow, vertexCache.layer); } else { package.material[j].SetFloat("frameIndex", data.frameIndex[k][i][0]); package.material[j].SetFloat("preFrameIndex", data.preFrameIndex[k][i][0]); package.material[j].SetFloat("transitionProgress", data.transitionProgress[k][i][0]); Graphics.DrawMesh(vertexCache.mesh, data.worldMatrix[k][i][0], package.material[j], 0, null, j); } } package.instancingCount = 0; } block.Value.runtimePackageIndex[k] = 0; } } // if (obj.Value.instancingData == null) // continue; // vertexCache.bufInstance.SetData(obj.Value.instancingData); // // for (int i = 0; i != vertexCache.subMeshCount; ++i) // { // Material material = vertexCache.instanceMaterial[i]; // material.SetBuffer("buf_InstanceMatrices", vertexCache.bufInstance); // vertexCache.args[i][1] = (uint)vertexCache.currentInstancingIndex; // vertexCache.bufArgs[i].SetData(vertexCache.args[i]); // // Graphics.DrawMeshInstancedIndirect(vertexCache.mesh, // i, // vertexCache.instanceMaterial[i], // new Bounds(Vector3.zero, new Vector3(10000.0f, 10000.0f, 10000.0f)), // vertexCache.bufArgs[i]); // } // vertexCache.currentInstancingIndex = 0; } }
private VertexCache CreateVertexCache(string prefabName, int renderName, int alias, Mesh mesh) { VertexCache vertexCache = new VertexCache(); int cacheName = renderName + alias; vertexCachePool[cacheName] = vertexCache; vertexCache.nameCode = cacheName; vertexCache.mesh = mesh; vertexCache.boneTextureIndex = FindTexture_internal(prefabName); #if USE_CONSTANT_BUFFER vertexCache.weight = new Vector4[mesh.vertexCount]; vertexCache.boneIndex = new Vector4[mesh.vertexCount]; int packageCount = 1; if (vertexCache.boneTextureIndex >= 0) { AnimationTexture texture = animationTextureList[vertexCache.boneTextureIndex]; packageCount = texture.boneTexture.Length; } vertexCache.packageList = new List <VertexCache.InstancingPackage> [packageCount]; for (int i = 0; i != vertexCache.packageList.Length; ++i) { vertexCache.packageList[i] = new List <VertexCache.InstancingPackage>(); } vertexCache.runtimePackageIndex = new int[packageCount]; InstanceData data = null; int instanceName = prefabName.GetHashCode() + alias; if (!instanceDataPool.TryGetValue(instanceName, out data)) { data = new InstanceData(); data.worldMatrix = new List <Matrix4x4[]> [packageCount]; data.frameIndex = new List <float[]> [packageCount]; for (int i = 0; i != packageCount; ++i) { data.worldMatrix[i] = new List <Matrix4x4[]>(); data.frameIndex[i] = new List <float[]>(); } instanceDataPool.Add(instanceName, data); } vertexCache.instanceData = data; #else ++vertexCache.instancingCount; //vertexCache.indexCount = new uint[m.subMeshCount]; vertexCache.args = new uint[mesh.subMeshCount][]; vertexCache.vertex = new InstancingVertex[mesh.vertexCount]; vertexCache.bufArgs = new ComputeBuffer[mesh.subMeshCount]; vertexCache.instanceMaterial = new Material[mesh.subMeshCount]; vertexCache.subMeshCount = mesh.subMeshCount; uint startIndex = 0; for (int j = 0; j != mesh.subMeshCount; ++j) { vertexCache.args[j] = new uint[5]; vertexCache.bufArgs[j] = new ComputeBuffer(1, vertexCache.args[j].Length * sizeof(uint), ComputeBufferType.IndirectArguments); vertexCache.args[j][0] = mesh.GetIndexCount(j); vertexCache.args[j][2] = startIndex; startIndex = vertexCache.args[j][0]; vertexCache.bufArgs[j].SetData(vertexCache.args[j]); vertexCache.instanceMaterial[j] = new Material(renderer.materials[j]); vertexCache.instanceMaterial[j].DisableKeyword("USE_CONSTANT_BUFFER"); vertexCache.instanceMaterial[j].EnableKeyword("USE_COMPUTE_BUFFER"); AnimationTexture texture = animationTextureList[vertexCache.boneTextureIndex] as AnimationTexture; vertexCache.instanceMaterial[j].SetTexture("_boneTexture", texture.boneTexture); //vertexCache.instanceMaterial[j].SetTexture("_albedoTexture", renderer.materials[j].GetTexture("_MainTex")); vertexCache.instanceMaterial[j].SetInt("_boneTextureBlockWidth", texture.blockWidth); vertexCache.instanceMaterial[j].SetInt("_boneTextureBlockHeight", texture.blockHeight); vertexCache.instanceMaterial[j].SetInt("_boneTextureWidth", texture.boneTexture.width); vertexCache.instanceMaterial[j].SetInt("_boneTextureHeight", texture.boneTexture.height); } #endif return(vertexCache); }