2013-02-11 101 views
0

试图使用Unity来实现从C#下面的文章中的噪声功能:http://www.decarpentier.nl/scape-procedural-basics实施薹的“程序基础知识”柏林噪声在Unity

而且这主要是工作,但一定出事了与整个X访问混合作为地形在频带生成..

Terrain generated with current noise function

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

的解决方案是在访问的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; 
}