Creating Dynamic Images

Godot Version

4.2

Question

Why won’t images created at runtime work when passed as shader parameters?

Here’s a chunk of my code:


    palette_image   = Image.create(palette_texture_size.x, palette_texture_size.y, false, Image.FORMAT_RGBA8)
    #palette_image   = Image.load_from_file("res://system/image/image.png")
    palette_texture = ImageTexture.create_from_image(palette_image)
    var png_palette = preload("res://system/image/palette.png")
    var png_image   = png_palette.get_image()
    for x in palette_texture_size.x:
        for y in palette_texture_size.y:
            set_palette_RGB(Vector2(x,y), png_image.get_pixel(x,y))
    palette_image.save_png("res://system/image/image.png")
    renderer.material.set_shader_parameter("palette_texture", palette_texture)

This code works on the SECOND run after uncommenting the second line. Why?
the texture created by Image.create() doesn’t work in my shader (shows black), but it definitely initializes to copy png_palette into itself and save to the file system. On the second run, it runs just fine by loading the version of itself it saved out last time - the image is displayed by the shader on the second run. So, why is “Image.create()” defective and how do I actually create images at runtime?

Im no expert in shaders but look around to see if you can cache it on runtime

You need to call ImageTexture.update() to update the texture’s Image after you have done your modifications

    palette_image   = Image.create(palette_texture_size.x, palette_texture_size.y, false, Image.FORMAT_RGBA8)
    #palette_image   = Image.load_from_file("res://system/image/image.png")
    palette_texture = ImageTexture.create_from_image(palette_image)
    var png_palette = preload("res://system/image/palette.png")
    var png_image   = png_palette.get_image()
    for x in palette_texture_size.x:
        for y in palette_texture_size.y:
            set_palette_RGB(Vector2(x,y), png_image.get_pixel(x,y))
    palette_texture.update(palette_image) # Update the Image
    renderer.material.set_shader_parameter("palette_texture", palette_texture)

Also, don’t use the res:// folder to save anything. It will work in the editor but when exporting a project the res:// folder is read-only.