179 lines
5.9 KiB
C#
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;
|
|
}
|
|
}
|
|
} |