Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | Kallistotele |
I’m making a Tron clone, the trail of the cycles generates a lot of vertexes every second and they never disappear.
The render is a Mesh.Primitive_triangles type, I thought it would have been easy to render but after a while the game starts to go very slow.
What are the settings of the material (spatial) that I should use? Are there other ways to improve performance?
the picture is not visible, but whty do you need some many vertexes? I mean, the trail from trone is basically a long rectangle surface, you need like 4 vertexes per each motorcycle turn
Andrea | 2021-03-15 11:58
The trail has to be rendered to create the collision even if you don’t turn, so I need to create 4 vertexes every frame and update the collisions.
Kallistotele | 2021-03-15 12:40
do you mean 4 vertexes or 4 additional vertexes?
if you mean 4 vertexes, and updating the position/collission on every frame is still too much for the engine, than maybe think about skipping some frames (it’s not like anybody will notice if the collision trail is a few pixel shorter than what is supposed to be), and maybe find a way of placing the geometry update on a secondary thread.
if you mean 4 additional vertexes each frame, than go back to 4 vertexes only
Andrea | 2021-03-15 12:49
I mean additional vertexes. Do you mean to change the vertex position of the same 4 vertexes and create new ones only when you turn?
I thought you couldn’t change vertex position, also I don’t know how to slow down the process method, i tried to use a timer but it doesn’t seem to work
Kallistotele | 2021-03-15 13:02
yes i mean that: i suppose you are using a Immediate geometry to create the trail, and i suppose you create a new array of point every frame, and pass this array of points into the immediate geometry using something similar to:
for p in array:
$immediate_geometry.add_vertex(p)
if this is what you do, you can keep doing that but limit the number of points to 4 for each turn. Eg:
var arr=PoolVector2Array()
func _ready();
arr.append(Vector2(0,0))
func _process():
if turning:
arr.append(Vector2(motorcycle.translation.x, motorcycle.translation.z))
$immediate_geometry.clear()
$immediate_geometry.begin()
for p in arr:
$immediate_geometry.add_vertex(Vector3(p.x, 0, p.y))
$immediate_geometry.add_vertex(Vector3(p.x, trail_height, p.y))
$immediate_geometry.add_vertex(Vector3(motorcycle.x, 0, motorcycle.z))
$immediate_geometry.add_vertex(Vector3(motorcycle.translation.x, trail_height, motorcycle.translation.z))
$immediate_geometry.end
Andrea | 2021-03-15 13:10
ImmediateGeometry is very slow (even for a few dozen vertices), I wouldn’t recommend ever using it in Godot 3.x. Even with only 4 vertices, its use had to be replaced with a mesh in Sprite3D: Use mesh instead of immediate for drawing Sprite3D by clayjohn · Pull Request #39867 · godotengine/godot · GitHub
Calinou | 2021-03-15 13:20
Actually I’m using a SurfaceTool inside a MeshInstance Node.
Immediate Geometry doesn’t let you create collisions from meshes, that said I’ going to try reducing the amount of vertexes as you said
Kallistotele | 2021-03-15 13:24
Ok I’m noob and I can’t fix the code myself. I created a timer for the generation of the vertexes, it has to be 0.017 seconds or less, or the trail is not rendered precisely.
A second timer creates the collision box every 0.07 seconds, it does improve performance if i increase the time, but i need the collisions to exist as soon as possible.
This is the code:
func _on_Timer_timeout():
if is_target and wr.get_ref():
surfTool.begin(Mesh.PRIMITIVE_TRIANGLES)
surfTool.add_vertex(prev_point1)
surfTool.add_vertex(prev_point2)
surfTool.add_vertex(Vector3(p.x,p.y+l,p.z))
prev_point1 = Vector3(p.x,p.y+l,p.z)
surfTool.add_vertex(Vector3(p.x,p.y-l,p.z))
prev_point2 = Vector3(p.x,p.y-l,p.z)
surfTool.add_index(0)
surfTool.add_index(1)
surfTool.add_index(2)
surfTool.add_index(1)
surfTool.add_index(2)
surfTool.add_index(3)
surfTool.index()
surfTool.commit(m)
set_mesh(m)
else:
get_parent().queue_free()
func _on_Refresh_timeout():
get_parent().get_child(1).shape = mesh.create_trimesh_shape()
Kallistotele | 2021-03-17 19:23
it’s not clear what you have done since we are missing what prev_point
and p
are, but does this work or not?
if it works, do you notice any stuttering?
ps: i dont know if that’s faster, and sometimes it brokes the collision shape, but have you thought about using scale
?
pps: for the timer, i would have used a simple counter, like (but i dont know which method is the most efficient tbh)
var t=0
func _process(_delta):
t+=1
if t>refresh_time:
t=0
do_stuff()
Andrea | 2021-03-18 15:35
It works, but after a while the game gets slower. I thought about resizing the mesh, but it would scale it on both directions
prev points are the previous point that I used a vertexes, and p is the position of the player
Kallistotele | 2021-03-18 16:25
yeah you have to scale it and move it at the same time.
strange though, if vertex count stays the same it shouldnt get worst over time
Andrea | 2021-03-18 22:42