Files
KopMap/Assets/NatureManufacture Assets/WorldStreamer/Scritps/Terrain/Editor/TerrainManagerUtils.cs
2025-09-02 18:55:19 +08:00

179 lines
5.9 KiB
C#

// /**
// * Created by Pawel Homenko on 11/2023
// */
using UnityEngine;
namespace WorldStreamer2
{
public static class TerrainManagerUtils
{
public static Texture2D HeightMapToNormal(Texture2D sourceImage, float strength = 1f)
{
//Mathf.Clamp(strength, 0.0f, 10.0f);
int w = sourceImage.width;
int h = sourceImage.height;
Texture2D normal = new Texture2D(w, h);
Color[] currentColors = null;
Color[] lColors = null;
Color[] rColors = null;
float sampleL;
float sampleR;
float sampleU;
float sampleD;
float xVector, yVector;
for (int x = 0; x < w; x++)
{
if (currentColors != null) lColors = currentColors;
currentColors = rColors ?? sourceImage.GetPixels(x, 0, 1, h);
lColors ??= currentColors;
rColors = x < w - 1 ? sourceImage.GetPixels(x + 1, 0, 1, h) : currentColors;
for (int y = 0; y < currentColors.Length; y++)
{
sampleL = lColors[y].r * strength;
sampleR = rColors[y].r * strength;
if (y < h - 1) sampleU = currentColors[y + 1].r * strength;
else sampleU = currentColors[y].r * strength;
if (y > 0) sampleD = currentColors[y - 1].r * strength;
else sampleD = currentColors[y].r * strength;
xVector = Mathf.Clamp01((((sampleL - sampleR) + 1) * 0.5f));
yVector = Mathf.Clamp01((((sampleD - sampleU) + 1) * 0.5f));
Color col = new Color(xVector, yVector, 1f, 1f);
normal.SetPixel(x, y, col);
}
}
normal.Apply();
return normal;
}
public static Texture2D GetNormalMap(float[,] rawHeights, float str = 2.0f)
{
int width = rawHeights.GetLength(0);
int height = rawHeights.GetLength(0);
Texture2D normal = new Texture2D(width, height, TextureFormat.ARGB32, true);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
normal.SetPixel(x, y, new Color(rawHeights[y, x], rawHeights[y, x], rawHeights[y, x]));
}
}
normal.Apply();
normal = HeightMapToNormal(normal, str / 20f);
normal = Resize(normal, Mathf.ClosestPowerOfTwo(normal.width), Mathf.ClosestPowerOfTwo(normal.width));
normal.Apply(true);
return normal;
}
public static void CalculateTerrainMaxMinHeight(Terrain terrain, float maxHeightTerrain, float minHeightTerrain, TerrainManager terrainManager)
{
int heightMapResolution = terrain.terrainData.heightmapResolution;
float[,] rawHeights = terrain.terrainData.GetHeights(0, 0, heightMapResolution, heightMapResolution);
float height;
float min = float.MaxValue;
float max = float.MinValue;
for (int y = 0; y < heightMapResolution; y++)
{
for (int x = 0; x < heightMapResolution; x++)
{
rawHeights[y, x] = Mathf.Clamp01(rawHeights[y, x]);
height = rawHeights[y, x];
if (height > max)
max = height;
if (height < min)
min = height;
}
}
if (max > terrainManager.MaxHeightTerrain) terrainManager.MaxHeightTerrain = max;
if (min < terrainManager.MinHeightTerrain) terrainManager.MinHeightTerrain = min;
}
public static Texture2D Resize(Texture2D texture2D, int targetX, int targetY)
{
RenderTexture rt = new RenderTexture(targetX, targetY, 24);
RenderTexture.active = rt;
Graphics.Blit(texture2D, rt);
Texture2D result = new Texture2D(targetX, targetY);
result.ReadPixels(new Rect(0, 0, targetX, targetY), 0, 0);
result.Apply();
return result;
}
public static Color Overlay(Color baseCol, Color blendCol)
{
Color outColor = new Color
{
a = 1
};
if (baseCol is {r: < 0.5f, g: < 0.5f, b: < 0.5f})
{
outColor.r = 2 * baseCol.r * blendCol.r;
outColor.g = 2 * baseCol.g * blendCol.g;
outColor.b = 2 * baseCol.b * blendCol.b;
}
else
{
outColor.r = 1 - 2 * (1 - baseCol.r) * (1 - blendCol.r);
outColor.g = 1 - 2 * (1 - baseCol.g) * (1 - blendCol.g);
outColor.b = 1 - 2 * (1 - baseCol.b) * (1 - blendCol.b);
}
return outColor;
}
public static Color LinearLightAddSub(Color baseCol, Color blendCol)
{
Color outColor = blendCol;
outColor.a = 1;
if (blendCol.r > 0.5f)
{
outColor.r = baseCol.r + (blendCol.r * 2 - 1) * 0.5f;
}
else
{
outColor.r = baseCol.r - (1 - blendCol.r * 2) * 0.5f;
}
if (blendCol.g > 0.5f)
{
outColor.g = baseCol.g + (blendCol.g * 2 - 1) * 0.5f;
}
else
{
outColor.g = baseCol.g - (1 - blendCol.g * 2) * 0.5f;
}
outColor.b = blendCol.b;
if (blendCol.b > 0.5f)
{
outColor.b = baseCol.b + (blendCol.b * 2 - 1) * 0.5f;
}
else
{
outColor.b = baseCol.b - (1 - blendCol.b * 2) * 0.5f;
}
return outColor;
}
}
}