Writing dynamically inside texture : Fastest alternative to SetPixel ?

DurzannDurzann Posts: 4Member

Hi there,

I'm actually working on a cellular automata and one of my constraint is to keep the logic on the CPU side,

I already displaying the actual state of my process under an ImageTexture with the SetPixel method but it's extremely slow and i will face huge frame drops when i will look for displaying multiple type of data on the same screen, is there fast way for displaying a 2D grid data on screen with Godot ?

Thx


Tags :

Comments

  • TwistedTwiglegTwistedTwigleg Posts: 2,127Admin
    edited February 24

    You might be able to use a Viewport to render the texture, and then use Node2D nodes with custom _draw functions to set pixels within the visible area of the Viewport. I'm not sure if it would be faster than using SetPixel, but it might be worth looking into.

    Also, welcome to the forums! :smile:

  • DurzannDurzann Posts: 4Member

    Hi, thanks for the answer, i'm glad to discover the godot community :)

    Indeed, i see many answer pointed out the viewport drawing system
    But what do you want to say by "setting the pixel within the visible area of the ViewPort" ?
    I tried to drawCircle/Line per cell of my data, but it's actually monstrously heavier than the SetPixel method : Did I just miss something with your idea ?

  • TwistedTwiglegTwistedTwigleg Posts: 2,127Admin

    @Durzann said:
    Hi, thanks for the answer, i'm glad to discover the godot community :)

    Indeed, i see many answer pointed out the viewport drawing system
    But what do you want to say by "setting the pixel within the visible area of the ViewPort" ?
    I tried to drawCircle/Line per cell of my data, but it's actually monstrously heavier than the SetPixel method : Did I just miss something with your idea ?

    I was thinking of draw_rect with rectangles of 1x1 size, but yeah, using the draw_ functions in CanvasItem was what I was thinking. I did not know the draw_ functions are heavier than using set_pixel, but thinking about it, at the individual pixel level (or even slightly above) it makes sense that it wouldn't perform as well since it would require an OpenGL draw call for each function used.

    Maybe to improve performance, you could draw regions that have the same pixel color together with larger rectangles in the draw_rect function? Or drawing lines of same colored pixels with draw_line? I'm not sure how feasible it would be, nor if the extra processing to find areas of the same color would negate any performance benefits, but that might be something to look into.

    Another thing I was thinking of while writing this is you might be a C# or C++ library (through GDNative) to manipulate an image saved on the user's computer, and then have Godot load the image when you make modifications. It likely wouldn't be any faster, but it is possible that by bypassing Godot and using an external library, you can modify the pixels faster.

    Outside of that, I do not know right off. I'll keep an eye out for other solutions though and will post if I come across anything.

  • panicqpanicq Posts: 31Member

    Hi, I tested using GDNative C++ Binding and without VSync it reaches 65 fps on my machine. My test is using a 512x512 image and for each pixel I'm setting a random color in the _process method. With a 1024 the framerate drops to 15. I'm now waiting for compute shaders to become available in Godot, hopefully in version 4.0 :D

  • MegalomaniakMegalomaniak Posts: 2,028Admin

    Yes, 4.0 should have them for the Vulkan renderer, but I doubt we'll see them in the gles 2 renderer, unless it'll be done on cpu, which would be far from ideal. So probably not.

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file