Согласованное случайное число в зависимости от положения (не на основе шума) - PullRequest
0 голосов
/ 20 сентября 2018

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

В контексте,У меня есть генератор карт, который использует перлин-шум для его построения, размещения воды, травы, камней и т. Д., Это прекрасно работает, но каждая плитка может иметь альтернативные текстуры, поэтому, например, плитка травы может иметь 5 альтернативных текстур, которые она может использовать.Я хочу иметь возможность генерировать один из них, совершенно случайно, но он должен быть согласованным при каждом воспроизведении и без использования перлин-шума, так как это обычно дает поток (несколько из одной текстуры, а затем несколько из следующей текстурыи т.д.)

Стоит отметить, что я не могу просто установить случайное начальное число для этого, поскольку эта часть мира может быть сгенерирована в любое время, а не в определенном порядке.

Я пыталсячто-то вроде следующего:

public static int PerlinNoiseCalcInt(float x, float y, float size, float power, int min, int max) {
        int f = Mathf.RoundToInt(Mathf.PerlinNoise(x / size * power, y / size * power) * max + min);
        return f < max ? f : max--;
    }

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

Ответы [ 3 ]

0 голосов
/ 21 сентября 2018

Стоит отметить, что я не могу просто установить случайное начальное число для этого, поскольку эта часть мира может быть сгенерирована в любое время, а не в определенном порядке.

Создатьновый System.Random для каждой координаты, используя хэш координат в качестве начального числа.

// this would be your coordinate
var coord = Vector3.one;

var rng = new System.Random(coord.GetHashCode());

// the below will always be the same (as long as coord doesn't change)
var rand1 = rng.Next();
var rand2 = rng.Next();
var rand3 = rng.Next();
0 голосов
/ 21 сентября 2018

Когда вы говорите «последовательный», вы имеете в виду «детерминированный»?

Есть много способов сделать это.Вы можете просто использовать любую функцию случайных чисел, где аргументы представляют собой некоторую комбинацию ваших координат.

Например:

public int GetTileInt(int x, int y, int seed, int numberOfOptions)
{
     return SomeRandomFunction(x^2*y + 2*y^2*x + seed)%numberOfOptions;
}

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

Другой вариант - просто применить случайное значение int к каждой плитке, независимо от какой-либо координаты.Затем для каждой плитки индексом текстуры будет число по модулю количества возможных текстур, а затем просто назначьте текстуру этому индексу.

0 голосов
/ 21 сентября 2018

Я не уверен, правильно ли я понял, что вы ищете, но вы пытались взглянуть на диаграммы Вороного ?Алгоритм будет выглядеть примерно так:

  • возьмите несколько случайных точек, называемых начальным числом или генератором, и примените к ним случайную текстуру (чем больше у вас начального числа, тем больше областей вы получите)
  • для каждой другой точки, найдите ближайшее семя и примените к нему ту же текстуру

Если вы будете следить только за семенами, вы сможете каждый раз регенерировать стакой же внешний вид.Вы также можете играть на вероятностях, если вы хотите генерировать чаще одну текстуру, чем другую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...