Пример #1
0
    void BakeTexture(Mesh mesh)
    {
        var vs    = mesh.vertices;
        var tris  = mesh.triangles;
        var lines = new List <LineInfo>();

        for (var i = 0; i < tris.Length / 3; i++)
        {
            var idx0 = tris[i * 3 + 0];
            var idx1 = tris[i * 3 + 1];
            var idx2 = tris[i * 3 + 2];

            var l0 = new LineInfo(idx0, idx1);
            var l1 = new LineInfo(idx1, idx2);
            var l2 = new LineInfo(idx2, idx0);

            new[] { l0, l1, l2 }.Where(ln => lines.Where(l => l.idx0 == ln.idx0 && l.idx1 == ln.idx1).Count() < 1).ToList().ForEach(l => lines.Add(l));
        }
        var ls      = lines.ToArray();
        var vBuffer = new ComputeBuffer(vs.Length, System.Runtime.InteropServices.Marshal.SizeOf(typeof(Vector3)));
        var lBuffer = new ComputeBuffer(ls.Length, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LineInfo)));

        vBuffer.SetData(vs);
        lBuffer.SetData(ls);

        output = new RenderTexture(Mathf.NextPowerOfTwo(ls.Length), 2, 0, RenderTextureFormat.ARGBHalf);
        output.enableRandomWrite = true;
        output.Create();

        var kernel = lineTexGen.FindKernel("CSMain");

        lineTexGen.SetBuffer(kernel, "_VBuffer", vBuffer);
        lineTexGen.SetBuffer(kernel, "_LBuffer", lBuffer);
        lineTexGen.SetTexture(kernel, "Output", output);
        uint x, y, z;

        lineTexGen.GetKernelThreadGroupSizes(kernel, out x, out y, out z);
        lineTexGen.Dispatch(kernel, (int)(ls.Length / x) + 1, 1, 1);

        vBuffer.Release();
        lBuffer.Release();

        var folderName = "BakedLineTex";
        var folderPath = Path.Combine("Assets", folderName);

        if (!AssetDatabase.IsValidFolder(folderPath))
        {
            AssetDatabase.CreateFolder("Assets", folderName);
        }

        var tex2d = RenderTextureToTexture2D.Convert(output);

        AssetDatabase.CreateAsset(tex2d, Path.Combine(folderPath, mesh.name + string.Format("_line.{0}.asset", ls.Length)));
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        Selection.activeObject = tex2d;
    }
Пример #2
0
    void SaveBlured()
    {
        var tex  = RenderTextureToTexture2D.Convert(bTex);
        var path = AssetDatabase.GetAssetPath(source);

        path  = System.IO.Path.GetDirectoryName(path);
        path += string.Format("/{0}_blur.asset", source.name);
        AssetDatabase.CreateAsset(tex, path);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        Selection.activeObject = tex;
    }
Пример #3
0
        private void BakeTextures(int texWidth, int texHeight, int verticesCount, ref List <VertInfo> infoList)
        {
            // bake  the vertexes and normals into the textures
            var positionsRenderTexture = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBHalf);
            var normalRenderTexture    = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBHalf);

            positionTexture            = new Texture2D(texWidth, texHeight, TextureFormat.RGBAHalf, false, false);
            normalTexture              = new Texture2D(texWidth, texHeight, TextureFormat.RGBAHalf, false, false);
            positionTexture.wrapMode   = TextureWrapMode.Clamp;
            normalTexture.wrapMode     = TextureWrapMode.Clamp;
            positionTexture.filterMode = FilterMode.Point;
            normalTexture.filterMode   = FilterMode.Point;

            foreach (var rt in new[] { positionsRenderTexture, normalRenderTexture })
            {
                rt.enableRandomWrite = true;
                rt.Create();
                RenderTexture.active = rt;
                GL.Clear(true, true, Color.clear);
            }

            var buffer = new ComputeBuffer(infoList.Count, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertInfo)));

            buffer.SetData(infoList.ToArray());

            var  kernel = infoTexGen.FindKernel("CSMain");
            uint x, y, z;

            infoTexGen.GetKernelThreadGroupSizes(kernel, out x, out y, out z);
            infoTexGen.SetInt("VertCount", verticesCount);
            infoTexGen.SetBuffer(kernel, "Info", buffer);
            infoTexGen.SetTexture(kernel, "OutPosition", positionsRenderTexture);
            infoTexGen.SetTexture(kernel, "OutNormal", normalRenderTexture);
            infoTexGen.Dispatch(kernel, verticesCount / (int)x + 1, texHeight / (int)y + 1, 1);

            // convert the texture back to normal texture2d then to texture
            var posTex  = RenderTextureToTexture2D.Convert(positionsRenderTexture);
            var normTex = RenderTextureToTexture2D.Convert(normalRenderTexture);

            Graphics.CopyTexture(posTex, positionTexture);
            Graphics.CopyTexture(normTex, normalTexture);
            // release all the buffer data
            positionsRenderTexture.Release();
            normalRenderTexture.Release();
            buffer.Release();
            positionTexture.Apply();
            normalTexture.Apply();
        }
Пример #4
0
    private void CreateAssets(AnimationState state, List <VertInfo> infoList)
    {
        var buffer = new ComputeBuffer(infoList.Count, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertInfo)));

        buffer.SetData(infoList.ToArray());

        var  kernel = infoTexGen.FindKernel("CSMain");
        uint x, y, z;

        infoTexGen.GetKernelThreadGroupSizes(kernel, out x, out y, out z);

        infoTexGen.SetInt("VertCount", vCount);
        infoTexGen.SetBuffer(kernel, "Info", buffer);
        infoTexGen.SetTexture(kernel, "OutPosition", pRt);
        infoTexGen.SetTexture(kernel, "OutNormal", nRt);
        infoTexGen.Dispatch(kernel, vCount / (int)x + 1, frames / (int)y + 1, 1);

        buffer.Release();

#if UNITY_EDITOR
        var posTex  = RenderTextureToTexture2D.Convert(pRt);
        var normTex = RenderTextureToTexture2D.Convert(nRt);
        Graphics.CopyTexture(pRt, posTex);
        Graphics.CopyTexture(nRt, normTex);

        var bta = new BakedTextureAnimation();
        bta.fullPathHash        = Animator.StringToHash(string.Format("Base Layer.{0}", state.name));
        bta.animationName       = state.name;
        bta.positionAnimTexture = posTex;
        bta.normalAnimTexture   = normTex;
        bta.texelSize           = new Vector4(1.0f / posTex.width, 1.0f / posTex.height, posTex.width, posTex.height);
        bakedTextureAnimations.Add(bta);
        go.GetComponent <TextureAnimations>().SetItemSource(bakedTextureAnimations);

        AssetDatabase.CreateAsset(posTex, Path.Combine(folderPath, pRt.name + ".asset"));
        AssetDatabase.CreateAsset(normTex, Path.Combine(folderPath, nRt.name + ".asset"));

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        prefab = PrefabUtility.ReplacePrefab(go, prefab);
#endif
    }
    public static Texture2D ConvertTextureUV(Texture tex, Mesh mesh, int width = 512, int height = 512)
    {
        var rt = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);

        RenderTexture.active = rt;
        GL.Clear(true, true, Color.clear);

        uvConverter.mainTexture = tex;
        uvConverter.SetFloat("_Alpha", 1f);
        uvConverter.SetPass(0);
        Graphics.SetRenderTarget(rt);
        Graphics.DrawMeshNow(mesh, Matrix4x4.identity);

        var tex2d = RenderTextureToTexture2D.Convert(rt);

        if (tex2d.format == TextureFormat.ARGB32)
        {
            var data = tex2d.EncodeToPNG();
            System.IO.File.WriteAllBytes("converted.png", data);
        }
        rt.Release();
        return(tex2d);
    }
    void Bake()
    {
        var skin     = GetComponentInChildren <SkinnedMeshRenderer>();
        var vCount   = skin.sharedMesh.vertexCount;
        var texWidth = Mathf.NextPowerOfTwo(vCount);
        var mesh     = new Mesh();

        foreach (var clip in clips)
        {
            var frames   = Mathf.NextPowerOfTwo((int)(clip.length / 0.05f));
            var dt       = clip.length / frames;
            var infoList = new List <VertInfo>();

            var pRt = new RenderTexture(texWidth, frames, 0, RenderTextureFormat.ARGBHalf);
            pRt.name = string.Format("{0}.{1}.posTex", name, clip.name);
            var nRt = new RenderTexture(texWidth, frames, 0, RenderTextureFormat.ARGBHalf);
            nRt.name = string.Format("{0}.{1}.normTex", name, clip.name);
            foreach (var rt in new[] { pRt, nRt })
            {
                rt.enableRandomWrite = true;
                rt.Create();
                RenderTexture.active = rt;
                GL.Clear(true, true, Color.clear);
            }

            for (var i = 0; i < frames; i++)
            {
                clip.SampleAnimation(gameObject, dt * i);
                skin.BakeMesh(mesh);

                infoList.AddRange(Enumerable.Range(0, vCount)
                                  .Select(idx => new VertInfo()
                {
                    position = mesh.vertices[idx],
                    normal   = mesh.normals[idx]
                })
                                  );
            }
            var buffer = new ComputeBuffer(infoList.Count, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertInfo)));
            buffer.SetData(infoList.ToArray());

            var  kernel = infoTexGen.FindKernel("CSMain");
            uint x, y, z;
            infoTexGen.GetKernelThreadGroupSizes(kernel, out x, out y, out z);

            infoTexGen.SetInt("VertCount", vCount);
            infoTexGen.SetBuffer(kernel, "Info", buffer);
            infoTexGen.SetTexture(kernel, "OutPosition", pRt);
            infoTexGen.SetTexture(kernel, "OutNormal", nRt);
            infoTexGen.Dispatch(kernel, vCount / (int)x + 1, frames / (int)y + 1, 1);

            buffer.Release();

#if UNITY_EDITOR
            var folderName = "BakedAnimationTex";
            var folderPath = Path.Combine("Assets", folderName);
            if (!AssetDatabase.IsValidFolder(folderPath))
            {
                AssetDatabase.CreateFolder("Assets", folderName);
            }

            var subFolder     = name;
            var subFolderPath = Path.Combine(folderPath, subFolder);
            if (!AssetDatabase.IsValidFolder(subFolderPath))
            {
                AssetDatabase.CreateFolder(folderPath, subFolder);
            }

            var posTex  = RenderTextureToTexture2D.Convert(pRt);
            var normTex = RenderTextureToTexture2D.Convert(nRt);
            Graphics.CopyTexture(pRt, posTex);
            Graphics.CopyTexture(nRt, normTex);

            var mat = new Material(playShader);
            mat.SetTexture("_MainTex", skin.sharedMaterial.mainTexture);
            mat.SetTexture("_PosTex", posTex);
            mat.SetTexture("_NmlTex", normTex);
            mat.SetFloat("_Length", clip.length);
            if (clip.wrapMode == WrapMode.Loop)
            {
                mat.SetFloat("_Loop", 1f);
                mat.EnableKeyword("ANIM_LOOP");
            }

            var go = new GameObject(name + "." + clip.name);
            go.AddComponent <MeshRenderer>().sharedMaterial = mat;
            go.AddComponent <MeshFilter>().sharedMesh       = skin.sharedMesh;

            AssetDatabase.CreateAsset(posTex, Path.Combine(subFolderPath, pRt.name + ".asset"));
            AssetDatabase.CreateAsset(normTex, Path.Combine(subFolderPath, nRt.name + ".asset"));
            AssetDatabase.CreateAsset(mat, Path.Combine(subFolderPath, string.Format("{0}.{1}.animTex.asset", name, clip.name)));
            PrefabUtility.CreatePrefab(Path.Combine(folderPath, go.name + ".prefab").Replace("\\", "/"), go);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
#endif
        }
    }
        private void Bake(AnimationClip[] clips)
        {
            if (!infoTexGen)
            {
                infoTexGen = (ComputeShader)Resources.Load("AnimationBaker/Shaders/MeshInfoTextureGen", typeof(ComputeShader));
            }
            if (!playShader)
            {
                playShader = (Shader)Resources.Load("AnimationBaker/Shaders/LitBakedStatePlayer", typeof(Shader));
            }

            AssetDatabase.SaveAssets();

            var instance          = Instantiate(graph.Prefab, Vector3.zero, Quaternion.identity);
            var instanceTransform = instance.transform;
            var skinRenderer      = FindSkinnedMeshRenderer(instanceTransform);

            for (int i = 0; i < skinRenderer.sharedMaterials.Length; i++)
            {
                var mat          = skinRenderer.sharedMaterials[i];
                var materialPath = outputPath + "/" + mat.name + ".mat";
                if (File.Exists(materialPath))
                {
                    File.Delete(materialPath);
                }
            }

            var dataPathLength = Application.dataPath.Length - 6;

            var meshPath = outputPath + "/" + cleanName + "Mesh.asset";

            if (File.Exists(meshPath))
            {
                File.Delete(meshPath);
            }
            meshPath = meshPath.Substring(dataPathLength);

            var positionTexturePath = StringUtils.Combine(outputPath, "Positions.asset");

            if (File.Exists(positionTexturePath))
            {
                File.Delete(positionTexturePath);
            }
            positionTexturePath = positionTexturePath.Substring(dataPathLength);

            var normalTexturePath = StringUtils.Combine(outputPath, "Normals.asset");

            if (File.Exists(normalTexturePath))
            {
                File.Delete(normalTexturePath);
            }
            normalTexturePath = normalTexturePath.Substring(dataPathLength);

            var prefabPath = StringUtils.Combine(outputPath, cleanName + ".prefab");

            if (File.Exists(prefabPath))
            {
                File.Delete(prefabPath);
            }
            prefabPath = prefabPath.Substring(dataPathLength);

            AssetDatabase.Refresh();

            var newAnimation = FindAnimation(instanceTransform);
            var boneMeshes   = new List <MeshFilter>();

            FindMeshInBones(boneMeshes, instanceTransform);
            var  skinTransform = skinRenderer.transform;
            var  oldMesh       = skinRenderer.sharedMesh;
            Mesh newMesh       = new Mesh();
            var  offset        = PopulateMesh(newMesh, oldMesh, boneMeshes, skinRenderer.transform);
            var  verticesCount = newMesh.vertexCount;

            // Save mesh

            AssetDatabase.CreateAsset(newMesh, meshPath);
            graph.rendererData.Mesh         = newMesh;
            graph.rendererData.SubMeshCount = newMesh.subMeshCount;

            var scale = Vector3.one;

            scale.x = 1 / rootBone.localScale.x;
            scale.y = 1 / rootBone.localScale.y;
            scale.z = 1 / rootBone.localScale.z;

            var totalClips  = 0;
            var frames      = new List <int>();
            var frameDeltas = new List <float>();
            var totalFrames = 0;
            var finalClips  = new List <AnimationClip>();

            for (int i = 0; i < clips.Length; i++)
            {
                var clip  = clips[i];
                var delta = clip.frameRate * 0.001f;
                var frame = Mathf.CeilToInt(clip.length / delta);
                frames.Add(frame);
                frameDeltas.Add(delta);
                totalFrames += frame;
                totalClips++;
                finalClips.Add(clip);
            }

            // to store metadata
            totalFrames += 1;

            var texHeight = Mathf.NextPowerOfTwo(totalFrames);
            var texWidth  = Mathf.NextPowerOfTwo(verticesCount);

            // store first cell:
            // total clips

            // second cell and beyond:
            // x: frame count
            // y: 1 / framerate
            // z: offset
            // w: wrap mode:
            //    0 play once the revert to default
            //    1 play once the revert to default
            //    2 loop
            //    4 not implemented
            //    8 play once then hold

            var infoList = new List <VertInfo>();

            int texOffset = 1;

            // infoList.Add(new VertInfo { position = new Vector3(totalClips, 0, 0), normal = Vector3.zero });

            for (int i = 0; i < frames.Count; i++)
            {
                infoList.Add(new VertInfo
                {
                    position = new Vector3(frames[i], finalClips[i].length, texOffset),
                    normal   = Vector3.zero,
                    extra    = (int)finalClips[i].wrapMode
                });
                texOffset += (int)frames[i];
            }
            for (int i = totalClips; i < verticesCount; i++)
            {
                infoList.Add(new VertInfo
                {
                    position = Vector3.zero, normal = Vector3.zero
                });
            }

            var boneOffset = Vector3.zero;
            var boneScale  = 0f;
            var animMesh   = new Mesh();

            for (int i = 0; i < finalClips.Count; i++)
            {
                var clip = finalClips[i];
                var dt   = 0f;
                var len  = 0;
                while (dt < clip.length)
                {
                    clip.SampleAnimation(instance, Mathf.Clamp(dt, 0, clip.length));
                    skinRenderer.BakeMesh(animMesh);
                    if (boneScale == 0)
                    {
                        var bounds = new Bounds();
                        for (int j = 0; j < animMesh.vertexCount; j++)
                        {
                            var point = skinTransform.TransformPoint(animMesh.vertices[j]);
                            if (j == 0)
                            {
                                bounds.center = point;
                            }
                            bounds.Encapsulate(point);
                        }
                        foreach (var filter in boneMeshes)
                        {
                            var boneMesh = filter.sharedMesh;
                            for (int j = 0; j < boneMesh.vertexCount; j++)
                            {
                                var point = filter.transform.TransformPoint(boneMesh.vertices[j]);
                                bounds.Encapsulate(point);
                            }
                        }
                        boneScale    = newMesh.bounds.size.y / bounds.size.y;
                        boneOffset.y = 0 - bounds.min.y;
                    }

                    for (int j = 0; j < animMesh.vertexCount; j++)
                    {
                        var vert = (skinTransform.TransformPoint(animMesh.vertices[j]) + boneOffset) * boneScale;
                        infoList.Add(new VertInfo {
                            position = vert, normal = animMesh.normals[j], extra = 1
                        });
                    }
                    foreach (var filter in boneMeshes)
                    {
                        var mesh = filter.sharedMesh;
                        for (int k = 0; k < mesh.vertexCount; k++)
                        {
                            var vert = (filter.transform.TransformPoint(mesh.vertices[k]) + boneOffset) * boneScale;
                            infoList.Add(new VertInfo {
                                position = vert, normal = mesh.normals[k], extra = 1
                            });
                        }
                    }
                    len++;
                    dt += frameDeltas[i];
                }
            }

            var positionsRenderTexture = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBHalf);
            var normalRenderTexture    = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBHalf);
            var positionTexture        = new Texture2D(texWidth, texHeight, TextureFormat.RGBAHalf, false, false);

            positionTexture.wrapMode   = TextureWrapMode.Clamp;
            positionTexture.filterMode = FilterMode.Point;
            var normalTexture = new Texture2D(texWidth, texHeight, TextureFormat.RGBAHalf, false, false);

            normalTexture.wrapMode   = TextureWrapMode.Clamp;
            normalTexture.filterMode = FilterMode.Point;

            foreach (var rt in new [] { positionsRenderTexture, normalRenderTexture })
            {
                rt.enableRandomWrite = true;
                rt.Create();
                RenderTexture.active = rt;
                GL.Clear(true, true, Color.clear);
            }

            var buffer = new ComputeBuffer(infoList.Count, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertInfo)));

            buffer.SetData(infoList.ToArray());

            var  kernel = infoTexGen.FindKernel("CSMain");
            uint x, y, z;

            infoTexGen.GetKernelThreadGroupSizes(kernel, out x, out y, out z);

            infoTexGen.SetInt("VertCount", verticesCount);
            infoTexGen.SetBuffer(kernel, "Info", buffer);
            infoTexGen.SetTexture(kernel, "OutPosition", positionsRenderTexture);
            infoTexGen.SetTexture(kernel, "OutNormal", normalRenderTexture);
            infoTexGen.Dispatch(kernel, verticesCount / (int)x + 1, texHeight / (int)y + 1, 1);

            var posTex  = RenderTextureToTexture2D.Convert(positionsRenderTexture);
            var normTex = RenderTextureToTexture2D.Convert(normalRenderTexture);

            Graphics.CopyTexture(posTex, positionTexture);
            Graphics.CopyTexture(normTex, normalTexture);

            positionsRenderTexture.Release();
            normalRenderTexture.Release();

            buffer.Release();

            AssetDatabase.CreateAsset(positionTexture, positionTexturePath);
            AssetDatabase.CreateAsset(normalTexture, normalTexturePath);

            // var pngData = positionTexture.EncodeToPNG();
            // System.IO.File.WriteAllBytes(Utils.Combine(outputPath, "DebugPositions.png"), pngData);

            AssetDatabase.Refresh();

            var materials = new Material[skinRenderer.sharedMaterials.Length];

            graph.rendererData.Materials         = new Material[skinRenderer.sharedMaterials.Length];
            graph.rendererData.ShadowCastingMode = skinRenderer.shadowCastingMode;
            graph.rendererData.ReceivesShadows   = skinRenderer.receiveShadows;
            for (int i = 0; i < skinRenderer.sharedMaterials.Length; i++)
            {
                var mat = new Material(playShader);
                mat.name = string.Format("{0}.{1}.Material", cleanName, i);
                mat.SetTexture("_MainTex", skinRenderer.sharedMaterials[i].mainTexture);
                mat.SetColor("_Color", skinRenderer.sharedMaterials[i].color);
                mat.SetTexture("_PosTex", positionTexture);
                mat.SetTexture("_NmlTex", normalTexture);
                mat.enableInstancing = true;
                var materialPath = outputPath + "/" + mat.name + ".mat";
                materialPath = materialPath.Substring(dataPathLength);
                AssetDatabase.CreateAsset(mat, materialPath);
                materials[i] = mat;
                graph.rendererData.Materials[i] = mat;
            }
            var go = new GameObject(cleanName);

            go.AddComponent <MeshFilter>().sharedMesh = newMesh;
            AssetDatabase.Refresh();
            var assembly      = Assembly.GetAssembly(typeof(StateGraph));
            var componentType = assembly.GetType("AnimationBaker.Baked." + cleanName + "Component");

            go.AddComponent(componentType);
            var mr = go.AddComponent <MeshRenderer>();

            mr.sharedMaterials = materials;
            mr.material        = materials[0];

            PrefabUtility.CreatePrefab(prefabPath, go);
            DestroyImmediate(go);
            DestroyImmediate(instance);
            EditorUtility.SetDirty(graph.rendererData);
        }
