Unity - 如何创建圆形渐变?
Unity - How to create circular gradient?
我需要一点帮助,我正在尝试使用 Unity 创建一个岛生成器。
但是我不知道如何使圆形脱落 map.But 相反,我设法创建了一个更像是盒形岛的岛。
这就是我正在做的事情:
- 我正在使用 Perlin 噪声生成高度图
- 我将生成 FallOff 贴图并从 Perlin 噪声中减去它
- 岛已生成,但不是圆形
岛状 hasbox 形状
我想创建这个
这是我的 Perlin 噪声函数
public float[,] GenerateNoise(int mapSize,int octaves, string seed, float noiseScale, float persistence, float lacunarity, Vector2 offset)
{
if (noiseScale <= 0)
{
noiseScale = 0.0001f;
}
float halfWidth = mapSize / 2f;
float halfHeight = mapSize / 2f;
float[,] noiseMap = new float[mapSize + 1, mapSize + 1];
System.Random rand = new System.Random(seed.GetHashCode());
//Octaves offset
Vector2[] octavesOffset = new Vector2[octaves];
for (int i = 0; i < octaves; i++)
{
float offset_X = rand.Next(-100000, 100000) + offset.x;
float offset_Y = rand.Next(-100000, 100000) + offset.y;
octavesOffset[i] = new Vector2(offset_X / mapSize, offset_Y / mapSize);
}
for (int x = 0; x < mapSize; x++)
{
for (int y = 0; y < mapSize; y++)
{
float amplitude = 1;
float frequency = 1;
float noiseHeight = 0;
float superpositionCompensation = 0;
for (int i = 0; i < octaves; i++)
{
float sampleX = (x - halfWidth) / noiseScale * frequency + octavesOffset[i].x;
float sampleY = (y - halfHeight) / noiseScale * frequency + octavesOffset[i].y;
float perlinValue = Mathf.PerlinNoise(sampleX, sampleY);
noiseHeight += perlinValue * amplitude;
noiseHeight -= superpositionCompensation;
amplitude *= persistence;
frequency *= lacunarity;
superpositionCompensation = amplitude / 2;
}
noiseMap[x, y] = Mathf.Clamp01(noiseHeight);
}
}
return noiseMap;
}
这是我的 FallOff 贴图函数
public float[,] GenerateFallOffMap(int mapSize)
{
float[,] fallOffMap = new float[mapSize , mapSize];
for (int x = 0; x < mapSize; x++)
{
for (int y = 0; y < mapSize; y++)
{
int index = x * mapSize + y;
float fallOff_A = x / (float)mapSize * 2 - 1;
float fallOff_B = y / (float)mapSize * 2 - 1;
float value = Mathf.Max(Mathf.Abs(fallOff_A), Mathf.Abs(fallOff_B));
fallOffMap[x,y] = Evaluate(value);
}
}
return fallOffMap;
}
static float Evaluate(float value)
{
float a = 3;
float b = 2.2f;
return Mathf.Pow(value, a) / (Mathf.Pow(value, a) + Mathf.Pow(b - b * value, a));
}
以距网格中心的距离为参数计算衰减值
/// value - The calculated value to process
/// radius - The distance from center to calculate falloff distance
/// x - The x-coordinate of the value position
/// y - The y-coordinate of the value position
/// cx - The x-coordinate of the center position
/// cy - The y-coordinate of the center position
public float RadialFallOff(float value, float radius, int x, int y, float cx, float cy)
{
float dx = cx - x;
float dy = cy - y;
float distSqr = dx * dx + dy * dy;
float radSqr = radius * radius;
if (distSqr > radSqr) return 0f;
return value;
}
这将导致 radius
处的硬中断。如果您想沿边缘进行更柔和的过渡,可以使用 innerRadius
和 outerRadius
来产生羽化效果:
/// value - The calculated value to process
/// innerRadius - The distance from center to start feathering
/// outerRadius - The distance from center to fully fall off
/// x - The x-coordinate of the value position
/// y - The y-coordinate of the value position
/// cx - The x-coordinate of the center position
/// cy - The y-coordinate of the center position
public float FeatheredRadialFallOff(float value, float innerRadius, float outerRadius, int x, int y, float cx, float cy)
{
float dx = cx - x;
float dy = cy - y;
float distSqr = dx * dx + dy * dy;
float iRadSqr = innerRadius * innerRadius;
float oRadSqr = outerRadius * outerRadius;
if (distSqr >= oRadSqr) return 0f;
if (distSqr <= iRadSqr) return value;
float dist = Mathf.Sqr(distSqr);
float t = Mathf.InverseLerp(innerRadius, outerRadius, dist);
// Use t with whatever easing you want here, or leave it as is for linear easing
return value * t;
}
你可以这样使用它:
float value = Mathf.Max(Mathf.Abs(fallOff_A), Mathf.Abs(fallOff_B));
value = Evaluate(value)
fallOffMap[x,y] = RadialFalloff(value, someRadius, x, y, mapSize / 2f, mapSize / 2f);
// or
fallOffMap[x,y] = FeatheredRadialFalloff(value, someInnerRadius, someOuterRadius, x, y, mapSize / 2f, mapSize / 2f);
我需要一点帮助,我正在尝试使用 Unity 创建一个岛生成器。
但是我不知道如何使圆形脱落 map.But 相反,我设法创建了一个更像是盒形岛的岛。
这就是我正在做的事情:
- 我正在使用 Perlin 噪声生成高度图
- 我将生成 FallOff 贴图并从 Perlin 噪声中减去它
- 岛已生成,但不是圆形 岛状 hasbox 形状
我想创建这个
这是我的 Perlin 噪声函数
public float[,] GenerateNoise(int mapSize,int octaves, string seed, float noiseScale, float persistence, float lacunarity, Vector2 offset)
{
if (noiseScale <= 0)
{
noiseScale = 0.0001f;
}
float halfWidth = mapSize / 2f;
float halfHeight = mapSize / 2f;
float[,] noiseMap = new float[mapSize + 1, mapSize + 1];
System.Random rand = new System.Random(seed.GetHashCode());
//Octaves offset
Vector2[] octavesOffset = new Vector2[octaves];
for (int i = 0; i < octaves; i++)
{
float offset_X = rand.Next(-100000, 100000) + offset.x;
float offset_Y = rand.Next(-100000, 100000) + offset.y;
octavesOffset[i] = new Vector2(offset_X / mapSize, offset_Y / mapSize);
}
for (int x = 0; x < mapSize; x++)
{
for (int y = 0; y < mapSize; y++)
{
float amplitude = 1;
float frequency = 1;
float noiseHeight = 0;
float superpositionCompensation = 0;
for (int i = 0; i < octaves; i++)
{
float sampleX = (x - halfWidth) / noiseScale * frequency + octavesOffset[i].x;
float sampleY = (y - halfHeight) / noiseScale * frequency + octavesOffset[i].y;
float perlinValue = Mathf.PerlinNoise(sampleX, sampleY);
noiseHeight += perlinValue * amplitude;
noiseHeight -= superpositionCompensation;
amplitude *= persistence;
frequency *= lacunarity;
superpositionCompensation = amplitude / 2;
}
noiseMap[x, y] = Mathf.Clamp01(noiseHeight);
}
}
return noiseMap;
}
这是我的 FallOff 贴图函数
public float[,] GenerateFallOffMap(int mapSize)
{
float[,] fallOffMap = new float[mapSize , mapSize];
for (int x = 0; x < mapSize; x++)
{
for (int y = 0; y < mapSize; y++)
{
int index = x * mapSize + y;
float fallOff_A = x / (float)mapSize * 2 - 1;
float fallOff_B = y / (float)mapSize * 2 - 1;
float value = Mathf.Max(Mathf.Abs(fallOff_A), Mathf.Abs(fallOff_B));
fallOffMap[x,y] = Evaluate(value);
}
}
return fallOffMap;
}
static float Evaluate(float value)
{
float a = 3;
float b = 2.2f;
return Mathf.Pow(value, a) / (Mathf.Pow(value, a) + Mathf.Pow(b - b * value, a));
}
以距网格中心的距离为参数计算衰减值
/// value - The calculated value to process
/// radius - The distance from center to calculate falloff distance
/// x - The x-coordinate of the value position
/// y - The y-coordinate of the value position
/// cx - The x-coordinate of the center position
/// cy - The y-coordinate of the center position
public float RadialFallOff(float value, float radius, int x, int y, float cx, float cy)
{
float dx = cx - x;
float dy = cy - y;
float distSqr = dx * dx + dy * dy;
float radSqr = radius * radius;
if (distSqr > radSqr) return 0f;
return value;
}
这将导致 radius
处的硬中断。如果您想沿边缘进行更柔和的过渡,可以使用 innerRadius
和 outerRadius
来产生羽化效果:
/// value - The calculated value to process
/// innerRadius - The distance from center to start feathering
/// outerRadius - The distance from center to fully fall off
/// x - The x-coordinate of the value position
/// y - The y-coordinate of the value position
/// cx - The x-coordinate of the center position
/// cy - The y-coordinate of the center position
public float FeatheredRadialFallOff(float value, float innerRadius, float outerRadius, int x, int y, float cx, float cy)
{
float dx = cx - x;
float dy = cy - y;
float distSqr = dx * dx + dy * dy;
float iRadSqr = innerRadius * innerRadius;
float oRadSqr = outerRadius * outerRadius;
if (distSqr >= oRadSqr) return 0f;
if (distSqr <= iRadSqr) return value;
float dist = Mathf.Sqr(distSqr);
float t = Mathf.InverseLerp(innerRadius, outerRadius, dist);
// Use t with whatever easing you want here, or leave it as is for linear easing
return value * t;
}
你可以这样使用它:
float value = Mathf.Max(Mathf.Abs(fallOff_A), Mathf.Abs(fallOff_B));
value = Evaluate(value)
fallOffMap[x,y] = RadialFalloff(value, someRadius, x, y, mapSize / 2f, mapSize / 2f);
// or
fallOffMap[x,y] = FeatheredRadialFalloff(value, someInnerRadius, someOuterRadius, x, y, mapSize / 2f, mapSize / 2f);