+1 vote

Using Godot 3.0-Beta1

For instance if you load a texture and attempt to use a texture method such as modulate you get an error.

    var c = load("res://Images/palette.png")
    c.modulate = Color(255, 0, 0)

This reports:

Invalid set index 'modulate' (on base: 'StreamTexture').

Is there a way to convert a StreamTexture to a texture in gdscript?

in Engine by (55 points)

1 Answer

–1 vote
Best answer

You cannot modulate an image nor a texture because these objects do not draw by themselves.

Apply it to a node that draws on screen and modulate that object.

by (7,818 points)
selected by

Hmm, the difficulty is that I'm using the images loaded to create a dynamic tileset. I wanted to make different colors of the tiles for selection by the user to put into their own tilemap. Basically like a paint program. A user can select a color from a palette. The colors are generated via gdscript and placed on a tilemap for selection. My problem is then, how do I change the color of individual tiles?

That feature may imply the creation of a new tile on the tileset for each chosen color, you can do that (add tiles to the tileset resource) and set the modulation for the new tiles.

Each tile can have modulation apart from the tilemap one.

Each tile can have a modulation apart from the tilemap one

That would be ideal but I'm still struggling on how to do that as I can't modulate the tileset or the tiles. Well, at least I haven't figured out how to modulate them.

palette_ts = TileSet.new()
var c = preload("res://Images/palette.png")

$BG/PaletteArea/Palette.tile_set = palette_ts
palette_ts.tile_set_texture(0, c)
$BG/PaletteArea/Palette.set_cell(0, 0, 0)

You can not modulate the "c" variable as it is a StreamTexture. Palette in this example is a TileMap. I can set the cell but how would I modulate the color after the texture is set?

try with pallete_ts.set(str(tile_number,"/modulate"), mod_color) or get("tile_number").modulate (since is a reference, may work if the get works).

I also completely forgot that you can set materials for individual cells (on godot 2 too), maybe creating materials with a common modulate shader instead and changing parameters can work.

That worked. A quick test made the tile red.

palette_ts.set("0/modulate", Color(255, 0, 0))

FYI, Using palettets.get("0") returns Nil so I can't test that one. I also realized I didn't actually call tileset_texture so I added that as well.

Current code:

    palette_ts = TileSet.new()
    var c = preload("res://Images/palette.png")
    palette_ts.tile_set_texture(0, c)
    $BG/PaletteArea/Palette.tile_set = palette_ts
    palette_ts.set("0/modulate", Color(255, 0, 0))
#   palette_ts.get("0").modulate = Color(255, 0, 0, 0)
    $BG/PaletteArea/Palette.set_cell(0, 0, 0)

I didn't try the material route. I'm guessing this would be over kill as you would need to make a custom shader for each tile, no? I barely understand shaders so maybe I it would be better to use the material shader instead? If I understand that method, I would do something like:

shader_type canvas_item;
uniform vec4 col : hint_color;
void fragment() {
  COLOR = col;

Recommendations? What's best, to modulate each color you want or to create a shader and do it that way?

Not sure the material but he shader code should be possible to share with all tiles.

Make an uniform color to set it, then to modulate can use any color operation available for the effect you want (mix, or just +).

Shaders are quick and the effect should be the same, these give you other options like for making color palettes.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.