How to associate a shader variable to an specific object?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Remiam

Hi, sorry for reviving an old post.
There is a question that I seem to not find an answer.

How to associate the mask_texture variable to the object I want?

In my project, I can see the effect of the shader on the tilemap grid on which the material is applied, but I want to use another tilemap with plain white tile as the mask.
I can see that uniform sampler2D adds a shader_param but the drop down list doesn’t to provide an input for another tilemap from the tree.

So more precisely, how do I tell the shader that the mask_texture variable is the second tilemap?

EDIT:
https://forum.godotengine.org/5416/using-variables-from-gdscript-in-shader
I found out that I maybe could add the nodes from gdscript but it still doesn’t work.
I changed the variable in both and also tried to change it only on the parent node while the child got his material from his parent. Neither worked.

var Mat
func _ready():
	Mat = self.get_material()
	Mat.set_shader_param("mask_texture", self)
	Mat.set_shader_param("grid", $Grid)

You can only use textures as masks.
I get it now, what You are trying to do. You want only certain tiles to present some visual effect. Unfortunately tilemap node has no easy way to achieve this. If You need deeply animated tilemap, with various visual effects for every interaction, You should create your own tilemap using particles or multimesh.

But perhaps there is no need for this. What kind of visual effects do You need ? Are You sure You can’t achieve it using another overlaying tilemap ?

Inces | 2022-09-04 18:36

I’m trying to have a grid that contours only specific tiles. I manage to do it with a second tilemap with the grid showing on specific cells from the second tilemap but the png are not as crisp as the draw_line.
The player can grab tiles and move them (I swap them with an instance lerping to mouse) the grid serve to indicate where the player can put a tile so it snaps back to the other tiles when the player drops it.

Remiam | 2022-09-04 18:42

The exact name is alpha-compositing A in B, I saw that Godot 4 alpha has some similar masking in the work but I only saw A out B.
Alpha compositing - Wikipedia

Remiam | 2022-09-05 14:05

png are not as crisp as the draw_line.

Do You mean You only want to contour border of selected tiles ? I would try to achieve this with autotiles of second tilemap. Mark empty tile as a middle one, and surrounding it, tiles with a single line drawn at the corresponding side of a square. So You will only need 5 pngs for whole “indicator” tilemap.

Inces | 2022-09-05 14:43

Yes, if I understood you well I think that was my first attempt, I had a main tilemap and the second was overlay with a transparent png grid, it worked, but I didn’t like the aspect of png, it flickers, even with gpu pixel snap on. But I think I will go with it if I can’t do the same with draw_line and a “A in B” mask.
I made my own system that detects the surrounding empty cells to a plain cell. Every time a cell is set it detects its neighbor and sets them as such. My atlas is very small so I avoided autotile because the bitmask smallest size (that now I think I can work around by making my atlas bigger), should I give it a try instead of my own system?
Is it possible to do the same with autotile?
Here the in-game usual tile for a single cell:
Screenshot-2022-09-05-125537 hosted at ImgBB — ImgBB
Then this is a swap with my debug tileset where the empty neighboring cells are colored in red (where the grid appears) and the second layer of empty neighbors in black to detect when to hide the grid as the player mouse crosses over it.
Screenshot-2022-09-05-125617 hosted at ImgBB — ImgBB
This is when a rigidbidy instance collapse with the tilmap and is replaced by a cell in the tilemap, the red cells reforms around the new cell:
Screenshot-2022-09-05-125917 hosted at ImgBB — ImgBB
This is the not so crispy png grid that works(it is a second tilemap appearing where the red debug cell are):
Screenshot-2022-09-05-132355 hosted at ImgBB — ImgBB
And this is the crisp draw_line grid, a previous system I made that do not deform where the red debug cells are:
Screenshot-2022-09-05-133027 hosted at ImgBB — ImgBB

Remiam | 2022-09-05 17:31

:bust_in_silhouette: Reply From: Inces

Ok, I kind of understand what You are going for… kind of :slight_smile:
But can You post a picture in any graphic program how do You want this indication contour to look correctly ?

You said You tried to use transparent tilemap overlay, but it caused visual flicker.
Why don’t You use non-transparent total overlay ? Just a png of coloured contour, simple outline, and nothing ( no alpha ) in the inside. If You overlay this tile on your original tile, You will get the effect of outlined original tile. You just have to keep second tilemap below original one in scene tree hierarchy, so second tilemap will be drawn with priority

Oh I see what you mean. I’ll give it a try and come back. Thanks!

Remiam | 2022-09-05 19:34

Ok well the problem is that I need most of the neighboring tiles, if I use them to show a png line they will take the place of the neighboring cells which also need their own grid. I think I will go with my old flickering png with a light_only.

Remiam | 2022-09-06 00:55

I still can’t imagine this. If You use the same cell/png size for 1st tilemap and 2nd tilemap, they shouldn’t take place of neighbouring tiles.

Inces | 2022-09-06 16:37

The png line you propose would need to be placed on a cell that also needs a grid.

Remiam | 2022-09-06 17:24

tile of a first tilemap is a coloured square of certain size, as You showed in hyperlinks. Like this :

#####
#####
#####

tile of a second tilemap can be empty sqiuare, coloured only on the sides, like this :

    @@@@@
    @   @
    @   @
    @@@@@

So when You overlay 2nd over 1st You should get :

@@@@@@
@####@
@####@
@@@@@@

which is outlined tile 1

Inces | 2022-09-06 19:45

I hope to understand what you say, maybe you could really help me. I’m sorry for being persistent. What I’m doing is this:

@@@@@@@@@@@@@@@@
@    @    @    @
@    @    @    @
@@@@@@@@@@@@@@@@
@    @####@    @
@    @####@    @
@@@@@@@@@@@@@@@@
@    @    @    @
@    @    @    @
@@@@@@@@@@@@@@@@

In case that what you propose implies putting a different grid on each of the main cells, I also want to avoid instantiating or making too many nodes for performance purposes.

Remiam | 2022-09-06 20:01

no, not different grid.
You use cells of one tilemap node. I propose to use cells of another tilemap node. So 2 nodes in total, this is no performance problem at all. You use set_cell method to mark some cells red when rigid body collides with them, and get_cell to recognize neighbouring tiles. You can do the same with cells of 2nd tilemap - getting cell of where mouse is hovering over, getting surrounding tiles in x range from there, and setting all of these tiles as indication color tiles. You can have multiple colors of indication as multiple cells of one tilemap. The main difference between two tilemaps is that one is always drawn above the other. This can’t be achieved by one tilemap, because real tiles and indication tiles would replace each other when setting, while with 2 tilemaps, they exist at the same time.

From what You showed in this example above, I understand that outline grid is a main state of project, and color filled suqare in the middle is the indication we are talking about ? This should work as well within my example. You can also make pngs for tiles larger than their cell_size, so they will stand out more visually

Inces | 2022-09-06 20:49

Ok, that is what I’m already doing, except that my second tilemap with the grid is a white square with transparency within it. The black square in my picture is not my focus, only the white grid. The color are my debug tiles, it is the same tilemap but I swap the atlas when I press my debug key. The red squares are transparent on my non-debug main atlas. I have a second tilemap over it taking the same set_cell modification as the main tilemap but instead of the red debug squares the tileset is an empty square (pgn of a square with transparency).
I could use this white square tilemap whitout using transparency, by only drawing the squares on tiny tiny cells, is that what you mean?

Remiam | 2022-09-06 21:21

:bust_in_silhouette: Reply From: Remiam

This is the answer to the main question of this thread.
https://forum.godotengine.org/5416/using-variables-from-gdscript-in-shader