Game Development

Blog 690: Shaders At Night

Shaders are some whacked out shit. On the other hand, they are responsible for actually making your game look like… whatever it’s meant to look like. So they’re kind of important. Which means, yes, I must learn them. Somehow.

I’m not daft, though. Why learn something weird and strange when you get buy yourself a handy tool to do all the hard work?

Shaders At Night

It never used to be this complicated. In Unreal Tournament, you just imported a texture and slapped it over stuff. It was like infinite virtual wallpapering, no hassle at all.

Funnily enough, Warcraft III actually had some very flexible options for painting things — you could layer many textures on top of each other, blending them in funny ways. My favourite effect was putting an “unshaded” additive mask on top of a texture to create areas like glowing headlamps — I used this all over my mechs in Project Y4. A subtle effect that produced rather nice bright spots when you dimmed the lights.

So it was with some surprise that I discovered the world of Unity was apparently less flexible than Warcraft III. The glorious bright future of stand-alone games, built on technology more than ten years in advance, and it couldn’t do material layers? Pah!

Needless to say, I was just looking in the wrong place.

I bag Warcraft III a lot but there were some real technical gems scattered around under the bonnet.
I bag Warcraft III a lot but there were some real technical gems scattered around under the bonnet.

Unity comes with a whole load of built-in shaders. You plug your textures into them, apply them to objects, they spit them out onto the screen with the effects you want. Kind of.

Because, well, when you’re a man of odd tastes and skewed understanding like me, what Unity provides out of the box isn’t quite right. Say I want specular highlights to make my “metal” (shut up) textures look a bit more metallic, but I don’t want to sacrifice those glowing lamps either — alas, Unity’s built-in shaders generally force you to pick one effect or the other. Don’t even think about getting transparency for fading out on top of that, either.

Then the world of Physically-Based Rendering came along, and all those shaders I was using got migrated into the Legacy folder. Oh dear oh dear.

(I like the idea of Physically-Based Rendering, that you throw shit together and it Just Works, doing all the magical stuff for you. The problem is that I’m using late-90s workflows to produce late-90s assets, so that plus my weak understanding of actual physics means I just can’t produce sensible results with PBR. No dice, Unity, I’m sticking to the old way.)

"Legacy" means "good", right? Experienced. Battle-hardened.
“Legacy” means “good”, right? Experienced. Battle-hardened.

So I was always going to end up having to build my own shaders.

The thing is, though, that the shader programming language is extremely esoteric, and after plenty of fumbling around with tutorials for ultra-beginners I was getting nowhere. I couldn’t understand what it was doing and how the pieces fitted together on the most basic “just paint this texture” shader, let alone think about turning that into the multi-layered blending masterpiece I want for my game.

No, I needed something to stand between me and the bare metal. A shiny node-base visual editor that could map my imperfect understanding to some kind of functional reality. I’ve had good results with hacking around in node-based editors before (“good” is relative), so it’s only natural to want more of that.

Enter ShaderForge, a shiny node-based visual editor for shaders. How convenient!

Which shaders are the Legacy ones and which ones are my new ones? You can't even tell!
Which shaders are the Legacy ones and which ones are my new ones? You can’t even tell!

After about four hours of fiddling, I basically have the ultra-shader that I always wanted.

Hell, it’s even better than what I was initially planning for. Probably not the most efficient way to deal with all these things from a performance perspective, but I figure I’ll be giving the graphics card an easy time of it in other ways so I’ve got room to spare.

The basic features went in very easily:

  • Specular highlights, to make shiny things look shiny. It’s a graphical step up from my usual levels but I’m not completely from the dark ages.
  • Emissive highlights, to make those glowing lamps. It uses a distinct mask texture so I can turn differnet lamps on and off without a hundred variations of each base texture.

Then came the fun stuff.

  • Camouflage layer, for colour scheming. This is the best bit — ShaderForge has the nodes to replicate the same layer blending I’d use in Paint Shop Pro 7 to create camouflage textures. Now, instead of doing that manually to create loads of static texture variations, I can do it all in-game with all the ease and flexibility that brings.
  • Wreckage layer, for broken objects. Again, another layer that had to be manually saved as yet another static variation — it just blackens stuff a bit so it’s not doing dynamic bullet-holes or anything, but this has so far done the job well enough and now I don’t have to re-export it every time I change the base.
  • Alpha clipping, for wreckage decaying. I am of the mind that nothing should appear or disappear instantaneously in games; everything must be smoothly transitioned or hidden behind something else. In order to make decayed bits of wreckage fade out, I used to have to swap materials again to a transparent version. Not anymore: this alpha clipping mode makes the object appear to get “eaten away”, giving that smooth transition without all the pain of transparency and juggling different materials.
It looks so simple from up here, but you should see the shader code it generates.
It looks so simple from up here, but you should see the shader code it generates.

All in all, then, a resounding success. ShaderForge has short-circuited all the insanity and given me quickly and painlessly the things I need. Hell, it’s given me more than I need — the wreckage overlay wasn’t something on my mind at all, and I never even considered being able to turn the lamps on and off either.

Then think of the other possibilities that are now open. Maybe I could add an icy overlay that can be turned on to allow characters to become frozen, and maybe a glowing red overlay for overheating in pools of lava… Mmmmmmmmmmm.

Thank you, sweet ShaderForge. The future is finally arriving.

And you tell me...

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.