【问题标题】:Implementing Scape's "Procedural Basics" Perlin Noise in Unity在 Unity 中实现 Scape 的“程序基础”Perlin Noise
【发布时间】:2013-01-26 04:46:39
【问题描述】:

尝试使用 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;
}

【问题讨论】:

    标签: c# unity3d noise


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-21
      • 2013-01-10
      • 1970-01-01
      相关资源
      最近更新 更多