简体   繁体   English

在Unity中实施Scape的“程序基础” Perlin Noise

[英]Implementing Scape's “Procedural Basics” Perlin Noise in Unity

Trying to implement the noise functions from the following article in C# using Unity: http://www.decarpentier.nl/scape-procedural-basics 尝试使用Unity在C#中的以下文章中实现噪声函数: http : //www.decarpentier.nl/scape-procedural-basics

And it's mostly working, but something must be wrong with the blending across the x access, as the terrain is generated in bands.. 而且它基本上可以正常工作,但是跨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;
}

The solution was to flip the y axis when accessing the Texture2D pixel values. 解决方案是在访问Texture2D像素值时翻转y轴。 By going 255 - y instead. 改为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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM