尝试使用Unity实现C#中以下文章中的噪声函数:http://www.decarpentier.nl/scape-procedural-basics
它主要起作用,但是在x访问中混合时必定是错误的,因为地形是在乐队中生成的。
public void AddPerlinNoise(float scale=4.0f)
{
for (int i = 0; i < Width; i++){
for (int j = 0; j < Height; j++){
float l = PerlinNoise(new Vector2(((float)i/(float)Width)*scale,((float)j/(float)Height)*scale));
Heights[i, j] += l;
}
}
}
private float PerlinNoise(Vector2 p){
Color col;
// Calculate 2D integer coordinates i and fraction p.
Vector2 i = new Vector2(Mathf.Floor(p.x),Mathf.Floor(p.y));
Vector2 f = p - i;
// Get weights from the coordinate fraction
//float2 w = f * f * f * (f * (f * 6 - 15) + 10);
Vector2 w = new Vector2(f.x * f.x * f.x * (f.x * (f.x * 6.0f - 15.0f) + 10.0f),f.y * f.y * f.y * (f.y * (f.y * 6.0f - 15.0f) + 10.0f));
Vector4 w4 = new Vector4(1, w.x, w.y, w.x * w.y);
// Get the four randomly permutated indices from the noise lattice nearest to
// p and offset these numbers with the seed number.
col = permTex.GetPixel((int)i.x,(int)i.y);
Vector4 perm = new Vector4(col.r,col.g,col.b,col.a);
Vector4 one = new Vector4(1,1,1,1);
Vector4 two = new Vector4(2,2,2,2);
// Permutate the four offseted indices again and get the 2D gradient for each
// of the four permutated coordinates-seed pairs.
col = gradTex.GetPixel((int)(perm.x*255.0f),(int)(perm.y*255.0f));
Vector4 g1 = new Vector4(col.r,col.g,col.b,col.a);
g1.Scale(two);
g1 = g1 - one;
col = gradTex.GetPixel((int)(perm.z*255.0f),(int)(perm.w*255.0f));
Vector4 g2 = new Vector4(col.r,col.g,col.b,col.a);
g2.Scale(two);
g2 = g2 - one;
// Evaluate the four lattice gradients at p
float a = Vector2.Dot(new Vector2(g1.x,g1.y), f);
float b = Vector2.Dot(new Vector2(g2.x,g2.y), f + new Vector2(-1, 0));
float c = Vector2.Dot(new Vector2(g1.z,g1.w), f + new Vector2( 0, -1));
float d = Vector2.Dot(new Vector2(g2.z,g2.w), f + new Vector2(-1, -1));
// Bi-linearly blend between the gradients, using w4 as blend factors.
Vector4 grads = new Vector4(a, b - a, c - a, a - b - c + d);
float n = Vector4.Dot(grads, w4);
// Return the noise value, roughly normalized in the range [0, 1]
return (n * 1.5f) / 2 + 0.5f;
}
答案 0 :(得分:0)
解决方案是在访问Texture2D像素值时翻转y轴。通过255 - y代替。
private float PerlinNoise(Vector2 p){
Color col;
// Calculate 2D integer coordinates i and fraction p.
Vector2 i = new Vector2(Mathf.Floor(p.x),Mathf.Floor(p.y));
Vector2 f = p - i;
// Get weights from the coordinate fraction
//float2 w = f * f * f * (f * (f * 6 - 15) + 10);
Vector2 w = new Vector2(f.x * f.x * f.x * (f.x * (f.x * 6.0f - 15.0f) + 10.0f),f.y * f.y * f.y * (f.y * (f.y * 6.0f - 15.0f) + 10.0f));
Vector4 w4 = new Vector4(1, w.x, w.y, w.x * w.y);
// Get the four randomly permutated indices from the noise lattice nearest to
// p and offset these numbers with the seed number.
col = permTex.GetPixel((int)i.x,255 - (int)i.y);
Vector4 perm = new Vector4(col.r,col.g,col.b,col.a);
Vector4 one = new Vector4(1,1,1,1);
Vector4 two = new Vector4(2,2,2,2);
// Permutate the four offseted indices again and get the 2D gradient for each
// of the four permutated coordinates-seed pairs.
col = gradTex.GetPixel((int)(perm.x*255.0f),255 - (int)(perm.y*255.0f));
Vector4 g1 = new Vector4(col.r,col.g,col.b,col.a);
g1.Scale(two);
g1 = g1 - one;
col = gradTex.GetPixel((int)(perm.z*255.0f),255 - (int)(perm.w*255.0f));
Vector4 g2 = new Vector4(col.r,col.g,col.b,col.a);
g2.Scale(two);
g2 = g2 - one;
// Evaluate the four lattice gradients at p
float a = Vector2.Dot(new Vector2(g1.x,g1.y), f);
float b = Vector2.Dot(new Vector2(g2.x,g2.y), f + new Vector2(-1, 0));
float c = Vector2.Dot(new Vector2(g1.z,g1.w), f + new Vector2( 0, -1));
float d = Vector2.Dot(new Vector2(g2.z,g2.w), f + new Vector2(-1, -1));
// Bi-linearly blend between the gradients, using w4 as blend factors.
Vector4 grads = new Vector4(a, b - a, c - a, a - b - c + d);
float n = Vector4.Dot(grads, w4);
// Return the noise value, roughly normalized in the range [0, 1]
return (n * 1.5f) / 2 + 0.5f;
}