3D Outline Shader

Hello, I’m trying to add some outline effect for 3d objects and it looks Im stucked :frowning_face:

What I have tried:

var outlineShader = new h3d.shader.Outline();
outlineShader.size = 0;
outlineShader.distance = 1;
outlineShader.color = new Vector(1, 1, 0);

instance.getMaterials()[0].mainPass.addShader(outlineShader);

The result is:
image

With outlineShader.size = 1:
image

And what I want to reach:
image

Any idea / hint? Maybe It should be handled in a totally different way - I’m not so experienced with 3D :confused:

Finally I found a solution while I checked the source code of Hide, maybe it will be useful for someone:

1, You need a custom renderer like hide.Renderer.hx (You can clean it, you need just the DefaultForwardComposite ScreenShader and the Renderer class)

2, Use this renderer like:
s3d.renderer = new levelup.core.renderer.Renderer();

3, Enable highlight pass on your object

var shader = new h3d.shader.FixedColor(0xffffff);
for (m in materials)
{
	var p = m.allocPass("highlight");
	p.culling = None;
	p.depthWrite = false;
	p.addShader(shader);
}

4, You can modify this effect easily, outlineBlur size is the size of the outline, the color is based on the FixedColor shader. If you want an exact color you can modify DefaultForwardComposite like this (But in this case you will loose the gradient effect):

class DefaultForwardComposite extends h3d.shader.ScreenShader
{
	static var SRC = {
		@param var texture:Sampler2D;
		@param var outline:Sampler2D;
		@param var color:Vec4;

		function fragment()
		{
			pixelColor = texture.get(calculatedUV);
			var outval = outline.get(calculatedUV).rgba;
			if (outval.a < 0.4 && outval.a > 0)
			{
				pixelColor.rgba = color;
			}
		}
	}

	public function new(v = 0)
	{
		super();
		color.setColor(v);
	}
}

image
image
image

2 Likes

Wow thanks so much for posting the clean instructions, you just saved me a lot of time :smiley: