Getting polygons from a specific color of a map texture

Godot Version

4.4.1

Question

Hi, I am planning to make a small grand strategy game on godot using Paradox colormap technique, like this one:
Imgur

Now I have a problem, generating Outline of the border so when I click on a random zone, the border of that zone will glow up.

I also look at this video make by Good Interactive Solution (https://www.youtube.com/watch?v=UtbU2fa4fMM&t=1s) but I wonder if there are any better solution than that, as it just loop over all pixels…(When i run the scene it just crashed)

Thanks in advance

I’d suggest doing a lot of the work before runtime.

You could preprocess this map and produce an indexed image (that is, each pixel is an index value) where the index in each pixel is which region it’s in. You could also make a data file containing an array of the regions along with useful info:

  • region name
  • a list of Vertex2D coordinates that define the vertices of the region’s polygon, which you could use to draw a line loop (for an outline), a translucent polygon (for a highlight), or whatever
  • region color
  • a list of adjacent regions, potentially useful for pathfinding or deciding what regions can be attacked directly from this one
  • terrain info, natural fortification, anything else…

With those, at runtime you could look a mouse click position up in the index map to get what region was selected, and then use that region’s info to highlight it, neighboring regions it can reach, and display whatever HUD info you want.

I would do like this:

  • Have unique colors for all countries
  • Get the pixel color from clicked position (I think you have this working allready?)
  • Pass that color to a shader and use it to brighten the country.

That’s pretty easy way to highlight, but if you want only the outlines to glow, it gets more tricky. I have some ideas:
I think looping trough the pixels to detect borders is a bit overkill. It would be much easier and faster to have another image that has the outlines allready drawn on it. Use the passed color value as a mask for the outline image. You can even use the map images alpha channel as the second image.

I tested my idea and it works.

map

No need for polygons or looping trough pixels. Just two images and a color value is used for choosing which image to draw.

Here’s the shader:

shader_type canvas_item;
render_mode blend_mix;

uniform vec3 highlight_color: source_color = vec3(0);
uniform sampler2D highlight_tex;

void fragment() {
	COLOR = texture(TEXTURE, UV);
	vec4 hl_tex = texture(highlight_tex, UV);;
	
	if(distance(highlight_color, COLOR.rgb) < 1.0 / 255.0)
		COLOR = hl_tex;
		
	COLOR.a = 1.0;
}

Does that mean I have to load the colormap into the environment?
If not, how can I implement the shader into the map?

my current environment conatains the map as staticbody3d, and no colormap layer in that node

I’m new to shader

I was using a TextureRect node (a 2d gui element), but you can use your MeshInstance3D just as well. It’s probably under your StaticBody3D.

Find the Material Override where you have your map texture allready. Convert the material to ShaderMaterial:

You will get a generated shader code that you can edit. Then copy paste stuff from my shader to yours. You need the two uniforms and the stuff from fragment function and replace COLOR with ALBEDO and COLOR.a with TRANSPARENCY.

But if your game is 2D, I recommend using a TextureRect or Sprite2D. You can convert Material to ShaderMaterial just like above, but then my shader can be copy-pasted without modifications.