Как добавить offset к генерации шуму Перлина

Speed Tree : Terrain & Trees.

Как добавить offset к генерации шуму Перлина

Сообщение scorp2007 19 май 2018, 03:31

Здравствуйте, надеюсь в верный раздел тему засунул, так как шум перлина все-таки в большинстве случаев используется для генерации ландшафта. У меня имеется некоторый код, который взят из исходника TerrainToolkit, а именно код генерации шума перлина, я его немного модернизировал, но единственная вещь которую не могу реализовать там - прикрутить контролирумый сдвиг по х-у, то есть offset, так как не до конца понимаю данный код. :-? Нужно это на случай если допустим terrain-ов будет больше 1. До этого был другой метод генерации шума перлина, где реализованы оффсеты по х-у, но по некоторым причинам именно нынешняя реализация из тулкита показывает наиболее лучший результат. Прошу помочь кто разбирается ^:)^ , вот код:

Синтаксис:
Используется csharp
public static float[,] generatePerlin(int mapWidth, int mapHeight, int seed, float scale, int perlinOctaves, float perlinAmplitude, int perlinFrequency, Vector2 offset)
    {

        int Tw = mapWidth;
        int Th = mapHeight;
        float[,] heightMap = new float[mapWidth, mapHeight];

        // Zero...
        for (int My = 0; My < Th; My++)
        {
            for (int Mx = 0; Mx < Tw; Mx++)
            {
                heightMap[Mx, My] = 0.0f;
            }
        }
        PerlinNoise2D[] noiseFunctions = new PerlinNoise2D[perlinOctaves];

        int freq = perlinFrequency;
        float amp = 1.0f;
        int i;
        for (i = 0; i < perlinOctaves; i++)
        {
            noiseFunctions[i] = new PerlinNoise2D(freq, amp, seed, offset);
            freq *= 2;
            amp /= 2;
        }

        for (i = 0; i < perlinOctaves; i++)
        {
            double xStep = ((float)Tw / (float)noiseFunctions[i].Frequency * scale);
            double yStep = ((float)Th / (float)noiseFunctions[i].Frequency * scale);
            for (int Px = 0; Px < Tw; Px++)
            {
                for (int Py = 0; Py < Th; Py++)
                {
                    int Pa = (int)(Px / xStep);
                    int Pb = Pa + 1;
                    int Pc = (int)(Py / yStep);
                    int Pd = Pc + 1;
                    double interpValue = noiseFunctions[i].getInterpolatedPoint(Pa, Pb, Pc, Pd, (Px / xStep) - Pa, (Py / yStep) - Pc);
                    heightMap[Px, Py] += (float)(interpValue * noiseFunctions[i].Amplitude);
                }
            }
            // Show progress...
            float percentComplete = (i + 1) / perlinOctaves;
            //generatorProgressDelegate("Perlin Generator", "Generating height map. Please wait.", percentComplete);
        }
        //GeneratorProgressDelegate normaliseProgressDelegate = new GeneratorProgressDelegate(dummyGeneratorProgress);
        normaliseMin = 0.0f;
        normaliseMax = 1.0f;
        normaliseBlend = 1.0f;
        heightMap = normalise(heightMap, new Vector2(mapWidth, mapHeight));

        for (int Px = 0; Px < Tw; Px++)
        {
            for (int Py = 0; Py < Th; Py++)
            {
                heightMap[Px, Py] = heightMap[Px, Py] * perlinAmplitude;
            }
        }
        for (i = 0; i < perlinOctaves; i++)
        {
            noiseFunctions[i] = null;
        }
        noiseFunctions = null;
        return heightMap;
    }

    public class PerlinNoise2D
    {
        private double[,] noiseValues;
        private float amplitude = 1.0f;
        private int frequency = 1;

        public PerlinNoise2D(int freq, float _amp, int seed, Vector2 offset)
        {
            //System.Random rand = new System.Random(System.Environment.TickCount);
            System.Random rand = new System.Random(seed);

            noiseValues = new double[freq, freq];
            amplitude = _amp;
            frequency = freq;


            for (int i = 0; i < freq; i++)
            {
                for (int j = 0; j < freq; j++)
                {
                    // noiseValues[i, j] = rand.NextDouble();
                    noiseValues[i, j] = rand.NextDouble();
                }
            }
        }

        public double getInterpolatedPoint(int _xa, int _xb, int _ya, int _yb, double Px, double Py)
        {
            double i1 = interpolate(noiseValues[_xa % Frequency, _ya % frequency], noiseValues[_xb % Frequency, _ya % frequency], Px);
            double i2 = interpolate(noiseValues[_xa % Frequency, _yb % frequency], noiseValues[_xb % Frequency, _yb % frequency], Px);
            return interpolate(i1, i2, Py);
        }

        private double interpolate(double Pa, double Pb, double Px)
        {
            double ft = Px * Mathf.PI;
            double f = (1 - Mathf.Cos((float)ft)) * 0.5;
            return Pa * (1 - f) + Pb * f;
        }

        public float Amplitude
        {
            get
            {
                return amplitude;
            }
        }

        public int Frequency
        {
            get
            {
                return frequency;
            }
        }
    }

    public static float[,] normalise(float[,] heightMap, Vector2 arraySize)
    {
        int Tx = (int)arraySize.x;
        int Ty = (int)arraySize.y;
        int Mx;
        int My;
        float highestPoint = 0.0f;
        float lowestPoint = 1.0f;
        //generatorProgressDelegate("Normalise Filter", "Normalising height map. Please wait.", 0.0f);
        // Find highest and lowest points...
        for (My = 0; My < Ty; My++)
        {
            for (Mx = 0; Mx < Tx; Mx++)
            {
                float heightAtPoint = heightMap[Mx, My];
                if (heightAtPoint < lowestPoint)
                {
                    lowestPoint = heightAtPoint;
                }
                else if (heightAtPoint > highestPoint)
                {
                    highestPoint = heightAtPoint;
                }
            }
        }
        //generatorProgressDelegate("Normalise Filter", "Normalising height map. Please wait.", 0.5f);
        // Normalise...
        float heightRange = highestPoint - lowestPoint;
        float normalisedHeightRange = normaliseMax - normaliseMin;
        for (My = 0; My < Ty; My++)
        {
            for (Mx = 0; Mx < Tx; Mx++)
            {
                float normalisedHeight = ((heightMap[Mx, My] - lowestPoint) / heightRange) * normalisedHeightRange;
                heightMap[Mx, My] = normaliseMin + normalisedHeight;
            }
        }
        //generatorProgressDelegate("Normalise Filter", "Normalising height map. Please wait.", 1.0f);
        return heightMap;
    }
 
scorp2007
UNIт
 
Сообщения: 109
Зарегистрирован: 17 авг 2014, 13:59

Вернуться в Земля и деревья.

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4