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; }
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; }
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(); }
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); }
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>"); }
// 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 }