So I got distracted by vertex and pixel shaders, and started playing with Microsoft’s HLSL. MS’s Effects framework turned out to be really handy, once I got my head around what the hell it was actually supposed to do. It manages your 3D card’s state for you – no more fiddling with FVFs, blending, or vertex shaders directly – instead, you just specify a pass, render an object, specify another pass, and so on.
I’ve had a couple of requests for code – I’m busy cleaning up the shader files, so you should see them soon. If anyone wants the C# code, email me. I’ll hopefully put it up eventually, but I’d like to clean it up first…
Here you can see my HLSL playground. The white frame can be dragged around and resized – it gives you a before-and-after effect of how the shader you’re working on compares to the default rendering. The head morphs randomly between different expressions.
This is a pretty trivial example – the surface is being offset by a sine wave moving through the head. This is pretty badly optimized – I have a few sines & cosines going on in there for each vertex every frame, which are extremely expensive in HLSL. I probably ought to be using a lower precision sin/cos. Code
It’s not very well behaved – depending the light conditions, in can easily get totally overblown and swamp the image with white, but can just as easily get so faint as to be invisible. Code
Natural Light Shader
It’s my attempt at natural light rendering – the sort of soft, global lighting conditions you get when outside in diffuse light. A glow is overlaid to soften the image – you can’t even see it, but it’s noticable when it’s missing…
Edges are detected by comparing the viewing direction with the surface normal, which we use to produce a texture coordinate. Custom-made mipmapped textures are used to control line width & give that rough handdrawn appearance to the lines.
I’m still working on the ‘watercolor’ shading – at the moment it’s just a blur effect on the original image.
Whole new world
So this is all well and good, but there’s only so much you can do with a single model. I started to look into means of loading entire scenes, and eventually came to the conclusion I’d have to come up with some sort of map file format and scene management. I could do my own format, but then I’d need to write map tools, come up with maps, and so on. So I hijacked the Quake3 format, which is reasonably well described here. Currently, my engine handles loading everything, calculating visibility sets, and curved surfaces. It doesn’t handle some of Quake3’s more complex texture effects, but I’m planning on writing my own shader tools anyway. That’s next on the list.
Commenting is closed for this article.