private void BakeAnimationsToTexture() { if (matricesTex != null) { Color[] colorBuffer = matricesTex.GetPixels(); int colorBufferIndex = 0; hierarchyMatrices = new Matrix4x4[colorBuffer.Length / 3]; int hierarchyMatrixIndex = 0; GPUSkinningUtil.ExtractBoneAnimMatrix( gpuSkinning, gpuSkinning.model.boneAnimations[0], (animMat, hierarchyMat) => { hierarchyMatrices[hierarchyMatrixIndex++] = hierarchyMat; Color c = colorBuffer[colorBufferIndex]; c.r = animMat.m00; c.g = animMat.m01; c.b = animMat.m02; c.a = animMat.m03; colorBuffer[colorBufferIndex++] = c; c = colorBuffer[colorBufferIndex]; c.r = animMat.m10; c.g = animMat.m11; c.b = animMat.m12; c.a = animMat.m13; colorBuffer[colorBufferIndex++] = c; c = colorBuffer[colorBufferIndex]; c.r = animMat.m20; c.g = animMat.m21; c.b = animMat.m22; c.a = animMat.m23; colorBuffer[colorBufferIndex++] = c; }, (frameIndex) => { if (frameIndex == 0) { numHierarchyMatricesPerFrame = hierarchyMatrixIndex; numPixelsPerFrame = colorBufferIndex; } } ); matricesTex.SetPixels(colorBuffer); matricesTex.Apply(false, true); } }
public override void Init(GPUSkinning gpuSkinning) { base.Init(gpuSkinning); if (!SystemInfo.supportsComputeShaders) { return; } shaderPropID_Time = Shader.PropertyToID("_GameTime"); // Material Shader shader = Shader.Find("Unlit/ProceduralModel"); if (!shader.isSupported) { return; } proceduralModelMaterial = new Material(shader); proceduralModelMaterial.mainTexture = gpuSkinning.model.newMtrl.mainTexture; // Vertices int[] indices = gpuSkinning.model.newMesh.triangles; Vector3[] vertices = gpuSkinning.model.newMesh.vertices; Vector4[] tangents = gpuSkinning.model.newMesh.tangents; Vector2[] uv = gpuSkinning.model.newMesh.uv; verticesComputeBuffer = new ComputeBuffer(indices.Length, GPUSkinning_ComputeShader_Vertex.size); var data = new GPUSkinning_ComputeShader_Vertex[indices.Length]; for (int i = 0; i < indices.Length; ++i) { var item = new GPUSkinning_ComputeShader_Vertex(); item.vertex = vertices[indices[i]]; item.tangents = tangents[indices[i]]; item.uv = uv[indices[i]]; data[i] = item; } verticesComputeBuffer.SetData(data); numVertices_computeBuffer = data.Length; // Global Data var globalData = new GPUSkinning_CompueteShader_GlobalData(); globalData.fps = gpuSkinning.model.boneAnimations[0].fps; globalData.animLength = gpuSkinning.model.boneAnimations[0].length; // Bone Animation Matrices List <GPUSkinning_ComputeShader_Matrix> cbMatricesList = new List <GPUSkinning_ComputeShader_Matrix>(); int matIndex = 0; GPUSkinningUtil.ExtractBoneAnimMatrix( gpuSkinning, gpuSkinning.model.boneAnimations[0], (animMat, hierarchyMat) => { var matData = new GPUSkinning_ComputeShader_Matrix(); matData.mat = animMat; cbMatricesList.Add(matData); ++matIndex; }, (frameIndex) => { if (frameIndex == 0) { globalData.oneFrameMatricesStride = matIndex; } } ); matricesComputeBuffer = new ComputeBuffer(cbMatricesList.Count, GPUSkinning_ComputeShader_Matrix.size); matricesComputeBuffer.SetData(cbMatricesList.ToArray()); // Global Data globalDataComputeBuffer = new ComputeBuffer(1, GPUSkinning_CompueteShader_GlobalData.size); globalDataComputeBuffer.SetData(new GPUSkinning_CompueteShader_GlobalData[] { globalData }); // Procedural Model Data var modelData = new GPUSkinning_ComputeShader_Model[numProceduralInstances]; int numProceduralModelsPerRow = (int)Mathf.Sqrt(numProceduralInstances); for (int i = 0; i < numProceduralInstances; ++i) { var aModelData = new GPUSkinning_ComputeShader_Model(); int row = i / numProceduralModelsPerRow; int col = i - row * numProceduralModelsPerRow; aModelData.pos = new Vector3(-row * proceduralModelGap, -1, -col * proceduralModelGap); aModelData.time = Random.Range(0.0f, 10.0f); modelData[i] = aModelData; } modelDataComputeBuffer = new ComputeBuffer(numProceduralInstances, GPUSkinning_ComputeShader_Model.size); modelDataComputeBuffer.SetData(modelData); // Draw Procedural Model GPUSkinning_Camera.instance.onPostRender += Draw; }