Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can i draw multiple cubes at once Without creating objects #2385

Open
zhu2900000 opened this issue Sep 26, 2022 · 9 comments
Open

How can i draw multiple cubes at once Without creating objects #2385

zhu2900000 opened this issue Sep 26, 2022 · 9 comments

Comments

@zhu2900000
Copy link

zhu2900000 commented Sep 26, 2022

Hi~
I found that multiple objects were created and refreshed in real time, with a lot of display latency. If you do not create a class like the following, but maintain multiple lines, the display efficiency will be much improved. Whether drawing a cube provides a relevant method. Or is there another faster way? Thank you.

Without creating objects, draw multiple cubes at once
like this:

data = np.random.normal(size=(1000, 2))
data[0] = -10, -10
data[1] = 10, -10
data[2] = 10, 10
data[3] = -10, 10
data[4] = -10, -10
plot = scene.Line(data, parent=view.scene)

Create a bunch of cubes in the form of multiple objects and update them in real time with low efficiency. Is it possible to draw many lines at once like drawing lines and update them in real time

@djhoese
Copy link
Member

djhoese commented Sep 26, 2022

https://vispy.org/faq.html#why-is-my-visualization-slower-when-i-add-more-visual-objects

If you have a lot of lines then creating one array with all of the separate lines and providing the connect keyword argument with "segments":

connect : str or array
Determines which vertices are connected by lines.
* "strip" causes the line to be drawn with each vertex
connected to the next.
* "segments" causes each pair of vertices to draw an
independent line segment
* numpy arrays specify the exact set of segment pairs to
connect.

will give you the best performance. There are a few other options, but in general as the FAQ answer above says, you want to reduce the overall number of Visuals.

@zhu2900000
Copy link
Author

https://vispy.org/faq.html#why-is-my-visualization-slower-when-i-add-more-visual-objects

If you have a lot of lines then creating one array with all of the separate lines and providing the connect keyword argument with "segments":

connect : str or array
Determines which vertices are connected by lines.
* "strip" causes the line to be drawn with each vertex
connected to the next.
* "segments" causes each pair of vertices to draw an
independent line segment
* numpy arrays specify the exact set of segment pairs to
connect.

will give you the best performance. There are a few other options, but in general as the FAQ answer above says, you want to reduce the overall number of Visuals.

I can now draw a lot of lines using this method, which works. But I need to draw a lot of cubes now, using a similar method.

@djhoese
Copy link
Member

djhoese commented Sep 27, 2022

@brisvag has some PRs that would allow instanced drawing (low-level OpenGL feature that allows drawing a lot of the same mesh very quickly). However, for a cube, you probably want to create a single MeshVisual with all of the cubes defined in a series of vertices/faces. @brisvag may even have an example that doesn't require his in-development stuff and can work on existing VisPy.

@brisvag
Copy link
Collaborator

brisvag commented Sep 28, 2022

It depends how many cubes you have and how they change between each other... Without instanced rendering, each use case must have an ad hoc shader.

If the number of cubes is not crazy (the mesh fits in gpu memory even copied N times) then you can just do everything in the shader; otherwise you need instanced rendering or other clever tricks. Some more code and a more detailed explanation of your needs would be helpful here @zhu2900000 :)

@zhu2900000
Copy link
Author

zhu2900000 commented Sep 29, 2022

@brisvag

I just wish there were some simple cubes, the number of cubes is plentiful, and write to update it in real time (pan and rotate). Creating a box object for each cube runs like a stutter. My computer doesn't have GPUs.

for i in range(***):
     box3d = scene.visuals.Box(self.size[0],self.size[1],self.size[2],
                                              edge_color="white",parent=self.parent_node)
     self.boxes.append(box3d)
tf = MatrixTransform()
tf.rotate(tf_theta, [0, 0, 1])
tf.scale([tf_width, tf_length, tf_height])
tf.translate((tf_x, tf_y, tf_z))

@brisvag
Copy link
Collaborator

brisvag commented Sep 29, 2022

Do you create new cubes every time you update? If so, updating them inplace might improve your performance. On the other hand, this seems like the perfect candidate for instanced rendering... Unfortunately, as @djhoese mentioned, this is not yet merged in main, let alone released. However, if you think you can dive in it, feel free to play with it! You can simply check out the branch in #2378, and look at the new instanced cube example I have there :)

@djhoese
Copy link
Member

djhoese commented Sep 29, 2022

I could have sworn we had an example of this but I can't find it. Can't you make a single MeshVisual with the vertices/faces for many separate "objects"? It might be annoying to construct those initial arrays, but shouldn't that work?

@brisvag
Copy link
Collaborator

brisvag commented Sep 30, 2022

Yes, that should work as well, but you either need to do everything in python to construct the mesh, or you need to use geometry shaders.

@djhoese
Copy link
Member

djhoese commented Sep 30, 2022

Right, that's what I meant. In python construct all the mesh vertices and create one MeshVisual representing multiple "objects" in the visualization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants