+3 votes

I'm looking for method to create outline or glow around 3d objects. I was trying to achive this effect using shader with "grow" value but it's very tricky and bugy. The best way for me will be render indyvidual objects to 2d texture and project outline on top of 3d image... but how to do that, or maybe ther is better method?

asked Jun 23, 2018 in Engine by websterek (229 points)
edited Jun 23, 2018 by websterek

or another idea, there is possible to make something like grow but with connected vertexes? Something like extrude of geometry along normals

When you say glow, do you mean like a fading effect coming off of the mesh?

Yes, something like on screen below. It's for indicating selected object on the level.

enter image description here

1 Answer

+2 votes

Ok I might have a solution. But I haven't really test it yet though so correct me if I'm wrong.

  1. Make an outline mesh. There's a button for that when you select a MeshInstance.
  2. Give the outline mesh a new custom ShaderMaterial.
  3. Make the shader unshaded.
  4. Inside the fragment shader, set the ALBEDO to a uniform called outline_colour. Of course this implies that you need to define this uniform first. Give it hint_colour.
  5. Also inside said shader, you must set ALPHA to dot(NORMAL, vec3(0,0,1))*outline_strength. outline_strength is how bright the outline is. Setting this uniform to 0 pretty much removes the outline.
answered Jun 24, 2018 by SIsilicon (3,796 points)

I'm not sure how this would work when the object is obscured by something.

I'm still at beggining to understand shaders in Godot. COuld you help me with writing this one?

I don't kown how should it works and how to set vec4 for albedo :(

shader_type spatial;
render_mode unshaded;

void fragment() {
    ALBEDO = vec3(1, 1, 0);
    ALPHA = dot(NORMAL, vec3(0,0,1))*1.0;

The shader looks alright to me. Except you don't have the uniforms set up. The uniforms are there so you can change the values outside of the shader.

shader_type spatial;
render_mode unshaded;

uniform vec4 outline_color: hint_color;
uniform float outline_strength = 1.0;

void fragment() {
    ALBEDO = outline_color.rgb;
    ALPHA = dot(NORMAL, vec3(0,0,1)) * outline_strength;

I suggest you read about Godot shaders in the Godot docs.

Edit: And I also think this method may not work for meshes with sharp edges(cubes, cylinders, etc..).

Sadly it's not solution what I'm looking for. But probably in godot 3.1 will be option for rendering such effects. I can wait for it, my production is still in early stage :)

Thanks for help!

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.