Skip to content

Instantly share code, notes, and snippets.

@xoppa
Created October 12, 2015 20:42
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xoppa/33589b7d5805205f8f08 to your computer and use it in GitHub Desktop.
Save xoppa/33589b7d5805205f8f08 to your computer and use it in GitHub Desktop.
very basic outline shader
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
const float offset = 1.0 / 128.0;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main()
{
vec4 col = texture2D(u_texture, v_texCoords);
if (col.a > 0.5)
gl_FragColor = col;
else {
float a = texture2D(u_texture, vec2(v_texCoords.x + offset, v_texCoords.y)).a +
texture2D(u_texture, vec2(v_texCoords.x, v_texCoords.y - offset)).a +
texture2D(u_texture, vec2(v_texCoords.x - offset, v_texCoords.y)).a +
texture2D(u_texture, vec2(v_texCoords.x, v_texCoords.y + offset)).a;
if (col.a < 1.0 && a > 0.0)
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.8);
else
gl_FragColor = col;
}
}
attribute vec4 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec2 v_texCoords;
void main()
{
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
@powertomato
Copy link

Well, I'm using this in Spatial shader type so will this work with SCREEN_TEXTURES?

I never did anything 3D with godot but in theory, a shader like this could work, but would need to render to texture/canvas first so that you have the objects that you want an outline on isolated in that canvas, apply the shader to that canvas and then render that texture to the screen

@sairam4123
Copy link

Oh I'm bit confused now, I think someone could help me here.

@powertomato
Copy link

Oh I'm bit confused now, I think someone could help me here.

outline_shader
This is a visiual illustration on how this shader works:

  1. First we get which pixels in the texture are transparent (black)
  2. We offset that to 4 directions: up (yellow), down (green), left (blue), right (red), in code that's the texture lookpus of the alpha channel e.g. texture(TEXTURE, UV + vec2( w, 0.0)).a
  3. We combine those, that's why we sum up all the lookups
  4. If the combination of those is above a certain threshold and the original texture is transparent on that position, we draw the outline color instead we draw the color from the original texture

In order to make the shader work in a 3D environment, you first need to render the objects that you want to have outlined into a texture, then render that texture onto the screen using the above shader.

Without detailed information about what you're trying to achieve and what your starting situation is, there is a lot of guesswork. So I suggest you ask your question in a forum where you can detail about the problem you're having.

@xijniN
Copy link

xijniN commented Oct 7, 2023

I adapted it to gamemaker :D

varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform float u_size;
uniform vec4 u_col; 

void main()
{
	vec4 col = texture2D(gm_BaseTexture, v_vTexcoord);
	if (col.a > 0.5)
	{
		gl_FragColor = col;
	}
	else 
	{
		float a = texture2D(gm_BaseTexture, vec2(v_vTexcoord.x + u_size, v_vTexcoord.y)).a +
			texture2D(gm_BaseTexture, vec2(v_vTexcoord.x, v_vTexcoord.y - u_size)).a +
			texture2D(gm_BaseTexture, vec2(v_vTexcoord.x - u_size, v_vTexcoord.y)).a +
			texture2D(gm_BaseTexture, vec2(v_vTexcoord.x, v_vTexcoord.y + u_size)).a;
		if (col.a < 1.0 && a > 0.0)
		{
			gl_FragColor = u_col;
		}
		else
		{
			gl_FragColor = col;
		}
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment