Useful trick

I want to share a useful trick with you.

When I write a new user interface, which I seem to do all the time, it’s an addiction, I usually start with hunting around for good textures. Taking ideas from anywhere.

When I finally do find something I like, then it’s generating a texture, cutting them up into regions, writing code to draw at any scale, blah blah blah

Well I am sick of that.

So in my latest UI I decided to do everything with shaders.

All my blits apart from the text use the same shader.

In the pixel shader I use the texture coordinates to fake a surface normal, then light it with two lightts.

The result is pretty good, and works at any resolution.

You can theme it by specifying colours instead of having to generate new textures

It’s resolution independent.

The central part of the shader is really simple

float4 MainPS(VertexShaderOutput input) : COLOR
{
float4 outcolor = input.Colour;

float3 N = normalize(float3(input.UV, 1));
float3 L = normalize(LightDirection);
float3 L2 = normalize(LightDirection2);
float NdotL = max(dot(N, L), 0);
float NdotL2 = pow(max(dot(N, L2), 0), 32);

outcolor = saturate(outcolor + (NdotL *  float4(1, 1, 0.7, 1)));
outcolor = saturate(outcolor + (NdotL2 *  float4(1, 1, 1, 1)));

float onex = 1.0 / input.Region.z;
float oney = 1.0 / input.Region.w;

float edge = 0;
if (input.UV.x < (2 * onex))
	edge = 1;

if (input.UV.y > 1.0 - (2 * onex))
	edge = 1;

float edge2 = 0;
if (input.UV.x > 1 - (2 * onex))
	edge2 = 1;

if (input.UV.y < (2 * onex))
	edge2 = 1;

outcolor = lerp(outcolor, HiLite, edge2);
outcolor = lerp(outcolor, float4(0, 0, 0, 1), edge);

return outcolor;
}

This is just the start of what can be done with this idea. I added a third light and animated it. Didn’t like it but it may be something one of you wanted to do.

You can build in a fade value, anything you want.

Just an idea to get you guys thinking

3 Likes