Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Geomorphing, Circular LODs, Symmetric grid #622

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Xtarsia
Copy link
Contributor

@Xtarsia Xtarsia commented Feb 15, 2025

closes #553
closes #383
closes #421
closes #209
closes #158

Clipmap method re-written. now exclusivly built from rectangular meshes, with a minimum 2 unit width/length.

renamed geoclipmap to Terrain3DGeoMesh class object, and moved related functions from Terrain3D into this class.

main shader, and extra shaders updated to implement geomorphing.

Geomorph is required as the clipmap does not have any seam meshes.

Minimum mesh size raised to 16 (things break down less than that, even with the old clipmap)

Vertex spacing minimum stepping adjusted to 1/16th (0.0625) prevents a few artifacts with the new methods.

v_camera_pos has been replaced by a uniform _camera_pos, and all relevent shader inserts updated.
Required as the shadow pass would set VIEW_MATRIX[3] to the light source position, resulting in a missmatch between the vertex positions between shadow/standard render passes

The entire mesh is now an alternating grid. Still to update collision to match (should hopefully be fairly straight forwards)
Edit: Collision grid now matches.

Current issues:
painting tools dont work untill swapping away / back to the scene on first load.
pretty sure ive not correctly implemented multiple things..
some crashes when closing / reloading.

Im not very familiar with c++ in general and have stumbled my way through this so far.. its "working" but Im a bit in the dark in regards to polishing this up.. an early review would be greatly appreciated!

Godot_v4.3-stable_win64_ayU9jwM6PB.mp4

@TokisanGames
Copy link
Owner

Does this resolve #191?

@Xtarsia
Copy link
Contributor Author

Xtarsia commented Feb 16, 2025

Does this resolve #191?

It doesnt implement a veiwport size based adjustment to mesh size, but it does very much reduce how noticable transitions are between LODs since they smoothly interpolate now.

@Xtarsia Xtarsia marked this pull request as ready for review February 19, 2025 21:28
@TokisanGames
Copy link
Owner

TokisanGames commented Feb 22, 2025

c03e2ec

  • Wow, geomorphing looks great. Very nice work.

  • The symmetric mesh looks great and is so much better at handling cliff areas at certain angles.

  • The circular lods makes the lowpoly shaders look much better without the lod artifacts.

  • Collision generation is quite slow.

Switching to Full / Editor is 10x slower. I thought it was going to crash at first. It's an extraordinary amount of time for only 3 regions in the demo.

Dynamic Editor at max size/radius is also quite slow to generate. The engine halts for a half second every update. Strangely CPU/GPU time don't report it, even with view gizmos turned off.

Actually, even at normal size, dynamic editor is noticeably sluggish. Turn off gizmos. Then compare with Dynamic Game and move the camera top down, to the side. FPS is high, but the display noticeably stutters.

No console messages. Haven't looked at the code yet.

  • Sculpting height reports this error: Terrain3DInstancer#1310:update_transforms: Instancer isn't initialized. And instances don't work either.

@Xtarsia
Copy link
Contributor Author

Xtarsia commented Feb 22, 2025

Sculpting height is fixed for me after 1dc804f

It seems the generate face loop in _get_shape_data takes an entire milisecond 😬

@Xtarsia
Copy link
Contributor Author

Xtarsia commented Feb 22, 2025

After some testing, and minor shuffling about, I can shave off a bit of time for a 65x65 size shapes from about 1.5ms to 1.2ms per _get_shape_data()

the generate faces loop creates the faces needed for a trimesh (concave) collision shape, so is required as far as I can see.

Testing on main, for a 65x65 shape size, it takes around 0.6ms.

So whilst this is slower, its not the main culprit. maybe set_shape_data() for concave collision shapes is just terribly slow?

Tho I am not sure why it would be so much slower than heightmapshape.

@TokisanGames TokisanGames changed the title Implement geomorphing Implement Geomorphing, Circular LODs, Symmetric grid Feb 22, 2025
@Xtarsia
Copy link
Contributor Author

Xtarsia commented Feb 22, 2025

Godot does a whole load of processing to the faces data, that is handled entirley different to the heightmapshape methods.

It may be better to write a PR for Godot to enable alternating quad diagonals as an option directly in the heightmap shape.

@TokisanGames
Copy link
Owner

TokisanGames commented Feb 23, 2025

Yes, but that could take 6 months. We should copy the HeightMapShape class and make it our own SymmetricHeightMapShape3D and include it here in this PR. That's how I made Terrain3DMaterial. ShaderMaterial wasn't designed to be extended through godot-cpp, so I ripped all the code and built on top of it.

@Xtarsia
Copy link
Contributor Author

Xtarsia commented Feb 23, 2025

height_map_shape_3d.cpp makes calls to the Physics server which is either godot_physics_server_3d.cpp or jolt_physics_server_3d.cpp

Which then pass the data to the respective module internals.

I was able to modify https://github.com/godotengine/godot/blob/394508d26dcf1b7a9362453f9009c07d969f1a7e/modules/godot_physics_3d/godot_shape_3d.cpp#L2061C1-L2081C2

That worked for the collision (with GodotPhysics), but I dont think gdextension can get that deep?

@TokisanGames
Copy link
Owner

Which function call is the one causing the slowdown? Is it set_faces? 🤔 I don't see much complexity there though.

height_map_shape_3d.cpp makes calls to the Physics server

The only calls I see are to shape_create(), which just memnews an object and returns an RID. Or set_shape_data, which sets data inside the shape. We can do both of those.

I looked through the code a bit and thought about options like making our own heightmap shape using the custom shape type. Or that GodotHeightMapShap3D is a GodotoncaveShape3D. Perhaps we could do our own processing and setting the data directly in the physics server to avoid setting faces.

Ultimately, however I think any shape we make needs to be a GodotShape3D and implement all of its virtual functions. And we don't have access to it via godot-cpp. So this option is out.

We can start on the Godot PR process, but I think our immediate options are either LOD0 not symmetric and fast or symmetric and slow. It's not just that it's slow, but it makes the engine halt and stutter, which is a big problem. Maybe we can put it in a thread?

@Xtarsia
Copy link
Contributor Author

Xtarsia commented Feb 23, 2025

LOD0 can be not symetric, its the best compromise at this point.

@TokisanGames
Copy link
Owner

Ok. That still allows us to geomorph and have circular lods?
Too bad we didn't get the PR in during the betas. Now we're looking at maybe 4.4.1 and 3.4.1.

@Xtarsia
Copy link
Contributor Author

Xtarsia commented Feb 23, 2025

Collision is fast again now! I can say after looking a lot more into the inner workings, that heightmap shape is handled very differently than concave. I can probably get a PR together for the engine in due time, tho it would mean touching both godotphysics and joltphysics modules, and the scene shapes for the editor debug mesh generation.

Ive actually got godot building so I can chip away at that - and potentially things like dx12 mipmaps 🤔 .

Ultimatley I should be able to boil it down to a check box, and an extra field in the data dict "alternating_grid".

Ready for a good review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants