Zylann / godot_voxel

Voxel module for Godot Engine
MIT License
2.59k stars 244 forks source link

Transvoxel gaps between lod levels in godot 4 #440

Closed Deins closed 1 year ago

Deins commented 1 year ago

Build: https://github.com/Zylann/godot_voxel/actions/runs/3028543632 When using VoxelLodTerrain node with Transvoxel mesher more often than not there are visible gaps between lod levels. I tested it with default material (no material applied) or custom material with vertex shader sample code from docs. image image

When using no stitching most common gaps dissapear, but still there were some holes (like in first screenshot). Is this known bug or am I missing something and different shader has to be used for godot-4?

Zylann commented 1 year ago

Transvoxel requires a ShaderMaterial to properly render seams, as shown here. It is slightly different than in Godot 3. The engine should use a default shader supporting this if you specify no material, or if you use the shader from the demo project (godot4 branch). Or maybe you are missing something in your shader? I can't reproduce the issue: image

Deins commented 1 year ago

Thanks for taking a look. I checked the demo project (https://github.com/Zylann/voxelgame/tree/godot4/project/smooth_terrain) and with default setup I didn't see any issues (other than out of scope, godot not importing/linking textures to the material). But when I switched the generator to flat the gaps appeared again: image I guess it only happens flat or axis aligned surfaces.

Zylann commented 1 year ago

Not seeing any gap with flat terrain either image

Zylann commented 1 year ago

I still haven't seen any gaps of that size on flat terrains, but I noticed sometimes transition meshes are not enabling when they should. It seems to be a bit random, and the ground doesn't need to be flat.

MGilleronFJ commented 1 year ago

Is it still happening? If so, can you provide a test project reproducing it?

Deins commented 1 year ago

Sorry for delay, didn't have time to look at it. But I tested it again with latest release https://github.com/Zylann/godot_voxel/actions/runs/3123916598 and its still happens. image

I don't think test scene will give you anything for me its easy to reproduce:

Have tested on 2 windows machines one with Intel HD and one with AMD gpu and both times gaps appeared. What I have found out is that the gaps mostly (not sure if only) appear on horizontal or vertical planes when X=0 or Y=0 or Z=0. When offsetting the plane only by 0.1 the gaps don't appear.

It seems that the shader code that offsets the vertices pulls away and creates holes there. But interestingly at the points where octree nodes cross there are no holes: image

I would suspect that maybe there some is math error that happens when x=0 or y=0 or z=0 but I haven't had time to dig into the implementation details.

Current workaround: disabling any vertex offset in the shader other than the culling seems to produce good results. I am not sure what is the purpose of moving seam vertices around. However during short testing I didn't discover any gaps without them yet. I guess the offsets make the seams visually more pleasing, but right now better uglier seams than holes in mesh.

Zylann commented 1 year ago

The holes you see correspond to where transition meshes are supposed to be, and they are shown/hidden with shader code, which is why I suspect a shader issue.

Zylann commented 1 year ago

I reproduced it, but I don't know how this can be avoided yet. It seems transition vertices are missing, because impossible to generate in that specific case. It's one of those embarrassingly ambiguous edge cases that are usually not present in typical use cases... I wouldnt even be surprised is float precision issues were also involved, because when surface is exactly lining up with a chunk border, it's not obvious to tell which side it will go in. The problem also disappears if flat height is changed to something that isn't a multiple of 16.

Zylann commented 1 year ago

I just tweaked transition meshing code in dc9f1a7de0c3003f8a2adf5ecd5d231418db0ccf, and it seems to solve that specific case.

Deins commented 1 year ago

Awesome, seems that fixed it 🥳 Great work.