Tuesday 4 September 2012

Vertex Shader Outlines

During the development process I needed to have a way to mark an item/enemy with a border. Initially I wanted every 3D object on the scene to have such a glowing border, then decided to give the border to specific objects only when a special ability was in effect (e.g. temporary invulnerability).

My way of achieving this effect was to render whole model scaled up in the background, and then render the normal model. Standard scaling via scale matrix wouldn't work well in this case, so I had to write a vertex shader that would move every vertex of a mesh slightly along its Normal vector. This makes the model look like it's been inflated which is perfect for border/stroke effect. The important thing is to inflate the model after all transformations have been applied (move, rotation, scale, and bone transforms) which means that it needs to be done in world/scene space.

Here's the code for the Stroke Effect shaders.

struct VertexShaderInput
{
 float4 Position : POSITION0;
 float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
 float4 Position : POSITION0;
};



VertexShaderOutput VSShadowFunction(VertexShaderInput input)
{
 VertexShaderOutput output;
 float4 worldPosition = mul(input.Position, World);
 worldPosition += (normalize(mul(input.Normal, World)) * 0.02 );
 worldPosition.y = 0.05;
 float4 viewPosition = mul(worldPosition, View);
 output.Position = mul(viewPosition, Projection);
 return output;
}

float4 StrokeFunction(float2 TextureCoordinate : TEXCOORD0) : COLOR0
{
 float4 color = StrokeColor;

 return color;
}


And here is the final result.

No comments:

Post a Comment