• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

Shaders Shader to create an outline around a primitive.

Coded Games

Member
So my game uses a lot of primitive shapes that are draw every frame because they animate and change shape constantly. This animation has been the main reason I have not used vertex buffers as it seems like I can't really resize a shape after creating the buffer.

A lot of these shapes have outlines, and to draw the outline I have been drawing the shapes twice, the first time black and slightly bigger, then the main shape. To me this seems like it is really slow. The more complex shapes in the game take up the vast majority of the runtime when drawing. So I am hoping that there is a way to optimize this by using shaders.



Here is an example of one of my primitives. The red shape and outline are drawn by creating two primitives with the draw_primitive_begin/draw_vertex functions. What I would like to do is just draw one primitive the way I currently am and then apply the outline with a shader. Does this seems like a smart way to do it?

Unfortunately, I know basically nothing about shaders. I watched Shawn Spalding's tutorial about making outline shaders and it does not appear to work. The fragment shader here does not appear to do anything:

GML:
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform float pixelH;
uniform float pixelW;

void main()
{
    vec2 offsetx;
    offset.x = pixelW;
   
    vec2 offsety;
    offset.y = pixelH;
   
    float alpha = texture2D(gm_BaseTexture, v_vTexcoord ).a;
   
    alpha = max(alpha, texture2D(gm_BaseTexture, v_vTexcoord + offsetx).a);
    alpha = max(alpha, texture2D(gm_BaseTexture, v_vTexcoord - offsetx).a);
    alpha = max(alpha, texture2D(gm_BaseTexture, v_vTexcoord + offsety).a);
    alpha = max(alpha, texture2D(gm_BaseTexture, v_vTexcoord - offsety).a);
   
    gl_FragColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
    gl_FragColor.a = alpha;
}
I figured this would happen as drawing these primitives doesn't really have a texture so a fragment shader does nothing. It seems like what I really would need is a vertex shader, but this is where I am lost. This seems like it should be a really simple thing, but I don't know where to go from here. Any help would be really appreciated!
 

angelwire

Member
One thing you can try is drawing all the shapes that need outlined to a transparent surface, and then drawing that surface with an outline shader. The downside to this would be that when individual objects overlap the outline wouldn't separate them.

There is another I can think of way using vertex buffers and custom formats if you're interested in learning those, but it's more complicated to implement and the surface idea would probably be better if it works for you.
 
Top