Enormes mundos 'salvajes' generados por procedimientos

76

Estoy seguro de que todos ustedes conocen juegos como Dwarf Fortress, tierra salvaje y tierra generada por procedimientos masivos. Algo como esto, tomado de este artículo muy útil.

Sin embargo, me preguntaba cómo podría aplicar esto a una escala mucho mayor; Me viene a la mente la escala de Minecraft (¿no es algo así como 8 veces el tamaño de la superficie de la Tierra?). Pseudoinfinito, creo que el mejor término sería.

:RE

El artículo habla sobre el ruido perlin fractal. No soy un experto en ello, pero tengo la idea general (es una especie de ruido generado aleatoriamente que es semi-coherente, por lo que no son solo valores aleatorios de píxeles).

Simplemente podría definir regiones X por X en tamaño, agregar algunas cosas de tipo de carga de región y tener un poco de ruido generando una región. Pero esto resultaría en enormes cantidades de islas.

En el otro extremo, no creo que realmente pueda generar una capa supermasiva de ruido perlin. Y creo que sería una gran isla.

Estoy bastante seguro de que el ruido de Perlin, o algo de ruido, sería la respuesta de alguna manera. Quiero decir, el mapa es muy bonito. Y podría reemplazar el ascii con mosaicos y obtener algo muy bonito.

El pato comunista
fuente
99
"daría lugar a enormes cantidades de islas" - O genera tierra con lagos, si solo intercambia tierra / agua.
3
Aun así, obtendrías una gran cantidad de lagos, en un patrón bastante estándar.
El pato comunista
3
@Kylotan: Mincraft tiene un tamaño infinito (bueno, no realmente, pero es realmente grande ... volumen total = largo. Valor máximo x 128 x largo. Valor máximo). Por lo tanto, no genera el mundo entero de una sola vez ni almacena todo el mapa en la memoria. Genera regiones de 16x128x16 bloques de forma asíncrona si no se han visitado antes, de lo contrario los carga desde el disco.
zfedoran
2
@The Communist Duck: Sí, esto es cierto, un juego como Minecraft puede salirse con la suya usando de 2 a 4 bytes de datos por bloque, pero solo se necesita guardar un byte después de que ya no esté visible (un byte describe el tipo de bloque , los otros bytes describen la iluminación y otros datos que pueden recalcularse más adelante). Aquí es donde se pone interesante, puede usar RLE para reducir drásticamente el tamaño almacenado a solo unos pocos bytes, ya que los bloques son algo coherentes, como mencionó.
zfedoran
44
'Realmente grande' no es lo mismo que infinito y no puedes usar los dos términos indistintamente. Si crece el mapa a medida que se descubre, ese es un tamaño finito que crece según la demanda, una propuesta bastante diferente de ser infinito. Cada bit de crecimiento se puede generar según sea necesario. Los datos del terreno en Minecraft son muy susceptibles de compresión trivial ya que existe un alto grado de coherencia entre los datos. (ej. RLE como se mencionó)
Kylotan

Respuestas:

35

Creo que entiendo mejor lo que estás preguntando ahora.

El ruido no es aleatorio: tiene un aspecto aleatorio, pero se basa completamente en una fórmula matemática y es repetible. Toda la información está codificada en la fórmula. Esto significa que puede tener una fórmula que potencialmente cubra un área infinita, y simplemente use la fórmula en las coordenadas del área que necesita. Cuando necesite un área adyacente, simplemente reutilice la fórmula en las nuevas coordenadas, y dado que la fórmula produce valores continuos, las áreas se unirán perfectamente.

Aquí hay un ejemplo simplificado, usando seno en lugar de ruido perlin para la generación de altura, e imaginando que el mundo es infinito en el eje X pero solo 1 unidad de altura en los ejes Y y Z.

La fórmula es: height(x,y) = sin(x/20)

El juego comienza, y generamos alturas para el área cercana, es decir. (0,0) a (9,0):

[0.0, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.34, 0.39, 0.43]

Tenemos una colina que se eleva hacia la derecha. Digamos que caminamos hasta el final y necesitamos generar los valores desde (10,0 a 19,0) ahora:

[0.48, 0.52, 0.56, 0.61, 0.64, 0.68, 0.72, 0.75, 0.78, 0.81]

Observe cómo la colina sigue subiendo constantemente, y que el valor en (10,0) sigue muy bien del valor en (9,0). Esto se debe a que la función seno es continua, lo que básicamente significa que si la ingresas 2 números adyacentes, obtendrás 2 resultados adyacentes, para una cierta definición de adyacente. Entonces, si usa las coordenadas de su mundo como los parámetros de la función que define su mundo, obtendrá un paisaje continuo que se ajusta sin importar la cantidad o la cantidad que genere a la vez. Cuando genera nuevas partes, fluirán automáticamente de las partes existentes, porque las alturas ya están predeterminadas.

Si el mundo no va a cambiar, ni siquiera necesita almacenar nada, ya que puede calcular exactamente cuál es la altura en cualquier punto de la fórmula. Obviamente, con algo como Minecraft, el mundo es totalmente deformable, por lo que solo debe guardar cada fragmento a medida que lo crea. Dado que existe un alto grado de coherencia entre los fragmentos adyacentes (es decir, si 1 bloque es hierba, es más probable que el bloque al lado sea hierba también) puede comprimir los datos de manera muy eficiente: la codificación de longitud de ejecución funcionaría bueno, pero también lo haría casi cualquier algoritmo de compresión estándar

Mientras que he hablado de la altura como el valor más obvio, puede usar el mismo sistema para generar cualquier característica que desee. Utilice una función matemática con propiedades continuas y donde las entradas son las coordenadas de su mundo y eso puede decidir la presencia de puntos de referencia, depósitos minerales, puntos de generación, lo que desee. (Obviamente, los valores en una fórmula pueden afectar a otra: no tiene sentido colocar un depósito de carbón en el aire, por lo que genera el mapa de altura mundial y luego solo calcula las posibilidades de carbón para los bloques que están lo suficientemente lejos bajo tierra).

Kylotan
fuente
Definitivamente has ayudado a aclarar las cosas, gracias. :) Pero algo así como una función de ruido no sería continua. Y AFAICS, si es continuo, no recibiría un mundo 'aleatorio'. ¿O me estoy perdiendo algo aquí?
El pato comunista
Perdón por el doble comentario, pero siento que lo anterior está separado de esto. Cuando dices 'usa las coordenadas mundiales para el ruido perlin', ¿sería este el mismo tipo de efecto que generar la capa de ruido 'enorme' pero en partes? Hoy me siento un poco lento en la aceptación.
El pato comunista
Bueno, su generación de ruido ciertamente puede ser continua, y generalmente lo es, porque la suaviza. Para suavizar los límites, es posible que deba leer un poco más allá del borde, pero el principio sigue siendo el mismo. Si el ruido en cuestión necesita datos pseudoaleatorios, lo genera a partir de cantidades conocidas, es decir. un hash de tus coordenadas mundiales. Las salidas son entonces predecibles.
Kylotan
2
En cuanto a la aleatoriedad, cada mundo puede tener su propio valor semilla que se utiliza en los cálculos. p.ej. sin (x + seed) en lugar de sin (x), en mi ejemplo anterior. Cada semilla diferente generará un mundo diferente. Y con respecto a la gran hoja ... No estoy seguro de qué relevancia tiene. No importa cuánto o cuán poco genere o cuándo lo haga. El estado inicial del mundo está definido por la fórmula matemática, y solo usas esa fórmula para descubrir ese estado cuando lo necesites.
Kylotan
32

Este tutorial que escribí hace años podría darte algo como lo que quieres:

texto alternativo

Si realiza la modificación de la isla en el último paso, tiende hacia una única masa de tierra que no llega al borde del mapa.

munificente
fuente
77
Grandes visualizaciones!
zfedoran
3
Recuerdo haber usado este tutorial cuando hice mi disertación de maestría sobre la simulación de fenómenos naturales. Usé el ejemplo de "colina" para crear la cúpula del cielo sobre mi mundo 3D. Excelente introducción al concepto de generación de terreno.
C.McAtackney
1
¡Loco, eso es asombroso! No sabía que nadie lo usara realmente.
generosa
1
DIOS MIO !!! También utilicé esto en un proyecto anterior ... ¡la forma más sencilla de generar terreno que he encontrado!
Guerra
15

Para crear una isla grande no es necesario generarla de una vez. Construiría regiones de forma asincrónica mientras las visita.

En lugar de usar una máscara para crear la isla como describe el artículo, una cosa que puedes hacer es jugar con las longitudes de onda de octava de ruido perlin para lograr el aspecto que buscas. Por lo general, la primera octava describe la forma general del terreno. Todas las octavas después simplemente agregan más detalles de grano fino. Por lo tanto, juega con la longitud de onda de la primera octava para controlar qué tan grandes serán tus masas de tierra. Si desea que la masa de tierra esté en el centro, simplemente puede reducir el mapa de altura en una cantidad creciente a medida que se aleja del centro y luego normaliza el ruido. Por ejemplo, imagine combinar estos dos para crear su isla:

primera octava detalles

Este artículo debería ayudar: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

Si quieres aprender sobre infinitos mundos 3D y sobre varios trucos que puedes usar para cambiar la apariencia del terreno jugando con la entrada y salida de ruido, mira este artículo: http://http.developer.nvidia.com /GPUGems3/gpugems3_ch01.html

Puede ser un poco difícil de leer si no está familiarizado con la canalización de gráficos y la programación del sombreador.

zfedoran
fuente
El tipo de efecto que quiero lograr es algo así como una 2D arriba hacia abajo del mapa de Minecraft (no del juego) ... si solo usara menos octavas, ¿no necesitaría generar una gran capa de ruido perlin? ¿O podría de alguna manera generar una cantidad muy pequeña?
El pato comunista
Creo que todavía puede estar un poco confundido acerca de cómo funciona el ruido perlin. Puede generar fragmentos de 16x16 bloques individuales enviando a la función los desplazamientos de coordenadas x e y para el ruido perlin. Observe cómo la función PerlinNoise_2D (flotante x, flotante y) toma las coordenadas x e y. En otras palabras, genera ruido para alguna posición (x, y). Además, generar menos octavas no es lo mismo que cambiar la longitud de onda de las octavas. Menos octavas => Menos detalle de grano fino. Longitud de onda más larga => más ampliada.
zfedoran
Además, aquí hay un artículo con un código que muestra cómo implementar zoom / longitudes de onda más largas: dreamincode.net/forums/topic/66480-perlin-noise
zfedoran
7

El ruido de Perlin y sus amigos son un buen punto de partida, pero probablemente quieras ir un paso más allá. La mayoría de los generadores populares basados ​​en ruido le darán resultados bastante interesantes. Para hacer que el terreno sea realista, debes echar un vistazo a los algoritmos que emulan los efectos de la erosión. Uno de los simuladores de juego más avanzados del mundo, Dwarf Fortress, hace la simulación de la erosión como uno de los pasos para construir el mundo.

Una de las soluciones geniales que he visto se describió en el artículo "Deposición avanzada de partículas" en Game Programming Gems 7. Hay muchas otras disponibles en Internet, por lo que hay muchos recursos para extraer (por ejemplo, 1 o 2 ) .

Dominik D
fuente