Generate new terrain on movement

I’m quite new to three.js and to 3D in general, so I might be in over my head here.

I’ve generated a patch of terrain using plane and simplex noise, and would like to generate new terrain as a player moves across it.
What would be the best way to approach this? I was thinking I might be able to manipulate the vertices of the geometry, similar to the effect in this video, but I’m not sure how? Or would it be better to split it into chunks and add new chunks on movement? Or to generate a large geometry and somehow control how much of it is rendered?

I’ve also added randomly generated objects to the terrain, such as trees and plants. How would I continuously add them to the generated terrain in the example above?

Here is an example of how I generate the terrain.

There are actually different solutions for this problem. Simple ones and very sophisticated stuff :wink:

Maybe the easiest approach is presented here: Endless Forest (2018 Port)

It’s some sort of showcase that demonstrates the basic structure of an endless runner. If you have a look at the source code, you will encounter a run() function which responsible for the animation of the camera and particles but also for respawning objects in the virtual world. The ground actually consists of two separate objects which are changed at certain conditions. You might want to use a similar approach in your application.

This approach is definitely faster than manipulating vertices per frame. The problem is that your chunks have to match at the seams. Unlike in the forest demo, your terrain is not flat which makes this a bit more complicated. In general, you can achieve this by generating the entire terrain geometry and divide it into multiple sections. This can be done at application start or in advance with a tool. You can then render only the current section and the adjacent ones. A section would be represented in three.js as a separate mesh with its own geometry. If you want to speed up things a bit, you can try to use a single mesh by merging the current geometry data via BufferGeometryUtils.mergeBufferGeometries(). Or you give instanced rendering a try.

It depends on your particular use case if this approach is sufficient or if you need something smarter.

An advanced terrain rendering algorithm was presented by Florian Bösch in the book WebGL Insights. The related chapter is Terrain Geometry - LOD Adapting Concentric Rings. He presented a LOD technique which is very useful in context of terrain rendering since you want to show more details at the players position and less details at distant places. Maybe you can use some of his thoughts for your own application.

2 Likes

Position of a vertex could be converted from local to world (at the side of javascript or in shaders, depends on needs) and that value can be used in the noise algorithm.
I was thinking about that approach recently and plan to create a concept. We’ll see if it works at all :thinking:

Before you create something by yourself, I suggest to study the related work. This area is actually very well researched and in most cases you can use something existing.

1 Like

Sure :slight_smile:
But who needs those ready-to-use solutions? To build your own bicycle is much more fun :slight_smile:

Yeah, it makes more fun but it’s also more time consuming. Consider a project with a limited amount of budget. In this context, you want to build your stuff based on components that are robust, reliable and performant. If a project would develop everything from scratch, it would never release its related product in time. Besides, a lot of development teams do not have the skill to develop let’s say a rendering or physics engine by themselves.

three.js is a ready-to-use 3D engine. You are using three.js, right? :wink:

2 Likes

Perfectly correct and I totally agree :slight_smile:

PS Next time I should wrap my phrases in <joke></joke> tags to make it clear when I’m joking :smile:

1 Like

I’ve already thought you are not serious :slight_smile:. But (new) visitors from a search engine might not get the joke so some lines for clarification can’t hurt :wink:

1 Like

Totally agree, i made Tesseract in my freetime and it took me about 2 years. Of course it isn’t just a basic solution, but if you want to make it serious itw will take more effort than time available, there is a lot prototyping, especially if your main product is something else and it’s just part of it, then out of box will be more reasonable.

2 Likes

Thank you for the detailed reply! As a newbie it’s hard to know how to approach a problem, so I really appreciate it.

I think the chunk approach will do just fine. Would that mean slicing the vertices array, or is there a better way of dividing the geometry?

I would slice buffer data. It’s a valid approach to subdivide the geometry.

1 Like

Thanks for the help! I think I have a better grasp on where to start now.

1 Like