[3.0x] Loading an image creates a StreamTexture. Need Texture methods...

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By zombieCraig
:warning: Old Version Published before Godot 3 was released.

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?

:bust_in_silhouette: Reply From: eons

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.

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?

zombieCraig | 2017-12-24 02:50

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.

eons | 2017-12-24 16:59

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()
palette_ts.create_tile(0)
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?

zombieCraig | 2017-12-29 21:17

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.

eons | 2017-12-31 14:44

That worked. A quick test made the tile red.

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

FYI, Using palette_ts.get(“0”) returns Nil so I can’t test that one. I also realized I didn’t actually call tile_set_texture so I added that as well.

Current code:

	palette_ts = TileSet.new()
	palette_ts.create_tile(0)
	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?

zombieCraig | 2018-01-02 01:16

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.

eons | 2018-01-02 09:29