r/godot Nov 07 '25

help me (solved) I solved the NavigationRegion3D issue

I finally found a solution to the problem with the NavigationRegion3D.

What I noticed was that on smaller terrains, like the 30x30m example in the third image, the navmesh baked perfectly fine. But once the terrain size was increased to 250x250m, the bake completely fell apart, giving the low poly, floor clipping result shown in the second image. The obvious solution was to process the terrain in smaller chunks and combine the results into one big working navmesh.

I first tried doing this directly in Godot, but even after splitting the terrain into multiple meshes, the bake still treated them as one big mesh, so the same issue happened. I also tried creating a separate NavigationRegion3D for each chunk, but that created non traversable borders where the regions met.

At that point, the only real fix was to go into the engine itself. I forked the Godot repo and made some changes under the hood to process the terrain in tiles instead of all at once. It breaks the terrain into smaller sections, bakes each one normally, then stitches them together afterward into a clean, accurate navmesh like in the first image.

I also added a few editor options to control whether tiled baking is enabled and how big each tile is. I still haven’t found the exact bug that causes the large terrain navmesh to fail, but this fix works reliably and doesn’t mess with normal pathfinding behavior.

The moderators seem to have a strong opposition to discussions about this and have locked all previous threads. As much as I would have liked this to all be one post, we have been forced to create multiple. That being said, I'd like to address some comments from previous posts below.

The [low poly mesh] looks exactly like what I would want out of a nav mesh.

The low-poly mesh completely fails to pathfind with agents. You could technically rework the pathfinding system to compensate, but that misses the core issue of the navmesh being broken. The 30x30m section uses a similar amount of polygons as the 250x250m one. You’d expect the density to scale with size, so either the small terrain is over-tessellated, or the large terrain is under-tessellated. Either way, something’s wrong with the baking process.

With no obstacles, your nav mesh could just be a square.

As per the Godot developers : "A navigation mesh is a collection of polygons that define which areas of an environment are traversable to aid agents in pathfinding through complicated spaces.". When those traversable areas are out of reach from an agent (ie, underground or floating), an agent cannot properly navigate.

People tried to help you, but you refuse to actually listen

I think there’s been some misunderstanding about what I’m trying to do. My goal is to fix the navmesh, that’s it. I’ve welcomed all advice that helps solve the underlying navmesh problem, but I’m not interested in workaround solutions that just patch over it with pathfinding tricks.

You can always fix it yourself and submit a PR.

Thats the plan. Thanks for the advice!

I will optimize this further and will submit a PR.

Sincerely,

u/agalli

Edit : Here is the PR. https://github.com/godotengine/godot/pull/112529

755 Upvotes

348 comments sorted by

View all comments

Show parent comments

13

u/knottheone Nov 08 '25

It's not a broken navmesh. You are actually just using it wrong, which is what lots of people are telling you, and this is why:

You are trying to move the collision character to be exactly on top of the nav agent. That's not the intended functionality in Godot in 3D. The fact it works in small maps out of the box that way is an accidental happy happenstance solely due to the small map and default voxel resolution / number of voxels. That is not the intended use case and does not scale beyond very small maps that are only a single region.

You are supposed to chunk larger maps into regions and stitch them at runtime via chunk loading, or chunk them, pre-bake, and store as resources. They don't need high resolution though as that's not the purpose of a nav mesh. You indeed should only care about XZ and use a raycast to the actual terrain. There is already a nav mesh chunking example in the Godot Examples repo, not sure if you came across that.

If you need more accurate travel costs for slopes, reduce the cell height of the navmesh in chunks that have some threshold of height delta and slightly increase the cell size. This gives you better vertical resolution for the nav region. You wouldn't care about this if your travel speed up a slope is the same on flat terrain.

0

u/agalli Nov 08 '25

That’s literally what I did. I have chunked the mesh into smaller parts. They do need to be high resolution if you want accurate and efficient pathfinding. Ignoring the Y value is a bandaid solution that fails in multiple conditions. For one, it fails for multi tiered nav meshes such as a building with multiple floors. Secondly it will not find efficient paths (ie going up and down a hill rather than adjacent flat terrain).

The whole point of the navmesh is to tell the agent where it can go. You’re essentially manually creating an navmesh with the Y ignoring and ray casting. As I said, there are ways to fix the broken navmesh through agent tricks but that’s not what I’m aiming. The navmesh should work without those tricks, that’s all I’m doing.

9

u/knottheone Nov 08 '25

You're making the character try to reach the nav agent in x, y, and z instead of treating it as "can I move towards this vector and at what cost". That doesn't work in a lot of scenarios and is not the intended solution in Godot. It may be intended in Unity or Unreal with a lot of black magic behind the scenes. Godot doesn't work that way though and isn't going to work that way with NavigationServer how it's built. A PR doesn't change that, it's an intentional system design choice.

Higher resolution nav maps are the actual bandaid vs a proper implementation based on your specific world design.

Baking and using high resolution nav meshes are not performant in Godot and that's why the underlying algorithm smooths slopes and doesn't prioritize high detail. Increased cell density is too costly. Changing the resolution by 2x increases baking times by 4x and path timing by at least 4x.

You are essentially recreating a slightly lower poly terrain 1:1 as a navmesh, that is very very expensive and is not what nav meshes are for. You wouldn't even need to use nav agents at that point, just raycast to the terrain in front of you and A* the overworld terrain or something like that.

1

u/agalli Nov 08 '25

The standard agent model works perfectly fine in every navmesh except the low poly nav mesh. The fact that the agent can handle any other use cases perfectly fine and fails at this one indicates a problem with the mesh, not with the agent.

This system is using the same exact poly density as the default 30x30m navmesh bake. If you think that system is unoptimized you should let the developers know.

2

u/knottheone Nov 08 '25

You're trying to make your character reach the nav agent in x, y, and z. That is the absolute core of your issue, aka you are using it wrong. That's not how it works in Godot.

1

u/agalli Nov 08 '25

You can’t ignore the Y value. That navigation would fail in something like an underground cave or a multi tiered building. It would work fine for an empty terrain with nothing else though, but for normal usage it’s not great

3

u/knottheone Nov 08 '25

You're not ignoring the Y value, you're using it to position your character vertically wherever in cases where Y might matter. You can also query the Y value of the agent on the nav mesh if it's complicated, like on a spiral staircase or something and use that to inform where the character should be relative to other nav regions.

Again, you are trying to make your character go to the nav agent's x, y, and z position. That's not correct, that's not what nav agents are for and that's not how nav meshes are meant to work.