EDIT: I have left the forum for now. Godot doesn't seem to be for me just yet. Will check the engine later, because it does have a lot of really nice aspects. I will not be reading any more answers, but do not see a way to lock the post. Perhaps others find it relevant.

I need to render a lot of "particles" as part of a fluid dynamics simulation and since you can (apparently?) not control the motion of individual particles with a particle system, I tried making a simple test using Sprite3D. On a high end gaming system, I can get 8FPS rendering 10000 sprites, which is entirely useless. Tested this in a windows desktop 64 bit build.

Since I am only just starting out with Godot to check the feasibility of it for my project, it is entirely possible I am doing something silly and that I am the cause for this misserable performance.

The script which does nothing but instantiate the "particles" is attacked below. I made the 3d sprite as a node in the scene, added a spatial material to it and set it to behave like a particle billboard. I turned off cast shadow and double sided. Then I saved the branch (containing just that sprite node) as a scene. That scene is what I am instantiating. I added a single camera to show the sprites.

extends Node

var COUNT=10000
var RANGE=5
var spriteArray=[]

var fps_label;

func _ready():
	fps_label=get_node("Label")

	for i in range(0,COUNT,1):
		var scene = load("res://MySprite.tscn")
		var scene_instance = scene.instance()		
		scene_instance.translate(Vector3(rand_range(-RANGE,RANGE),rand_range(-RANGE,RANGE),0))		
		spriteArray.append(scene_instance)
		scene_instance.set_name("sprite"+str(i))
		add_child(scene_instance)	

func _process(delta):
	fps_label.set_text(str(Engine.get_frames_per_second()))

I should comment that I can use a 3d particle system and render 100 thousand particles (that is how many I request, at least) at 500FPS

2 options that pop to mind: a. extent the particle system on godot source level to get the functionality you need, it is open-source after all, MIT licensed so you don't risk license infection either if that is a concern, and you can likely find help getting up and running either on github issue tracker or developer irc or... b. write your own particle system plugin through GDNative.

! hidden option c: make a feature request and wait for next release to see if someone else might have been interested in implementing it.

for a: https://github.com/godotengine/godot/issues

for b: https://godotengine.org/article/dlscript-here http://docs.godotengine.org/en/3.0/tutorials/plugins/gdnative/gdnative-c-example.html

edit: also, not sure if it would even help but unless I'm mistaken there is also MultiMesh you might be interested looking into. http://docs.godotengine.org/en/3.0/tutorials/3d/3d_performance_and_limitations.html#use-instancing-multimesh http://docs.godotengine.org/en/3.0/classes/class_multimesh.html#class-multimesh in case you are actually dealing with 3D.

Being entirely new to Godot, I am not going with option a right now, thank you very much ;-) For option b, I am actually going to do this using GdNative, since the computation heavily requires it, but the issue is then still how to to push the position data to the particle system.

What I actually did in unity was to create a shader which simply read positions from a shader array and rendered little billboards. Each frame I would write the new data to the array in the shader, and viola.

I see that the particle system in Godot does have a process material which can be a shader. I am still not quite clear on if I can do the same with that, or what exactly a process material is, but I am starting to think that might be a solution.

Anyone having some insight on that part?

Edit: reading now that arrays are currently not supported in the shader language but might be in 3.1. Then I guess I could potentially do it by moving the 3d particle positions over packed in a texture. A lot of unknowns, though.

This is a GDScript,right?....I'm not a programmer but beginer in GDScript I would use for instancing func physics process(delta): and in the func ready set physics process (true) for instancing is better use preload() also use const COUNT = 10000 or var count = 10000 if I'm wrong...so forget it :-)

The node system and Godot's high-level rendering utilities are not designed for rendering very high amounts of objects. You should use lower-level APIs in this case, as demonstrated in this benchmark.

I am familiar with that test, but what it really demonstrates is that the computation of the motion is faster when done in native code. That is only natural, and that was my plan as well. The actual drawing of the sprites happen in the Godot engine and should not change in speed depending on whether the initial "create sprite" call came from script of native code.

In my test, I only instantiate the sprites. I do not move them. I then look at how quickly the engine is able to simply draw them, and apparently, that is not very fast. To be fair to the engine, you should generally not make and render 10.000+ 3d sprites. I only did that, though, because the particle system would not let me control the motion, which is something I would need for the project to work.

Seems like I will be stuck with unity a bit longer. There I render a large number of 3d points with the current particle positions, feed that through a geometry shader which generates quads billboards, at current calculated point location, that I texture with a fragment shader and that works just fine.

A lot of other things about Unity works less fine, though, so I am a bit sad that Godot does not have that final piece of the puzzle ready just yet.

Hm, I can see how that sounds promising, but I doubt I can create individual particles using that, as opposed to a continuous mesh. Please elaborate

For various reasons, I cannot using marching cubes right now. What it boils down to is very large difference in scale and inability to properly define the grid used for the marching(shape) methods.

Thanks, though.

5 years later