Пример #8
0
    public void Vector3ToTex()
    {
        if (string.IsNullOrEmpty(outputPath))
        {
            return;
        }

        if (_data == null || _data.Length == 0)
        {
            Debug.Log("<color=red>target data is empty</color>");
            return;
        }

        if (string.IsNullOrEmpty(outputPath))
        {
            folderPath = outputPath;
        }
        else
        {
            folderPath = Path.Combine("Assets", outputPath);
        }

        int texWidth  = Mathf.NextPowerOfTwo(_data.Length);
        int texHeight = 2;

        Debug.Log("positionData.Length : " + _data.Length);
        Debug.Log("texWidth : " + texWidth);

        RenderTexture rt = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBFloat);

        rt.name = textureName;
        rt.enableRandomWrite = true;
        rt.Create();
        RenderTexture.active = rt;
        GL.Clear(true, true, Color.clear);


        //for (int i = 0; i < _data.Length; i++)
        //{
        //}
        _dataBuffer = new ComputeBuffer(_data.Length, Marshal.SizeOf(typeof(Data)));
        //positionDataBuf.SetData(_positionData);
        _dataBuffer.SetData(_data);
        texGen.SetTexture(0, "output", rt);
        //texGen.SetBuffer(0, "positionBuf", positionDataBuf);
        texGen.SetBuffer(0, "dataBuf", _dataBuffer);

        //texGen.Dispatch(0, _positionData.Length / 8 + 1, 1, 1);
        texGen.Dispatch(0, _data.Length / 8 + 1, 1, 1);

        tex = RenderTextureToTexture2D.Convert(rt);

        for (int i = 0; i < tex.width; i++)
        {
            var pos          = tex.GetPixel(i, 0);
            var distrubution = tex.GetPixel(i, 1);
            //Debug.Log("<color=green>" + pos + "</color>");
            //Debug.Log("<color=red>" + distrubution + "</color>");
        }

        string fileName      = rt.name + ".asset";
        string assetFilePath = Path.Combine("Assets/", fileName);

