private static RLEPacketType PacketType(Color32[] _arData, int _iPacketPosition) { if ((_iPacketPosition != _arData.Length - 1) && EncodeToTGAExtension.Equals(_arData[_iPacketPosition], _arData[_iPacketPosition + 1])) { return(RLEPacketType.RLE); } else { return(RLEPacketType.RAW); } }
public static void CombineTextureToTga(string savePath, Texture [] editorArray, bool [] defualts) { Texture2D black = new Texture2D(1, 1, TextureFormat.RGBA32, false); black.SetPixel(0, 0, Color.black); black.Apply(); Texture2D white = new Texture2D(1, 1, TextureFormat.RGBA32, false); white.SetPixel(0, 0, Color.white); white.Apply(); int width = 1; int height = 1; for (int i = 0; i < editorArray.Length; i++) { if (null == editorArray[i]) { if (defualts[i]) { editorArray[i] = white; } else { editorArray[i] = black; } continue; } width = Mathf.Max(width, editorArray[i].width); height = Mathf.Max(height, editorArray[i].height); } if (width == 0) { return; } RenderTexture[] temp = new RenderTexture[editorArray.Length]; Texture2D[] temp2 = new Texture2D[editorArray.Length]; for (int i = 0; i < editorArray.Length; i++) { temp[i] = RenderTexture.GetTemporary(width, height); if (null != editorArray[i]) { Graphics.Blit(editorArray[i], temp[i]); } temp2[i] = new Texture2D(width, height, TextureFormat.RGBA32, false); RenderTexture.active = temp[i]; temp2[i].ReadPixels(new Rect(0, 0, width, height), 0, 0); temp2[i].Apply(); RenderTexture.ReleaseTemporary(temp[i]); } Texture2D final = new Texture2D(width, height, TextureFormat.RGBA32, false); float[] _cols = new float[4]; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { for (int k = 0; k < 4; k++) { //_cols[k] = temp2[k].GetPixel(i, j).r* temp2[k].GetPixel(i, j).a; _cols[k] = temp2[k].GetPixel(i, j).r; } final.SetPixel(i, j, new Color(_cols[0], _cols[1], _cols[2], _cols[3])); } } final.Apply(); for (int i = 0; i < editorArray.Length; i++) { GameObject.DestroyImmediate(temp2[i]); } int iBytesPerPixel = 4; if (editorArray.Length > 3 && (black == editorArray[3] || white == editorArray[3])) { iBytesPerPixel = 3; } //TextureFormat.ARGB32 || _texture2D.format == TextureFormat.RGBA32 byte[] date = EncodeToTGAExtension.EncodeToTGA(final, iBytesPerPixel); //byte[] date = TgaUtil.Texture2DEx.EncodeToTGA(final, true); //byte [] date = final.EncodeToPNG (); System.IO.File.WriteAllBytes(savePath, date); GameObject.DestroyImmediate(final); GameObject.DestroyImmediate(black); GameObject.DestroyImmediate(white); }
void BakeObj() { if (isUVWarp) { if (null == uvMat) { return; } else { CreatePlane(); _meshRender = planeRender; planeRender.sharedMaterial = uvMat; } } else { if (null == _meshRender) { EditorUtility.DisplayDialog("提示", "请选择一个MeshRender对象", "确定"); return; } } //简单的检查. if (!_meshRender.sharedMaterial.HasProperty("S_BAKE")) { EditorUtility.DisplayDialog("提示", "当前物体的材质使用的shader暂时不支持烘焙", "确定"); return; } if (null == cam) { cam = Camera.main; } if (null == cam) { return; } int width = GetSize(index0); int height = GetSize(index1); if (null != rt) { GameObject.DestroyImmediate(rt); } if (fromFirstTexture) { if (uvMat) { width = uvMat.mainTexture.width; height = uvMat.mainTexture.height; } else { width = _meshRender.sharedMaterial.mainTexture.width; height = _meshRender.sharedMaterial.mainTexture.height; } } rt = new RenderTexture(width, height, 24); if (usingSceneViewDirect) { if (SceneView.lastActiveSceneView != null) { bakeCam = CopyCamera(SceneView.lastActiveSceneView.camera, bakeCam); bakeCam.transform.position = SceneView.lastActiveSceneView.camera.transform.position; bakeCam.transform.rotation = SceneView.lastActiveSceneView.camera.transform.rotation; } } else { bakeCam = CopyCamera(cam, bakeCam); } float oldCull = _meshRender.sharedMaterial.GetFloat("_Cull"); _meshRender.sharedMaterial.SetFloat("_Cull", 0f); _meshRender.sharedMaterial.EnableKeyword("S_BAKE"); bakeCam.gameObject.hideFlags = HideFlags.DontSaveInEditor; Vector2 _MainTexOffset = _meshRender.sharedMaterial.mainTextureOffset; Vector2 _MainTexScale = _meshRender.sharedMaterial.mainTextureScale; _MainTexOffset = new Vector2(GetSign(_MainTexOffset.x), GetSign(_MainTexOffset.y)); _MainTexScale = new Vector2(GetSign(_MainTexScale.x), GetSign(_MainTexScale.y)); _meshRender.sharedMaterial.mainTextureOffset = _MainTexOffset; _meshRender.sharedMaterial.mainTextureScale = _MainTexScale; Renderer [] rs = GameObject.FindObjectsOfType <Renderer>(); bool[] rst = new bool[rs.Length]; for (int i = 0; i < rs.Length; i++) { rst[i] = rs[i].enabled; rs[i].enabled = false; } oldPos = _meshRender.transform.position; bakeCam.targetTexture = rt; bakeCam.enabled = true; _meshRender.enabled = true; bakeCam.farClipPlane = 1000; if (!usingSceneViewDirect) { _meshRender.transform.position = bakeCam.transform.position + bakeCam.transform.forward * 500; } bakeCam.Render(); //确保相机包含物体. bakeCam.enabled = false; for (int i = 0; i < rs.Length; i++) { rs[i].enabled = rst[i]; } //br.callback = OnFinish ; _meshRender.sharedMaterial.SetFloat("_Cull", oldCull); _meshRender.sharedMaterial.DisableKeyword("S_BAKE"); _meshRender.transform.position = oldPos; bakeCam.enabled = false; string path = EditorUtility.SaveFilePanelInProject("提示", "TextureName", "tga", "请输入保存文件名"); if (path.Length != 0) { //保存png RenderTexture prev = RenderTexture.active; RenderTexture.active = rt; Texture2D png = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false); png.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); byte[] bytes = EncodeToTGAExtension.EncodeToTGA(png, 3); System.IO.File.WriteAllBytes(path, bytes); Texture2D.DestroyImmediate(png); png = null; RenderTexture.active = prev; AssetDatabase.ImportAsset(path); Texture2D t = AssetDatabase.LoadAssetAtPath <Texture2D>(path); Material mat = new Material(Shader.Find("Mobile/Diffuse")); mat.mainTexture = t; mat.mainTextureScale = _MainTexScale; mat.mainTextureOffset = _MainTexOffset; path = path.Replace(".tga", ".mat"); AssetDatabase.CreateAsset(mat, path); } GameObject.DestroyImmediate(bakeCam.gameObject); }
public static byte[] EncodeToTGA(this Texture2D _texture2D, Compression _compression = Compression.RLE) { const int iTgaHeaderSize = 18; const int iBytesPerPixelRGB24 = 3; // 1 byte per channel (rgb) const int iBytesPerPixelARGB32 = 4; // ~ (rgba) int iBytesPerPixel = _texture2D.format == TextureFormat.ARGB32 || _texture2D.format == TextureFormat.RGBA32 ? iBytesPerPixelARGB32 : iBytesPerPixelRGB24; // using (MemoryStream memoryStream = new MemoryStream(iTgaHeaderSize + _texture2D.width * _texture2D.height * iBytesPerPixel)) { using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { // Write TGA Header binaryWriter.Write((byte)0); // IDLength (not in use) binaryWriter.Write((byte)0); // ColorMapType (not in use) binaryWriter.Write((byte)(_compression == Compression.None ? 2 : 10)); // DataTypeCode (10 == Runlength encoded RGB images) binaryWriter.Write((short)0); // ColorMapOrigin (not in use) binaryWriter.Write((short)0); // ColorMapLength (not in use) binaryWriter.Write((byte)0); // ColorMapDepth (not in use) binaryWriter.Write((short)0); // Origin X binaryWriter.Write((short)0); // Origin Y binaryWriter.Write((short)_texture2D.width); // Width binaryWriter.Write((short)_texture2D.height); // Height binaryWriter.Write((byte)(iBytesPerPixel * 8)); // Bits Per Pixel binaryWriter.Write((byte)0); // ImageDescriptor (not in use) Color32[] arPixels = _texture2D.GetPixels32(); if (_compression == Compression.None) { // Write all Pixels one after the other for (int iPixel = 0; iPixel < arPixels.Length; iPixel++) { Color32 c32Pixel = arPixels[iPixel]; binaryWriter.Write(c32Pixel.b); binaryWriter.Write(c32Pixel.g); binaryWriter.Write(c32Pixel.r); if (iBytesPerPixel == iBytesPerPixelARGB32) { binaryWriter.Write(c32Pixel.a); } } } else { // Write RLE Encoded Pixels const int iMaxPacketLength = 128; int iPacketStart = 0; int iPacketEnd = 0; while (iPacketStart < arPixels.Length) { Color32 c32PreviousPixel = arPixels[iPacketStart]; // Get current Packet Type RLEPacketType packetType = EncodeToTGAExtension.PacketType(arPixels, iPacketStart); // Find Packet End int iReadEnd = Mathf.Min(iPacketStart + iMaxPacketLength, arPixels.Length); for (iPacketEnd = iPacketStart + 1; iPacketEnd < iReadEnd; ++iPacketEnd) { bool bPreviousEqualsCurrent = EncodeToTGAExtension.Equals(arPixels[iPacketEnd - 1], arPixels[iPacketEnd]); // Packet End if change in Packet Type or if max Packet-Size reached if (packetType == RLEPacketType.RAW && bPreviousEqualsCurrent || packetType == RLEPacketType.RLE && !bPreviousEqualsCurrent) { break; } } // Write Packet int iPacketLength = iPacketEnd - iPacketStart; switch (packetType) { case RLEPacketType.RLE: // Add RLE-Bit to PacketLength binaryWriter.Write((byte)((iPacketLength - 1) | (1 << 7))); binaryWriter.Write(c32PreviousPixel.b); binaryWriter.Write(c32PreviousPixel.g); binaryWriter.Write(c32PreviousPixel.r); if (iBytesPerPixel == iBytesPerPixelARGB32) { binaryWriter.Write(c32PreviousPixel.a); } break; case RLEPacketType.RAW: binaryWriter.Write((byte)(iPacketLength - 1)); for (int iPacketPosition = iPacketStart; iPacketPosition < iPacketEnd; ++iPacketPosition) { Color32 c32Pixel = arPixels[iPacketPosition]; binaryWriter.Write(c32Pixel.b); binaryWriter.Write(c32Pixel.g); binaryWriter.Write(c32Pixel.r); if (iBytesPerPixel == iBytesPerPixelARGB32) { binaryWriter.Write(c32Pixel.a); } } break; } iPacketStart = iPacketEnd; } } binaryWriter.Write(0); // Offset of meta-information (not in use) binaryWriter.Write(0); // Offset of Developer-Area (not in use) binaryWriter.Write(c_arV2Signature); // ImageDescriptor (not in use) } return(memoryStream.ToArray()); } }
static void printLightMapIndex() { TextureImporterFormat format = TextureImporterFormat.ASTC_4x4; string root = AssetDatabase.GetAssetPath(Lightmapping.lightingDataAsset); root = root.Substring(0, root.LastIndexOf('/')); string end1 = "_comp_shadowmask.png"; string end2 = "_comp_light.exr"; var s = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); string end3 = "_LightSM.tga"; List <string> found_paths = new List <string>(); int width = 512; int height = 512; string [] paths = System.IO.Directory.GetFiles(root); Dictionary <int, string> lightMapTemp = new Dictionary <int, string>(); int maxIndex = -1; for (int i = 0; i < paths.Length; i++) { string path = paths[i]; if (path.EndsWith(end1)) { string heater = path.Substring(0, path.Length - end1.Length); int index = int.Parse(heater.Substring(heater.LastIndexOf('-') + 1)); maxIndex = Mathf.Max(index, maxIndex); string path2 = heater + end2; if (System.IO.File.Exists(path2)) { Texture2D t = AssetDatabase.LoadAssetAtPath <Texture2D>(path); Texture2D t2 = AssetDatabase.LoadAssetAtPath <Texture2D>(path2); found_paths.Add(path); found_paths.Add(path2); width = t.width; height = t.height; RenderTexture rt = RenderTexture.GetTemporary(t.width, t.height, 0); Material mat = new Material(Shader.Find("Hidden/HdrToHalfColor")); mat.SetTexture("_MainTex", t2); mat.SetTexture("_MainTex2", t); Graphics.Blit(t2, rt, mat); RenderTexture.active = rt; Texture2D png = new Texture2D(rt.width, rt.height, TextureFormat.RGBA32, false); png.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); byte[] bytes = EncodeToTGAExtension.EncodeToTGA(png, 4); string path3 = heater + end3; System.IO.File.WriteAllBytes(path3, bytes); AssetDatabase.ImportAsset(path3); TextureFormatHelper.ModifyTextureFormat(path3, "iPhone", format); TextureFormatHelper.ModifyTextureFormat(path3, "Android", format); TextureImporter texImporter = TextureImporter.GetAtPath(path3) as TextureImporter; texImporter.isReadable = true; GameObject.DestroyImmediate(png, true); RenderTexture.ReleaseTemporary(rt); GameObject.DestroyImmediate(t, false); GameObject.DestroyImmediate(t2, false);; lightMapTemp[index] = path3; } } } Texture2DArray texture2DArray = new Texture2DArray(width, height, maxIndex + 1, TextureFormat.ASTC_4x4, true); foreach (var kp in lightMapTemp) { AssetDatabase.ImportAsset(kp.Value); Texture2D t = AssetDatabase.LoadAssetAtPath <Texture2D>(kp.Value); Graphics.CopyTexture(t, 0, texture2DArray, kp.Key); texture2DArray.Apply(); GameObject.DestroyImmediate(t, true); AssetDatabase.DeleteAsset(kp.Value); //System.IO.File.Delete(kp.Value) ; } texture2DArray.wrapMode = TextureWrapMode.Clamp; texture2DArray.filterMode = FilterMode.Bilinear; string arrayPath = root + "\\" + s.name + "_LMSM.asset"; AssetDatabase.CreateAsset(texture2DArray, arrayPath); AssetDatabase.ImportAsset(arrayPath); ShadowMarkTex2dAry sma = GameObject.FindObjectOfType <ShadowMarkTex2dAry>(); if (null == sma) { GameObject g = null; if (null != Camera.main) { g = Camera.main.gameObject; } else { g = new GameObject("Camera"); g.AddComponent <Camera>(); } sma = g.AddComponent <ShadowMarkTex2dAry>(); } sma.shadowMark = AssetDatabase.LoadAssetAtPath <Texture2DArray>(arrayPath); AddCmpToRender(); //Texture2D empty = new Texture2D(1, 1,TextureFormat.RGBA32,false); //empty.SetPixel(0, 0, Color.white); for (int i = 0; i < found_paths.Count; i++) { var str = found_paths[i]; //System.IO.File.WriteAllBytes(str,empty.EncodeToPNG()); //AssetDatabase.ImportAsset(str); AssetDatabase.DeleteAsset(str); } EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene()); //GameObject.DestroyImmediate(empty, true); }