Несоответствие страниц ландшафта Perlin :неуловимая ошибка

Я разрабатывал игру на движке Unity Game Engine, в которой, я надеюсь, можно будет использовать выгружаемый ландшафт для бесконечного мира (, распространенной в настоящее время темы ). Мой генератор ландшафта использует исключительно перлиновый шум. Но в настоящее время разработка серьезно замедлена из-за ошибки :Края страницы не совпадают, даже близко. Проблема где-то в коде, где я генерирую ландшафт, или, возможно, в другом фрагменте кода, который запускается каждый раз, когда я заканчиваю генерировать страницу. Но проблема точно не в вызовах функций юнити, так что вы можете помочь мне, даже если вы не знакомы с юнити.

Возможные причины... 1 )Шум Перлина выбран для неправильного расположения каждой страницы, ошибка математики. 2 )Генератор случайных чисел повторно заполняется между созданием страниц. 3 )Шум Перлина повторно заполняется между созданием страниц. 4 )? Я не знаю.

ПРИМЕЧАНИЕ. :Я практически исключил числа 2 и 3, глядя на весь мой код. Я запускаю генераторы только один раз каждый, и Unity не может просто так повторно заполнять Random между запусками генератора.

На самом деле, если вы можете описать способ отладки, который облегчит эту задачу, пожалуйста, сообщите. Это помогло бы мне гораздо больше в долгосрочной перспективе.

Вот код, который я запускаю один раз для каждой страницы, с полными комментариями, поэтому вам не нужно знать Unity3D...

 /* x and y are the indices of the tile being loaded. The game maintains a
    square of pages loaded, where the number of pages per side is equal to
    loadSquares (see below). x and y are the indices of the page to generate
    within that square. */
    public void generate(int x, int y)
    {
         /* pagePos represents the world x and y coordinates of the bottom left
            corner of the page being generated. This is given by...
              new Vector2((-(float)loadSquares / 2.0f + x + xCoord) * tileSize, 
                          (-(float)loadSquares / 2.0f + y + zCoord) * tileSize);
            This is because the origin tile's center is at 0, 0. xCoord represents
            the tile that the target object is on, which is what the loaded square
            is centered around. tileSize is the length of each side of each tile.
         */
        Vector2 pagePos = getPagePos(x, y);
        //Here I get the number of samples x and y in the heightmap.
        int xlim = td[x,y].heightmapWidth;
        int ylim = td[x,y].heightmapHeight;
            //The actual data
        float[,] array = new float[xlim, ylim];
            //These will represent the minimum and maximum values in this tile.
            //I will need them to convert the data to something unity can use.
        float min = 0.0f;
        float max = 0.0f;
        for(int cx = 0; cx < xlim; cx++)
        {
            for(int cy = 0; cy < ylim; cy++)
            {
                //Here I actually sample the perlin function.
                //Right now it doesn't look like terrain (intentionally, testing).
                array[cx,cy] = sample(
                    new Vector3((float)cx / (float)(xlim - 1) * tileSize + pagePos.x, 
                                (float)cy / (float)(ylim - 1) * tileSize + pagePos.y, 
                    122.79f));
                //On the first iteration, set min and max
                if(cx == 0 && cy == 0)
                {
                    min = array[cx,cy];
                    max = min;
                }
                else
                {
                    //update min and max
                    min = Mathf.Min(min, array[cx,cy]);
                    max = Mathf.Max(max, array[cx,cy]);
                }
            }
        }
        //Set up the Terrain object to receive the data
        float diff = max != min ? max - min : 10.0f;
        tr[x,y].position = new Vector3(pagePos.x, min, pagePos.y);
        td[x,y].size = new Vector3(tileSize, diff, tileSize);
        //Convert the data to fit in the Terrain object
     /* Unity's terrain only accepts values between 0.0f and 1.0f. Therefore,
        I shift the terrain vertically in the code above, and I
        squish the data to fit below.
     */
        for(int cx = 0; cx < xlim; cx++)
        {
            for(int cy = 0; cy < ylim; cy++)
            {
                array[cx,cy] -= min;
                array[cx,cy] /= diff;
            }
        }
        //Set the data in the Terrain object
        td[x,y].SetHeights(0, 0, array);
    }
}

Интересная и, вероятно, важная деталь :Плитки должным образом соединены с плитками, смежными с их углами по направлениям x/z. Сдвиг выборки происходит каждый раз, когда плитки не имеют одинаковой дельты от x -до -z. На изображении ниже правый тайл -расположен на +x и +z от другого тайла.Все плитки с этим отношением правильно связаны.

enter image description here

Вот файлы проекта, загруженные в zip. Скажи мне, если он не работает или что-то в этом роде...http://www.filefactory.com/file/4fc75xtd3yzl/n/FPS_zip

Чтобы увидеть ландшафт, нажмите Play после переключения на testScene, если он там не начинается. GameObject генерирует данные и объекты ландшафта (, у него есть скрипт RandomTerrain из scripts/General/, прикрепленный ). Вы можете изменить параметры шума перлина оттуда. Обратите внимание, что сейчас в генерации ландшафта активна только первая октава перлина, o _элеватор. Все другие общедоступные переменные октавы перлина не имеют значения для устранения этого сбоя.

7
задан 12 revs 14 July 2012 в 13:06
поделиться