/r/proceduralgeneration
This subreddit is about everything procedurally generated (media, techniques, ...)
This subreddit is about everything procedurally generated (pictures, videos, discussions on techniques, ...)
/r/proceduralgeneration
Hi. I'm making a procedural generated landscape and have ran into a problem. I'm feeding the noise function I'm using with world coordinates where 1 unit is one meter. This results in a very high frequency noise by default so I have to scale down the input coordinates a lot to get low frequency which can create accurate sized hills and mountains. This works well for the terrain geometry which have a minimal vertex spacing of 0.5 meters.
But I'm also generating textures and in the highest resolution (when closest to ground) I am dealing with sampling steps which are 0.03125 per sample point. Since I have to downscale the world coordinates by a factor of 10000 to get the frequency I require this results in floating point precision issues at those small increments. So one or more adjacent sample points can become the exact same position which in turn results in the exact same noise value. This is a problem becuase I need to efficiently calculate normals per texel for texture blending. And if I can't calculate a normal from the adjacent height values (because they are the same) it completely ruins everything.
I could of course take samples with a set minimum offset which would guarantee that all samples are different, but for performance requirments this is out of the question, I need to make use of the samples already calculated by adjacent threads in the compute shader to get anywhere near acceptable performance.
So I started to think that there must be some way to have the noise function be much lower frequency by default so I don't need to downscale the input coordinates at all and get into this precision issue. I can't use doubles either as that is massively murdering the performance on a GPU.
Unfortunately I don't really "get" how perlin noise works and my attempts to modify the function I'm using have failed spectacularly. So I was wondering if anyone knows this and how it's typically solved.
The perlin function I'm using is this one: https://github.com/BrianSharpe/Wombat/blob/master/Perlin2D_Deriv.glsl
Example of the problem I'm facing
The title is not worded well, sorry, but I couldn't think at anything different.
The jist of the thing is this: I want to write an NPC procedural generation routine that chooses a random number of personality traits, and in which each subsequent trait is informed by the previous ones to some degree (so that, for example, if it picks "lazy" as first choice, it doesn't picks "sporty" as the second one because it doesn't make too much sense).
I'm still learning, so this might be a very easy problem to solve, but as of now I have no idea how to tackle it without creating an angodly amount of lookup tables for each combination.
Can you help me with ideas and learning material? Thanks!
So I have been working on a project where I need to detect a person is in danger by any physical means threatened by another individual or group of Individuals, I have some basic idea of Unreal for Game development but this simulation and procedural generation is totally new for me so any advice regarding the same will be appreciated
Seed I used while testing. Rivers where generated by picking random points above an elevation then following the slope of the elevation down, creating lakes whenever they flowed into valleys.
Tectonic plates layered on top of the terrain. They where generated using a Voronoi diagram then each plate was given a random velocity(green asterisks). Plate collisions where then determined using the plates vectors and positions. Boundary types are as follows: red, convergent; orange, divergent; and pink, transform. Convergent boundaries create mountain ranges/island chains and divergent boundaries create create rift valleys. The height of mountain ranges somewhat vary based on the intensity of the plate collisions. Please note: I am not a geologist so my understanding of how plate boundaries effect terrain is most likely incorrect.
Pure elevation map created with multiple arrays of OpenSimplex noise at different octaves added together in addition to the modifications made by the plate boundaries.
Made in Blender using Geometry Nodes
Recently I have been working on a little opengl renderer for procedural planets, with the eventual goal of expanding to an entire universe. These are some screenshots I really enjoyed and wanted to show off. I have some videos of flight on my youtube channel: https://youtu.be/SaLLzhwu-J8?feature=shared
https://www.youtube.com/watch?v=OmRL9ZBgwPQ&list=PLQBIOV-hHB3wUm_c-v2wa1pPpk-l6vBrZ&index=21
new programmer. Not very mathy
i'm sure what i'm looking for is related to fourier, lissajous, wave functions, periodic functions, dynamic functions, parametric, generate, kinetic, epicycles, chaos theory, uniformly rotating circles/compasses, maybe euler and maxwell equations....... but this is just alot of words to me in a google hole........... when i'm sure what im looking for is a simple field of maths or family of equations or algorithms or something.
really just looking for simple ways to implement the kind of forms seen in the video in a plotter like matplotlib (i'll look into p5 later) that I can add live updating of parameters to and other simple-ish things like algorithms for floatiness, parallax motion, and simple noise.
not looking for complex shaders or advanced stuff. just nice, varied geometry plots that, with parameters, can be animated to move between very ordered and mandala-esque, to random chaotic squigglies.
pointers in the right direction greatly appreciated!
it's satisfying for me.
https://i.redd.it/depgpr9tv5md1.gif
It takes quite a while for the random walk to reach the first white cell, but if you are patient and watch it through to the end, the gif will eventually terminate with a completed maze.
It looks like always converging and terminating in finite time, but when i increase the maze size, the consuming time drastically increases due to its stochastic nature. how to fix it? at the first place, did i properly implement the algorithm?
I know there are many other algorithms for generating mazes other than Wilson's. But this question focuses on Wilson only.
I share my Python source code below. it's a bit dirty and not well-organized, so feel free to ask me if you are wondering the code.
def random_step(r, c, R, C):
dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]
neighbors = []
for dr, dc in dir:
nr, nc = r + dr, c + dc
if 0 <= nr < R and 0 <= nc < C:
neighbors.append((nr, nc))
return random.choice(neighbors)
from PIL import Image, ImageDraw
def draw_maze(maze, path, nonust, uniform_scale):
R, C = len(maze), len(maze[0])
img_size = (C * uniform_scale, R * uniform_scale)
img = Image.new("RGB", img_size, "black")
drawer = ImageDraw.Draw(img)
for r in range(R):
for c in range(C):
x0, y0 = c * uniform_scale, r * uniform_scale
x1, y1 = x0 + uniform_scale, y0 + uniform_scale
if (r, c) not in nonust:
drawer.rectangle([x0, y0, x1, y1], fill="white")
elif (r, c) in path:
drawer.rectangle([x0, y0, x1, y1], fill="gray")
# elif maze[r][c] == (True, True, True, True):
# drawer.rectangle([x0, y0, x1, y1], fill="white")
else:
drawer.rectangle([x0, y0, x1, y1], fill="pink")
if maze[r][c][0]:
drawer.line([x0, y0, x1, y0], fill="brown", width=2)
if maze[r][c][1]:
drawer.line([x1, y0, x1, y1], fill="brown", width=2)
if maze[r][c][2]:
drawer.line([x0, y1, x1, y1], fill="brown", width=2)
if maze[r][c][3]:
drawer.line([x0, y0, x0, y1], fill="brown", width=2)
return img
def Wilson(R, C, uniform_scale):
maze = [[[True, True, True, True] for _ in range(C)] for _ in range(R)]
frames = []
nonust = {(i, j) for j in range(C) for i in range(R)}
r0, c0 = random.randint(0, R - 1), random.randint(0, C - 1)
nonust.discard((r0, c0))
maze[r0][c0] = [True, True, True, True]
while len(nonust) > 0:
startr, startc = random.choice(list(nonust))
path = [(startr, startc)]
while path[-1] in nonust:
r, c = path[-1]
nr, nc = random_step(r, c, R, C)
if (nr, nc) in path:
path = path[: path.index((nr, nc)) + 1]
else:
path.append((nr, nc))
frames.append(draw_maze(maze, path, nonust, uniform_scale))
for i in range(len(path) - 1):
r, c = path[i]
nr, nc = path[i + 1]
if nr == r - 1:
maze[r][c][0] = False
maze[nr][nc][2] = False
elif nr == r + 1:
maze[r][c][2] = False
maze[nr][nc][0] = False
elif nc == c - 1:
maze[r][c][3] = False
maze[nr][nc][1] = False
elif nc == c + 1:
maze[r][c][1] = False
maze[nr][nc][3] = False
nonust.discard((r, c))
frames.append(draw_maze(maze, path, nonust, uniform_scale))
frames[0].save(
"Wilson.gif",
save_all=True,
append_images=frames[1:],
duration=0.5,
loop=0,
)