Loading and showing LODs on runtime from GLTF files

Godot Version

Godot_v4.3-stable_mono_win64

Question

I have existing geometry in GLTF format. For each geometry I have various LOD versions. I’d like to load these on runtime, visualize them and switch between the LOD levels automatically (in the same way that would happen if I’d import the GLTF into the Godot project and enable the LOD system for it).

To be clear, the main need here is to visualize the LOD levels and to be able to do it runtime. So importing the files into Godot project is not really the solution I’m looking for here.

As starting point, here’s the code with which I’m currently loading the GLTF files on runtime:

private void Load(string filename) {
	var doc = new GltfDocument();
	var state = new GltfState();
	var error = doc.AppendFromFile(filename, state);

	if (error != Error.Ok)
	{
		GD.Print($"When trying to load {filename}: {error}");
		return;
	}

	var rootNode = doc.GenerateScene(state);
	AddChild(rootNode);

	GD.Print($"Loaded {filename}");
}

Using this approach, I’d like to load each LOD files (that are currently in separate GLTF files) and plug the results somehow into Godot LOD system. Is it possible?

Another approach that came to mind was switching to using a GLTF extension that supports LODs and load just one GLTF file. So if Godot supports that, I’d be quite interested in that as well. Still, runtime only.

Godot does LoD automatically. Is that not sufficient?

Thanks, but I’m afraid not. As I wrote above, the need is for loading the GLTFs in runtime and plugging them into Godots LOD system.

I ended up solving my needs by utilizing VisibilityRangeBegin and VisibilityRangeEnd fields. It’s clunkier than using the relative size of the mesh on screen. It also requires that the origin of every mesh is actually in the middle of the mesh. However, it got the job done for me.

To be more exact, here’s the code:

private void Load(string filename, float visRangeBegin, float visRangeEnd, Node container) {
	var doc = new GltfDocument();
	var state = new GltfState();
	var error = doc.AppendFromFile(filename, state);

	if (error != Error.Ok)
	{
		GD.Print($"When trying to load {filename}: {error}");
		return;
	}

	var rootNode = doc.GenerateScene(state);

	var meshes = rootNode.FindChildren("*", "GeometryInstance3D");

	if (meshes == null || meshes.Count == 0)
	{
		GD.Print($"Couldn't find any GeometryInstance3D in the GltfDocument in the file {filename}");
	}

	foreach (var meshNode in meshes)
	{
		// using visibility ranges assumes that the origin point of the meshes is actually in the center of the mesh data
		var mesh = (GeometryInstance3D)meshNode;
		mesh.VisibilityRangeBegin = visRangeBegin;
		mesh.VisibilityRangeEnd = visRangeEnd;
	}

	container.AddChild(rootNode);
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.