Hello.
I am making a simple 3D bechmark mini tool to test godot's capabilities of 3D primitive rendering. It has 3 parameters 'x, y, z' to generate 2002004=1600000 or 1600k nodes with 3D model, I made 3 slider to adjust the x, y,z values respectively, it will disable a portion of 1600k nodes when you lower the slider value, and it will enable a portion of 1600k if you upper it. But it seems iterating through them and setting the visibility of each node is pretty laggy.
So I wonder if there is a better way to toggle large amount of node visibility optimally, like disabling/enabling a group of nodes or nodes in range between 2 values.

Project is here:
https://godotforums.org/d/37426-godot-simple-benchmark-project-3d

Thanks.

  • xyz replied to this.

    You could also try interfacing directly with RenderingServer rather than having a bunch of nodes. I'd try call_group_flags and using threads first though.

    • xyz replied to this.

      award Using the server wouldn't benchmark the nodes though. But TBH I don't see much point in doing this. Having so many draw calls will surely be slow. If those nodes are used for drawing the same thing then instanced rendering should be used instead.

      What are we actually benchmarking here @MagickPanda and for what purpose?

        hmm thanks for tips.

        The mini tool is inspired by the bunny mark tool duane posted, I even stole the fps part of code from bunny mark -_-

        The idea is to test how many shaded primitive triangles Godot could handle before the fps become unacceptably low.

        I will try to scratch together a project zip asap, so you could see how it works and maybe find the bottleneck of the chaotic codes I rushed.

        xyz

        • xyz replied to this.

          MagickPanda If you benchmark triangles then they should be all in the same draw call i.e. inside same mesh instance or multi mesh. There's a massive overhead per each rendered node, on both gpu and cpu side. In the total time measured this way, the actual triangle rendering will have a minor part.

            xyz
            I tested with both vulkan and opengl(gl compatible).
            It seems the vullan render did a pretty good job at merging DC's, it only has 14 DC with 160k models. But with opengl rendeter, the DC jumped to 14k with 160k, resulting approximately only 10-20% perfomance of vulkan's.

            P.S: I uploaded project here:
            https://godotforums.org/d/37426-godot-simple-benchmark-project-3d

            • xyz replied to this.

              MagickPanda Maybe try to compare it with a single MultimeshInstance3D node having 160k instances.

                xyz hmm never tried meshinstance3d, will update my pool to use it to see if it boosts performance significantly.

                • xyz replied to this.

                  MagickPanda You should definitely do it with instancing. The problem with you benchmark setup is that something similar will unlikely appear in an actual project. If a lot of same things need to be rendered then instancing is pretty much the only reasonable approach. If on the other hand objects are mostly different then there will be no eventual driver optimizations. So you should comparatively benchmark one vs the other. Those are the situations that will most likely occur in the real world.

                  MagickPanda It seems the vullan render did a pretty good job at merging DC's, it only has 14 DC with 160k models. But with opengl rendeter, the DC jumped to 14k with 160k, resulting approximately only 10-20% perfomance of vulkan's.

                  How did you determine the number of draw calls?

                    xyz The draw call can be obtained from godot's build in profiler, under monitor tab, there is a treeview containing effective primitive count and drawcalls.