1
\$\begingroup\$

this little freak, is roughly 1.3 meters tall so around 4.2 feet. In first person he is decently easy to spot but in third person he blends too easily with ground so even if he is only 4-5 meters away from you so 16-20 feet... it get's very hard keep eyes on him. and since it's "AI" is set to follow the player's back, it is very easy to not notice a goblin that is about to bonk your head from behind.

even when looking at him while he is wacking, slamming and swinging his stick around, his body is almost invisible and you see moslty just the stick.

so to prevent that, I came up with a simple idea , give the players an ability "concentrate" when players activate concentrate they walk slowly but all enemies within a certain distance are outlined.

so in godot.... how do you outline things?

enter image description here

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Outline Mesh

The closest to a build-in solution is to create an outline mesh. That is a mesh that is slightly larger but inverted (normals are the opposite way, so inside is outside and vice versa).

The main drawback of this approach is that the size of the outline is defined in 3D space (so the outline is also affected by perspective, and will look smaller the further away from the camera).


You can create an outline mesh from code by calling create_outline on the Mesh. Which will create a new Mesh, which then you would have to give to a MeshInstance.


Or you can do it from the editor:

  1. Select the MeshInstance
  2. Click the "Mesh" option in the toolbar
  3. Click "Create Outline Mesh..."
  4. Specify the margin (how much larger you want it to be).
  5. Click create.

It will create a new MeshInstance as a child of the original.


Either way, do not forget to set a material. And also, for the effect to work, you need the new MeshInstance to move the same way as the original.


Outline Shader

The other option is create a post-process shader... With the approach you can define your outline in pixels, so you don't have the perspective problem.

If you are going to target mobile, I'll advice you to not use this method, as the performance is much worse.

You can use the approach described in Custom post-processing, which have you render the scene to a secondary Viewport so you can use the resulting image as a Texture which is the input for your shader. This approach only gives you color... Getting other information might require rendering to other secondary Viewports while also overriding materials to get what you want.

Or you can use method described in Advanced post-processing that has you create a simple mesh (often a quad) to cover the screen. This approach gives you color in the SCREEN_TEXTURE, and depth in DEPTH_TEXTURE. Also it avoids secondary Viewports.

Either way you want to implement an Edge detection algorithm (e.g. filter/convolution/kernel).

In fact, you can find an example in the "Custom post-processing" article linked above... Which does this:

    vec3 col = -8.0 * texture(TEXTURE, UV).xyz;
    col += texture(TEXTURE, UV + vec2(0.0, SCREEN_PIXEL_SIZE.y)).xyz;
    col += texture(TEXTURE, UV + vec2(0.0, -SCREEN_PIXEL_SIZE.y)).xyz;
    col += texture(TEXTURE, UV + vec2(SCREEN_PIXEL_SIZE.x, 0.0)).xyz;
    col += texture(TEXTURE, UV + vec2(-SCREEN_PIXEL_SIZE.x, 0.0)).xyz;
    col += texture(TEXTURE, UV + SCREEN_PIXEL_SIZE.xy).xyz;
    col += texture(TEXTURE, UV - SCREEN_PIXEL_SIZE.xy).xyz;
    col += texture(TEXTURE, UV + vec2(-SCREEN_PIXEL_SIZE.x, SCREEN_PIXEL_SIZE.y)).xyz;
    col += texture(TEXTURE, UV + vec2(SCREEN_PIXEL_SIZE.x, -SCREEN_PIXEL_SIZE.y)).xyz;
    COLOR.xyz = col;

You might find more examples searching online. Be aware that they all require their specific setup to work (either extra Viewports or the quad that covers the screen, or something else). Also double check for which version of Godot they are for, as Godot 4 results are taking more and more prevalence.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .