I’m generate meshes, and I wanted to generate LODs for them as well, however I hit a wall where generate_lods() from ImporterMesh doesn’t create any LODs, and adding a dictionary w/ array of indexes during add_surface() has no effect on the mesh’s current LOD in the viewport.
@tool
extends Node3D
@export_tool_button("Run") var run : Callable = _run # Dont forget to reload project after adding this
@export_range(0,10,1) var x_idxes : int = 4 # x size of mesh sheet
@export_range(0,10,1) var y_idxes : int = 4 # y size of mesh sheet
@export_category("LODS")
@export_range(0.0,100.0, 0.1) var lod_range := 1.0 # distance for the LOD dictionary
@export var generate_lods := false # enable this to try auto-generating lod
@export_range(1,180,1) var norm_merge_ang : int = 25 # angle used for generating lod
var mesh_instance : MeshInstance3D
func _run():
if mesh_instance != null:
mesh_instance.queue_free()
mesh_instance = MeshInstance3D.new()
add_child(mesh_instance)
mesh_instance.set_owner(self)
var importer_mesh = ImporterMesh.new()
var lod := {lod_range:PackedInt32Array()}
var points : PackedVector3Array
var ns : PackedVector3Array
var i = 0
for y in range(0, y_idxes):
for x in range(0,x_idxes):
var pos := Vector3(x, 0.0, y)
lod[lod_range].push_back(i)
points.push_back(pos)
ns.push_back(Vector3.UP)
i+=1
points.push_back(pos + Vector3(1.0,0.0,0.0))
ns.push_back(Vector3.UP)
i+=1
points.push_back(pos + Vector3(0.0,0.0,1.0))
ns.push_back(Vector3.UP)
i+=1
points.push_back(pos + Vector3(1.0,0.0,1.0))
ns.push_back(Vector3.UP)
i+=1
points.push_back(pos + Vector3(0.0,0.0,1.0))
ns.push_back(Vector3.UP)
i+=1
points.push_back(pos + Vector3(1.0,0.0,0.0))
ns.push_back(Vector3.UP)
i+=1
print("num pnts: ", points.size())
print("lod pnts: ", lod[lod_range])
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
surface_array[Mesh.ARRAY_VERTEX] = points
surface_array[Mesh.ARRAY_NORMAL] = ns
importer_mesh.add_surface(Mesh.PRIMITIVE_TRIANGLES, surface_array,[],lod)
if generate_lods:
importer_mesh.generate_lods(norm_merge_ang,norm_merge_ang,[])
print("num_lods: ", importer_mesh.get_surface_lod_count(0))
mesh_instance.mesh = importer_mesh.get_mesh()
mesh_instance.lod_bias = 0.01
LMK what I’m doing wrong here. I have absolutely no clue at this point.
Here’s a working example for anyone else who stumbles on this:
@tool
extends Node3D
@export_tool_button("Run") var run : Callable = _run # Dont forget to reload project after adding this
@export_range(0,10,1) var x_idxes : int = 4
@export_range(0,10,1) var y_idxes : int = 4
@export_category("LODS")
@export_range(0.1,100.0, 0.1) var lod_bias := 1.0
@export_range(1,180,1) var norm_merge_ang : int = 25
var mesh_instance : MeshInstance3D
func _ready():
_run()
func _run():
if mesh_instance != null:
mesh_instance.queue_free()
mesh_instance = MeshInstance3D.new()
add_child(mesh_instance)
mesh_instance.set_owner(self)
var importer_mesh = ImporterMesh.new()
var points : PackedVector3Array
var ns : PackedVector3Array
var inds : PackedInt32Array
var i : int = 0
for y in range(0, y_idxes):
for x in range(0,x_idxes):
var a_pos := Vector3(x, 0.0, y)
var b_pos := Vector3(x+1.0, 0.0, y)
var c_pos := Vector3(x, 0.0, y+1.0)
var d_pos := Vector3(x+1.0, 0.0, y+1.0)
# Tri 1 = A-B-C
points.push_back(a_pos)
ns.push_back(Vector3.UP)
inds.push_back(i)
i += 1
points.push_back(b_pos)
ns.push_back(Vector3.UP)
inds.push_back(i)
i += 1
points.push_back(c_pos)
ns.push_back(Vector3.UP)
inds.push_back(i)
i += 1
# Tri 2 = D-C-B
points.push_back(d_pos)
ns.push_back(Vector3.UP)
inds.push_back(i)
i += 1
points.push_back(c_pos)
ns.push_back(Vector3.UP)
inds.push_back(i)
i += 1
points.push_back(b_pos)
ns.push_back(Vector3.UP)
inds.push_back(i)
i += 1
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
surface_array[Mesh.ARRAY_VERTEX] = points
surface_array[Mesh.ARRAY_NORMAL] = ns
surface_array[Mesh.ARRAY_INDEX] = inds
importer_mesh.add_surface(Mesh.PRIMITIVE_TRIANGLES, surface_array)
importer_mesh.generate_lods(norm_merge_ang,norm_merge_ang,[])
mesh_instance.mesh = importer_mesh.get_mesh()
mesh_instance.lod_bias = lod_bias
I didn’t bother making the manual LOD generation work, it just seemed like tedious index tracking. I think the way it would work would be to input the indexes of the points you wish to keep. However, I have a feeling that you would have to input them in a similar triangle-making order as how we put in the positions. I haven’t tried it yet because I’m perfectly happy with the generated results.