#if UNITY_EDITOR
        UnityEditor.AssetDatabase.CreateAsset(tex, assetFilePath);
        UnityEditor.AssetDatabase.SaveAssets();
        UnityEditor.AssetDatabase.Refresh();
#endif

        //Copy file to destination
        string toPath = Path.Combine(folderPath, fileName);

        Debug.Log("toPath : " + toPath);
        File.Copy(assetFilePath, toPath, true);

        if (rt != null)
        {
            rt.Release();
        }

        if (_dataBuffer != null)
        {
            _dataBuffer.Release();
        }

        Debug.Log("<color=green>bake completed</color>");
    }
Пример #9
0
    // Use this for initialization
    void Start()
    {
        if (mesh == null && GetComponent <MeshFilter>() != null)
        {
            mesh = GetComponent <MeshFilter>().sharedMesh;
        }
        if (mesh == null && GetComponent <SkinnedMeshRenderer>() != null)
        {
            mesh = GetComponent <SkinnedMeshRenderer>().sharedMesh;
        }

        var rts = MeshInfoTexture.GeneratePositionNormalTexture(mesh, texSize, texSize);

        var     positionTex = RenderTextureToTexture2D.Convert(rts[0]);
        var     normalTex   = RenderTextureToTexture2D.Convert(rts[1]);
        Texture colorTex    = null;

        if (originColTex != null)
        {
            colorTex = MeshInfoTexture.ConvertTextureUV(originColTex, mesh, texSize, texSize);
        }

        var uvBuffer = new ComputeBuffer(
            texSize * texSize,
            SizeOf(typeof(Vector2)),
            ComputeBufferType.Append);
        var uvCounter = new ComputeBuffer(
            1,
            SizeOf(typeof(int)),
            ComputeBufferType.IndirectArguments);

        uvBuffer.SetCounterValue(0);

        var kernel = sampler.FindKernel("sampleOpaqueTexel");

        sampler.SetInt("TexSize", texSize);
        sampler.SetTexture(kernel, "Tex", positionTex);
        sampler.SetBuffer(kernel, "OpaqueUv", uvBuffer);
        sampler.Dispatch(kernel, texSize / 8, texSize / 8, 1);

        var count = new[] { 0 };

        uvCounter.SetData(count);
        ComputeBuffer.CopyCount(uvBuffer, uvCounter, 0);
        uvCounter.GetData(count);
        var numUvs = count[0];

        Debug.Log(numUvs);

        var width  = texSize / 2;
        var height = Mathf.NextPowerOfTwo(numUvs / width);
        var rt     = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat);

        rt.enableRandomWrite = true;
        rt.Create();
        RenderTexture.active = rt;
        GL.Clear(true, true, Color.clear);

        kernel = sampler.FindKernel("buildUvTex");
        sampler.SetInt("TexSize", width);
        sampler.SetInt("NumUvs", numUvs);
        sampler.SetBuffer(kernel, "UvPool", uvBuffer);
        sampler.SetTexture(kernel, "Output", rt);
        sampler.Dispatch(kernel, width / 8, height / 8, 1);

        uvBuffer.Release();
        uvCounter.Release();

        var uvTex = RenderTextureToTexture2D.Convert(rt);

        positionTex.filterMode = normalTex.filterMode = colorTex.filterMode = uvTex.filterMode = FilterMode.Point;
        positionTex.wrapMode   = normalTex.wrapMode = colorTex.wrapMode = uvTex.wrapMode = TextureWrapMode.Clamp;

        rt.Release();
        rts[0].Release();
        rts[1].Release();


#if UNITY_EDITOR
        if (!AssetDatabase.IsValidFolder(assetFolderPath))
        {
            AssetDatabase.CreateFolder("Assets", assetFolderName);
        }
        AssetDatabase.CreateAsset(positionTex, string.Format("{0}/{1}_pos.asset", assetFolderPath, mesh.name));
        AssetDatabase.CreateAsset(normalTex, string.Format("{0}/{1}_norm.asset", assetFolderPath, mesh.name));
        if (colorTex != null)
        {
            AssetDatabase.CreateAsset(colorTex, string.Format("{0}/{1}_col.asset", assetFolderPath, mesh.name));
        }
        AssetDatabase.CreateAsset(uvTex, string.Format("{0}/{1}_uv.asset", assetFolderPath, mesh.name));

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
#endif
    }
    private void animatorRootMeshFix()
    {
#if UNITY_EDITOR
        var      sampleGO = Instantiate(this.gameObject, Vector3.zero, Quaternion.identity) as GameObject;
        Animator animator = sampleGO.GetComponentInChildren <Animator>();
        if (animator != null)
        {
            animator.cullingMode     = AnimatorCullingMode.AlwaysAnimate;
            animator.applyRootMotion = ApplyRootMotion;
        }
        var skin     = sampleGO.GetComponentInChildren <SkinnedMeshRenderer>();
        var vCount   = skin.sharedMesh.vertexCount;
        var texWidth = Mathf.NextPowerOfTwo(vCount);

        var dictOnStateAndClips = FillDictionaryOfClipsAndStates(animator);

        foreach (var keyValue in dictOnStateAndClips)
        {
            var  clip            = keyValue.Value;
            var  stateName       = keyValue.Key;
            bool DoNeedToProcess = false;
            foreach (var item in clipsToBake)
            {
                DoNeedToProcess |= item.name == clip.name;
            }
            if (!DoNeedToProcess)
            {
                continue;
            }
            var frames   = Mathf.NextPowerOfTwo((int)(clip.length / 0.05f));
            var infoList = new List <VertInfo>();

            var pRt = new RenderTexture(texWidth, frames, 0, RenderTextureFormat.ARGBHalf);
            pRt.name = string.Format("{0}.{1}.posTex", name, clip.name);
            var nRt = new RenderTexture(texWidth, frames, 0, RenderTextureFormat.ARGBHalf);
            nRt.name = string.Format("{0}.{1}.normTex", name, clip.name);
            var tRt = new RenderTexture(texWidth, frames, 0, RenderTextureFormat.ARGBHalf);
            tRt.name = string.Format("{0}.{1}.tanTex", name, clip.name);
            foreach (var rt in new[] { pRt, nRt, tRt })
            {
                rt.enableRandomWrite = true;
                rt.Create();
                RenderTexture.active = rt;
                GL.Clear(true, true, Color.clear);
            }

            int bakeFrames = Mathf.CeilToInt(frames);
            var dt         = clip.length / frames;
            animator.Play(stateName, 0, 0);
            for (int i = 0; i < frames; i++)
            {
                float bakeDelta = Mathf.Clamp01(((float)i / frames));
                EditorUtility.DisplayProgressBar("Baking Animation", string.Format("Processing: {0} Frame: {1}", stateName, i), bakeDelta);
                float animationTime = bakeDelta * clip.length;
                animator.Update(dt);
                Mesh m = new Mesh();
                skin.BakeMesh(m);
                infoList.AddRange(
                    Enumerable.Range(0, vCount)
                    .Select(idx => new VertInfo()
                {
                    position = m.vertices[idx],
                    normal   = m.normals[idx],
                    tangent  = m.tangents[idx],
                })
                    );
                DestroyImmediate(m);
                // debug only
                // Instantiate(sampleGO, i * Vector3.right, Quaternion.identity);
            }


            var buffer = new ComputeBuffer(infoList.Count, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertInfo)));
            buffer.SetData(infoList.ToArray());

            var  kernel = infoTexGen.FindKernel("CSMain");
            uint x, y, z;
            infoTexGen.GetKernelThreadGroupSizes(kernel, out x, out y, out z);
            infoTexGen.SetInt("VertCount", vCount);
            infoTexGen.SetBuffer(kernel, "Info", buffer);
            infoTexGen.SetTexture(kernel, "OutPosition", pRt);
            infoTexGen.SetTexture(kernel, "OutNormal", nRt);
            infoTexGen.SetTexture(kernel, "OutTangent", tRt);
            infoTexGen.Dispatch(kernel, vCount / (int)x + 1, frames / (int)y + 1, 1);
            buffer.Release();

            var folderName = "BakedAnimationTex";
            var folderPath = Path.Combine("Assets", folderName);
            if (!AssetDatabase.IsValidFolder(folderPath))
            {
                AssetDatabase.CreateFolder("Assets", folderName);
            }

            var subFolder     = name;
            var subFolderPath = Path.Combine(folderPath, subFolder);
            if (!AssetDatabase.IsValidFolder(subFolderPath))
            {
                AssetDatabase.CreateFolder(folderPath, subFolder);
            }

            var posTex  = RenderTextureToTexture2D.Convert(pRt);
            var normTex = RenderTextureToTexture2D.Convert(nRt);
            var tanTex  = RenderTextureToTexture2D.Convert(tRt);
            Graphics.CopyTexture(pRt, posTex);
            Graphics.CopyTexture(nRt, normTex);
            Graphics.CopyTexture(tRt, tanTex);

            var mat = new Material(playShader);
            mat.SetTexture("_MainTex", skin.sharedMaterial.mainTexture);
            mat.SetTexture("_PosTex", posTex);
            mat.SetTexture("_NmlTex", normTex);
            mat.SetFloat("_Length", clip.length);
            if (clip.wrapMode == WrapMode.Loop)
            {
                mat.SetFloat("_Loop", 1f);
                mat.EnableKeyword("ANIM_LOOP");
            }

            var go = new GameObject(name + "." + clip.name);
            go.AddComponent <MeshRenderer>().sharedMaterial = mat;
            go.AddComponent <MeshFilter>().sharedMesh       = skin.sharedMesh;

            AssetDatabase.CreateAsset(posTex, Path.Combine(subFolderPath, pRt.name + ".asset"));
            AssetDatabase.CreateAsset(normTex, Path.Combine(subFolderPath, nRt.name + ".asset"));
            AssetDatabase.CreateAsset(tanTex, Path.Combine(subFolderPath, tRt.name + ".asset"));
            AssetDatabase.CreateAsset(mat, Path.Combine(subFolderPath, string.Format("{0}.{1}.animTex.asset", name, clip.name)));
            PrefabUtility.SaveAsPrefabAsset(go, Path.Combine(folderPath, go.name + ".prefab").Replace("\\", "/"));
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            EditorUtility.ClearProgressBar();
        }
        GameObject.DestroyImmediate(sampleGO);
#endif
    }