@hutukawa said:
Thank you all. Got idea to make it by using one large texture and change UV offset of texture in planes. But... I think it is not worth enough, cause of future updates of tile-types and trying to scale UV in offset of 0.001s...
There is that downside of using a single, large texture, as it does impose some limits on how many textures you can have. That said though, I think using a single texture with UV offsets is the most performant way of doing it from a pure GPU perspective, since everything can be drawn in a single draw call.
If you want to go down this route again for any reason and are looking for a reference, I've written a voxel tutorial that may be helpful. It's a few years old and is a touch slow, but it might be useful as a reference if you get stuck on the UV part.
For now - i draw every plane as new mesh once to static geometry. It can handle so many objects. But when i did it by only one mesh - object, it was more faster and got worked by thousands if planes without fps drops.
Yeah, having a single plane as a separate mesh would be costly since it has to send all the plane data to the GPU one at a time.
However, you might be able to get a middle ground by using a separate Mesh per material, so all planes that use the same material are in the same mesh. This is kinda in between using separate meshes per plane and only a single mesh. You get the benefits of sending large amounts of data to the GPU at once (so faster than individual planes) but you also get the benefit of material's being separate.
Maybe do it like: All top planes on One mesh, all LeftSides on other and etc. But, i think it will create same untextured problems.
P.S.
Also i found this in Godot Q&A:
But i can't figure it out logic, and is it possible to use it on many planes created by For-loop?
You'd probably need to store the data for each different plane material separately and then commit each surface one at a time. Something like this, I think (just an example):
# Lists to hold the data needed to pass to the Surface tool. We want a list per material, per data that will be sent to the SurfaceTool (one for vertices, UV, etc).
var dirt_mat_vertices = []
var sand_mat_vertices = []
# etc
# Get the data to pass to the surface tool
# (Just an example)
for plane in world_planes:
if (plane.material == dirt):
dirt_mat_vertices.append(plane.vert_one)
dirt_mat_vertices.append(plane.vert_two)
dirt_mat_vertices.append(plane.vert_three)
dirt_mat_vertices.append(plane.vert_four)
elif (plane.material == sand):
sand_mat_vertices.append(plane.vert_one)
sand_mat_vertices.append(plane.vert_two)
sand_mat_vertices.append(plane.vert_three)
sand_mat_vertices.append(plane.vert_four)
# The key is instead of calling something like SurfaceTool.add_vertex you instead want to do cache that data per-material in a list
# Now with all the data cached, we can make the mesh
var surface_tool = SurfaceTool.new()
# setup the surface tool as needed
var mesh = null
# Process dirt
surface_tool.set_material(dirt_mat)
for i in range(0, dirt_mat_vertices):
surface_tool.add_vertex(dirt_mat_vertices[i])
mesh = surface_tool.commit()
# Process sand
surface_tool.set_material(sand_mat)
for i in range(0, sand_mat_vertices):
surface_tool.add_vertex(sand_mat_vertices[i])
mesh = surface_tool.commit(mesh)
I think something like that would work, but I have not tried it.