HowTo:IntroToShaders
Contents
Introduction to Shaders, and what they mean to the modelling and texturing pipeline
I'm going to expand on this and write a whole bunch of wiki how-to's; this is a first overview. As of this writing, the default shaders aren't finalized yet, and the changes that are coming affect the way the textures need to be packed.
However, you CAN start working on bumpmaps and normalmaps (and shininess maps) right now, if you want. There will be off-line tools provided to convert texture packs from the current set, namely...
* Diffuse texture * Specular texture * Glow texture * Damage texture, plus the new * Normal map * Shininess map (the current shader expecting it in the alpha channel of the specular texture)
...to the most likely new packing arrangement of:
* Texture 0: Diffuse texture (plus normalmap dU in alpha) * Texture 1: Specular texture (plus shininess in alpha) * Texture 2: Glow texture (plus ambient occlusion in alpha) * Texture 3: Damage texture (plus normalmap dV in alpha)
In fact, there may be several such tools, for variations in types and numbers of input textures. And I have a prototype of one such tool, the "nodulizer":
The nodulizer is really a Blender3D .blend file. You throw it into a folder where you want to convert a set of textures, rename the textures to what the nodulizer expects, or else edit the input nodes for them (on the left), adjust the scaling factor with that input node at the bottom left corner, and press the Use Nodes button in the menu bar below. The scaling factor is there in case you have large (2k by 2k or 4k x 4k originals, and want to produce 1k outputs; otherwise make the scaling factor 1.0. Needless to say, you need to have Blender installed, then you can just double- -click on nodulizer.blend.
You can download the nodulizer beta here: nodulizer.7z Just don't use it yet; the shader that uses this packing is still in the works; but you can play with it, see what it does.
There may also be a command line tool to do the same thing; not decided yet, but the advantage of using Blender's "nodes" and "noodles" is that the tool can be easily customized, specialized, tweaked, expanded... So, IF there may be a command line version, it will probably only be provided for a default repacking, for those who can't use Blender due to their religion :D
But, getting back to basics, the question most often asked: what's the difference between bump- and normalmaps?
Bump map
A bump map is a gray scale image where the brightness represents height above the surface, and darkness represents depth. 50% gray means at surface level.
The problem with bumpmaps is they take a lot of processing in the gpu (videocard) to be really good to use; and that they are quintessentially non-mipmap-able. So normalmaps soon took over.
Normalmaps:
Normal maps encode simply the angle of the surface. At each point on the surface, if you think of a normal vector to it, how much it is moved to left or to right from the straight UP position is called the dU. How much it is moved forwards or back from straight up is the dV. And how high it is, is the z. And the length of the normal vector is normalized to 1. What does that mean? 255, of course. :D Well, the way colors are represented in rgb is 8-bits unsigned, going from 0 to 255. On the other hand, you could think of that as a fractional number i.e.: going from 0/256 to 255/256, which is almost 1. In OpenGl it is customary to work with 0-0.994 representation.
In a tangent space normal map, normals are specified relateive to the surface (as opposed to older normal maps where x y and z were specified in global coords). So, since, on average, a surface is flat, z is usually close to 1. z goes in the blue channel, so normal maps, when you open them in Gimp look very blue. Red gets the dU, but transposed, as the dU could be positive or negative. 50% red means zero. Same with green and dV. So where a surface is flat, the normal map color is red = 0.5, green = 0.5, blue = 1.0
And you produce them with xNormal, and/or with the Gimp plugin from nvidia. The plugin takes a grayscale bumpmap and computes a normal map. xNormal takes a fine mesh and a coarse mesh, and makes a normal map that, when applied to the coarse mesh, makes it appear like the fine mesh.
Dual Joe nowadays swears by denormgen; --says it's easier to use than xnormal, runs on Linux, and can stack normalmaps. I haven't tried it yet.
What do they look like?
Bumpmap:
Normal map:
The above normal map is actually a combination of subtle normal corrections computed using xNormal, from a 100k+ polygon mesh, and the result of making a normal map out of the bumpmap above, using Gimp's normal map plugin from Nvidia. That plugin has a choice in the Conversion drop box, called "Normalize Only". Very useful when you're blending normal maps, because normal maps get corrupted by blending ops, and you need to renormalize them, afterwards. Also, if you want to increase the strength of a normal map, you can dim down a bit the blue channel in Gimp, then renormalize.
Shininess Map
"Shininess" is a bad name for a good thing to model, a fundamental property of materials, which can make a glass cockpit look glossy, and make metal look "shiny" without looking "glossy". (Just goes to show what a bad name "shininess" is... Metal looks "shinier" although less glossy, by having a lower shininess than glass. Why couldn't they call it "gloss", for Pete's sake?)
Here's shininess at work in my current beta shader:
Hard to appreciate with a still picture... The metal does reflect the environment, but the reflections are so blurred you can barely notice them. Don't confuse "shininess" with "specular color". Totally different animals.
Shininess describes how "UN-blurred" reflections are. A high shininess (200 or so) reflects images sharp and clear. With a shininess of 100 you begin to notice blurriness. With a shininess of 20, the reflected environment is so blurred it looks almost like half way between specularity or plain diffuse color.
Unlike specular color, shininess is a monchrome (gray scale) parameter. For the ship in the shader screenshot above, this is what the specular texture looks like:
And this is what the shininess texture looks like:
Notice that specular color of the cockpit is pinkish or purplish. Yes, it looks green, but that's because there's a bit of green light I put in the glow map, to make it look like someone lives there; but the specular reflections are actually tinted purple. But anyhow, what I wanted to call your attention to is that the specular strength of the cockpit is not much greater than that of the metal, and in fact it should be less, or rather, the metal should be brighter in specular. I'll fix that. But the cockpit will still look glossier than the metal --i.e.: won't blur the reflections.
And what makes the cockpit look "glossy" is the white color in the shininess map, versus grey for the metal.
Texture packing
As of this writing, it goes like I wrote at the beginning of the file:
* Texture 0: Diffuse texture (plus normalmap dU in alpha) * Texture 1: Specular texture (plus shininess in alpha) * Texture 2: Glow texture (plus ambient occlusion in alpha) * Texture 3: Damage texture (plus normalmap dV in alpha)
EDIT: There's contention in the issue, at the moment. We may remove dU from the alpha of diffuse and move it onto a 5th texture. This is because a requirement for transparency that wasn't there when shader work began, now is rearing its ugly head. I'm fighting with all my strength to keep transparency apart from opaqueness, but I'm not sure if I'll succeed :D IMO, transparency looks like crap in most game engines, because for it to work properly, you need to model refractions and fresnel effects; and you can't have one shader that's good at all the things that need to be done for solids to look good, and be able to do transparent things well too. So, transparent materials should be done with a specialized shader, not just throwing alpha in, half-assedly.
Anyways, stay tuned.
Miscellanea
A new release of the vs engine may automatically initialize the ambient and specular color in the system xml's (obtain them from averaging the color of their background textures). This will be a Good Thing (TM)! Where would you suppose ambient light comes from, if not from the background. So, if we're in a blue nebula, it makes no sense for ambient light to be red. But the chances of it being blue, if left to modders, is about 2^-24, or one in 65 million. So, with this change, it will be right automatically.
This subject is not complete without discussing ambient occlusion baking and the glow map; but this is too experimental at the moment. Suffice it to say that if I succeed, we'll never use gl ambient light, but will use the glow map to emulate ambient illumination, with self-occlusion baked in, and modulated by the color and intensity of the background.
Also: "detail textures". No need to complicate this post with it too much, but... Detail textures are basically tiling textures, typically 256x256, that map multiple times over the same UV map as the regular textures do, typically 16x16 times, "adding detail" as you get closer to an object (ship or station).
There will be two:
* Texture 4: Diffuse detail (color in rgb, detail normal map dU in alpha) * Texture 5: Spec detail (luma in red and blue, shininess in green, normal dV in alpha)
(The above is tentative and subject to change.) The reason you don't need to worry about it is that there will be default detail textures that will apply generally to all ships and stations and planets, unless you supply your own detail textures and specify them in the bfxm. The default ones will simply be some kind of perlin noise, barely noticeable, just enough to hide pixelation artifacts; no more.