GetHeightNormalMapEditor.cs 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System;
  4. using System.Collections;
  5. using System.Reflection;
  6. using System.IO;
  7. namespace LuxURPEssentials
  8. {
  9. [CustomEditor (typeof(GetTerrainHeightNormalMap))]
  10. public class GetTerrainHeightNormalMapEditor : Editor {
  11. private SerializedObject GetTerrainHeightNormalMap;
  12. private SerializedProperty savePathTerrainHeightNormalMap;
  13. public override void OnInspectorGUI () {
  14. GetTerrainHeightNormalMap = new SerializedObject(target);
  15. GetTerrainHeightNormalMap script = (GetTerrainHeightNormalMap)target;
  16. script.GetTerData();
  17. savePathTerrainHeightNormalMap = GetTerrainHeightNormalMap.FindProperty("savePathTerrainHeightNormalMap");
  18. if (GUILayout.Button("Get Height Normal Map")) {
  19. CreateTerrainHeightNormal();
  20. }
  21. GetTerrainHeightNormalMap.ApplyModifiedProperties();
  22. }
  23. void CreateTerrainHeightNormal() {
  24. GetTerrainHeightNormalMap script = (GetTerrainHeightNormalMap)target;
  25. TerrainData targetTerrainData = script.targetTerrainData;
  26. Texture2D tempTex = new Texture2D(targetTerrainData.heightmapResolution, targetTerrainData.heightmapResolution, TextureFormat.RGBA32, false, true);
  27. Color32[] cols = new Color32[tempTex.width * tempTex.height];
  28. for( int x = 0; x < tempTex.width; x++ ) {
  29. for( int y = 0; y < tempTex.height; y++ ) {
  30. // Bring x and y into the 0-1 Range used by GetInterpolatedHeight
  31. float sample_xpos = 1.0f * x / (tempTex.width - 1);
  32. float sample_ypos = 1.0f * y / (tempTex.height - 1);
  33. // Get and encode height
  34. float height = targetTerrainData.GetInterpolatedHeight(sample_xpos, sample_ypos) / targetTerrainData.size.y;
  35. // Encoding/decoding [0..1) floats into 8 bit/channel RG. Note that 1.0 will not be encoded properly.
  36. int height0 = Mathf.FloorToInt(height * 255.0f);
  37. int height1 = Mathf.FloorToInt((height * 255.0f - height0) * 255.0f);
  38. // Get normal
  39. Vector3 normal = targetTerrainData.GetInterpolatedNormal(sample_xpos, sample_ypos);
  40. float normal_x = (normal.x * 0.5f + 0.5f) * 255.0f;
  41. float normal_z = (normal.z * 0.5f + 0.5f) * 255.0f;
  42. cols[x + y * tempTex.width] = new Color32( (byte)height0, (byte)height1, (byte)normal_x, (byte)normal_z );
  43. }
  44. }
  45. tempTex.SetPixels32(cols);
  46. tempTex.Apply(false);
  47. string directory;
  48. string file = "Terrain Height Normal Map";
  49. if (savePathTerrainHeightNormalMap.stringValue =="") {
  50. directory = Application.dataPath;
  51. }
  52. else {
  53. directory = Path.GetDirectoryName(savePathTerrainHeightNormalMap.stringValue);
  54. file = Path.GetFileNameWithoutExtension(savePathTerrainHeightNormalMap.stringValue);
  55. }
  56. string filePath = EditorUtility.SaveFilePanel("Save Terrain Height Normal Map", directory, file, "png");
  57. if (!string.IsNullOrEmpty(filePath)) {
  58. filePath = FileUtil.GetProjectRelativePath(filePath);
  59. savePathTerrainHeightNormalMap.stringValue = filePath;
  60. byte[] bytes = tempTex.EncodeToPNG();
  61. System.IO.File.WriteAllBytes(filePath, bytes);
  62. AssetDatabase.Refresh();
  63. TextureImporter ti = AssetImporter.GetAtPath(filePath) as TextureImporter;
  64. ti.textureCompression = TextureImporterCompression.Uncompressed;
  65. ti.sRGBTexture = false;
  66. ti.wrapMode = TextureWrapMode.Clamp;
  67. ti.mipmapEnabled = false;
  68. ti.npotScale = TextureImporterNPOTScale.None;
  69. AssetDatabase.ImportAsset(filePath, ImportAssetOptions.ForceUpdate);
  70. AssetDatabase.Refresh();
  71. }
  72. DestroyImmediate(tempTex);
  73. }
  74. }
  75. }