Introduction to the CineMut family of GLSL shaders
(If you don't know what a “shader” is, skip to the next section below.)
CineMut is the name of a family of GLSL shaders soon to be released under strict GPL (“copyleft”) license. They are currently, as of this writing (August 2009), in development for the VS (Vegastrike) engine; but they could be used in other engines.
The goal is for them to be a small family (just a few shaders) to cover most of the shading needs for most games.
They are intended to be fast, single-pass shaders, rich in their feature set, and well grounded in Physics and Optics, –as opposed to flashy but not-too-real-looking, run of the mill shaders.
And the philosophy is to do things well that really matter to the eye, such as Fresnel, but to save instructions when it comes to hard-to-notice and too expensive subtleties; –i.e.: There are more efficient ways to achieve good-looking ambient shadowing than to use 17 spherical harmonics; and there are more efficient ways to show well differentiated materials than to use a full, nine-texture, BRDF shader…
The flagship of the family is CineMut Opaque, which currently can depict realistic metals, paints and plastics, as well as matte materials.
Among its many features,
- Materials are characterized in a more physics-oriented way than the standard diffuse color plus specular color –which can easily be used to create materials that don't and can't exist; and you need to be a scientist to use correctly. Currently, a material is specified by a single color (“albedo”), a metallic specularity versus diffuse ratio, a dielectric constant, a dielectric purity of the surface, a glossiness, a glossiness purity, two channels for anisotropy, a few “detail control” channels, a mix-in diffuse channel for alpha-blending rust or dirt, and a set of “damage” channels.
- Fresnel is computed using the full Fresnel equation, using the specified dielectric constant for the material. NO rough approximations are used; it's the real thing: the full Fresnel equation for un-polarized light.
- Multiple inner bounces of light in 2-layer materials, such as paints, are taken into account.
- Over-all correctness: shadows falling on a partly-diffuse/partly-specular material don't modulate specular reflections, for instance; –the way they INCORRECTLY do in many shaders out there. For another example, we've seen shaders that add an ambient light specular component… That is incorrect, because environment mapping IS the ambient specular component; so that would be adding the component twice. For yet another example, many shaders out there use a single AO channel (Ambient Occlusion), but correctness requires two: a uniform ao (UAO) and a cosine ao (CAO) which have different meanings, and different uses. And for another example, implementations of Phong shading usually ignore the fact that the higher the shininess (glossiness), and therefore the smaller the specular light spots are, the brighter they should be. CineMut models this in a scientifically correct manner.
- Self-shadowing and specular self-occlusion using occlusion queries computed with the help of a PRT (precomputed radial transfer) -based bent normals texture. Note that there are many shadowing algorithms out there that can do inter-object shadows, but fail at intra-object self-shadowing. Our philosophy has therefore been to cover the more difficult case –self-shadowing– first; and then leave the choice of inter-object shadowing algorithm open, –on the table.
- Soft shadows and soft lighting, controlled by an angular light radius packaged with each dynamic light, as opposed to the usual point-light model.
- Shininess (glossiness) control of environment map blurriness via cube map offset control, scientifically correlated to the Phong power used for specular light reflections.
- Specular reflections from statically baked lights (this one's just a hack; but better than nothing).
- A tiling, “detail texture” is used to add noise, perling clouds and/or bumpiness to the diffuse, specular, gloss or normalmap channels, at the sub-texel level, –in ways that are controlled per-texel by a few channels in the main texture.
Here's a screenshot from an early test; forgive the horrible model and horrible unwrap; just focus on the looks of the blue paint (gas tank), versus the glossy blue plastic (box under the seat), versus metals, etc.
Planned features include,
- A second detail texture and further detail control channels.
- Paralax (less than full paralax, but “good enough”)
- Radiosity
- Possibly a hint of self-reflections and caustics.
- Curvature-based anisotropy.
Other planned shaders besides CineMut Opaque:
- CineMut FireGlass, for transparent materials, such as glass, translucent materials, and light-emissive planes
- CineMut Atmosphere, for planetary atmospheres and clouds
- CineMut Rocks, for rocks and rocky planets and asteroids
- CineMut Bio, for human skin, plant leaves, and generally all materials using sub-surface scattering
- CineMut Cockpit, for cockpit interiors and and wind-shield effects, such as light glares.
- CineMut AsteroidField, for WC-style asteroid fields full of floating rocks, pebbles and dust.
But, first of all, What are "shaders"?
Shaders are like “programs”; –software–; but instead of running on the main processor, they run on your Graphics Processing Unit (GPU), –that special transputer chip found in videocards which often needs a huge heatsink and a centrifugal fan… you got it.
There are two kinds of such programs, or shaders:
- Vertex shaders: they execute once for each mesh vertex, per frame. They are used for per-vertex calculations, of course; but their results are usually fed to “interpolants” which are further processed in a per-fragment basis, –see below.
- Fragment shaders (A.K.A. “pixel” shaders): The term “fragment” is slightly more correct… Well, to simplify matters, think of them as programs that execute once per pixel, per frame. Now, if your resolution is, say, 1280 x 1024, and you're getting 60 FPS, the number of times your “pixel” shader is running is, indeed, 1280 x 1024 x 60 = 78,643,200 times per second, at least; and if that is a mind-boggling speed for a program several pages long, full of vector math, powers, trigonometry and whatnot to run, well, it should be mind-boggling. Typically, the math processing power in a GPU is many, many times higher than the processing power of your typical “Pentium” or whatever CPU. And the instructions in a shader program are not executed serially; they are pipelined and parallelized. But to get back to “fragment” vs. “pixel” terminology, the reason the term “fragment” is more correct is that the number we just calculated would be right if you forced FSAA (Full Screen Anti-Aliasing) off in the driver. When FSAA is on, a pixel may be broken into multiple “fragments” when it is crossed by geometry edges, in which case the fragment shader program executes once per pixel-fragment.
There are a number of languages that vertex and fragment shaders can be written on; some more proprietary than others. CineMut shaders are written in the free and open source language GLSL.
Where does the name "CineMut" come from
I (chuck_starchaser) came up with it; comes from Latin… It all began with a big argument between Klauss and I at the VS (Vegastrike) forum. We're both perfectionists, and usually work well together; but on that day our philosophies clashed in one respect: Klauss wanted our new shader (name-less at the time) to continue with a tradition established by the existing VS shaders: There were modifiers and settings in the mesh files of models that affected the final color, brightness, specularity, etceteras, of the materials of models and lighting conditions. But I wanted NONE of it.
Why?
Because, in my opinion, being able to “tweak” things via the mesh is a disservice. It means that there would be no dependable absolutes…
You see, I'm both a programmer and an artist. When I'm programming, I want to see beauty in the code. When I'm working on art, I want scientific rigor and consistency.
I believe, for example, that there should be a combination of diffuse and specular color for, say, 22 karat gold; and that these colors should be written down somewhere, be dependable, re-usable, and in fact, be part of a Materials Library. Every time I want to show gold on a 3D model, I just have to pull the data for gold from the library, and stick it there, without doubts or fears. Same for titanium, brick, or high gloss olive green paint. I don't want a statement full of caveats, like “IF your mesh settings are this or that, then your colors for gold would be this; otherwise…”. I WANT my materials to look wrong if they are wrong; and to have to go back and fix them in the texture. I don't want after-the-fact tweaks; thank you very much. But Klauss insisted that many artists would appreciate the tweaks. We finally agreed to disagree, and to have two parallel shader families: one with and one without tweaks.
So, from the Latin “sine”, meaning “without”, and “mut” meaning “change” or “tweak”, arose “SineMut”; but then I figured that spelling it like “CineMut” would sound more cinematic
But so, what the name “CineMut” stands for is consistency and dependability. It says “it is ALL in the texture”; nothing elses affects the looks of your materials. If you use a given combination of colors and texture channels to achieve a given material look in one model, it will look the same in any other model (and in any game that uses CineMut, for that matter, as part of the license “deal” will require adhering to the “it's all in the textures” philosophy).
Requirements
CineMut Opaque is a single-pass shader. Having said that, it is pretty big as single-pass shaders go. The basic hardware requirement is a ps3.0 shader revision -capable graphics processor. Something like an NVidia 8800 or better. Where does this leave proud owners of old Radeon 9000's? Well, it leaves them in the dumpster; –SOL (“Shit Out of Luck”) to put it plainly.
You see, the philosophy behind CineMut is to take open source games to the level of leading edge commercial gaming graphics –or hopefully even a level above it–, and, naturally, we can't do that AND support old hardware at the same time. (I know that the tradition is for open source to lag behind commercial quality; but I don't personally subscribe to traditions in general, or this one in particular.)
CineMut Opaque also puts some heavy requirements on the texture packing. We are developing a parallel project called "LaGrande", which is a collection of Blender node networks to facilitate the processing and packaging of textures for CineMut Opaque -compatibility. Even so, there's a fair amount of work involved in texturing a model for CineMut, versus texturing for the garden variety of shaders out there. For example, the type of bent normals CineMut Opaque requires need special bakes done with xNormal (prtP, prtN and UAO), Blender bakes of model space normals, tangents and binormals, a bump map, a normalmap from that bumpmap (from Gimp), and then running those bakes through a number of LaGrande node networks, to finally get the tangent-space bent normals needed. This process will be condensed into a single executable in the future, once CineMut Opaque matures a bit.
Texture Packing details
The current texture packing format uses several 4-texture atlases, to reduce the need of texture units, and its most recent version, as of this writing, is:
Notes:
- “Alpha” a meaningless term, from a point of view of optics and physics, and I was more than reluctant to have any such thing (there will be CineMut FireGlass for transparent materials); but NOT having alpha would preclude rapid, automatic conversions of existing models to CineMut-compatible format; and would interfere with uses of alpha as per putting holes into things, via alpha-testing, which is a common technique. So alpha is in, after all.
- Mix-in color and Age Alpha… We were talking in some PU forum about whether it makes sense for a brand new ship you buy to show rust. Well, it doesn't; but if you see a ship of the same type that's been around a while, it makes more sense. Not that rust makes sense in space; but in gaming it's a tradition; and CineMut is not only targeted to to space games. Rust and scratches and to some extent dirt, are connected to a an object's age. Combat may result in “rapid aging” to some extent; but it won't put thick rust on your ship's engines. I think that age should be a parameter passed to the shader, just like damage is, in Vegastrike. So, the idea here is to have the rust or scratch or dirt color in the mix-in color channels, and a sort of logarithmic encoding of rust “clouds”, and scratch lines, in the Age Alpha channel. The shader will apply age-dependent gamma to the alpha channel, then blend the RGBA with diffuse; and lower specularity and dielectric purity inversely with the gamma-ed Age Alpha.
- Iridescence is something new in this latest packing. I'm not entirely sure what it IS, yet, but I know we need it for titanium rusts :D Probably a normalized dielectric thickness. I have to read up on it. Iridescence is what makes some materials show rainbow-like reflections that change with angle.
- There's now a whopping 5 channels for detail control. This might seem excessive, but I believe it isn't. Thing is, we need to control,
- the intensity of detail texture application
- whether it puts bumps on the normal map and/or
- whether it puts clouds in the shininess map and/or
- whether it puts noise in the diffuse color, and if so,[list]
- whether it should look like sparse white dots or
- black dots or
- some perlin noise in-between[/list]
- frequency of the detail map (big or small tiling)[/list]
- Plus, we may have a second detail texture for random direction scratchiness; and/or
- a custom detail map for representing evenly tiled surfaces.
- So… I'm not even sure how to control all that from only 5 texture channels.
- The bent normal is no longer in a separate, un-compressed texture; but that means we need to use special tricks to get some precision out of dxt5 compression. So, I'm repeating the U and V in 3 rgb channels each, and will encode it with offsets so that the steppings in the encoding are staggered, for a rough total precision of 7 bits. The Z is the most critical and so it goes in an alpha channel, which is 8-bit (yeah, I'm simplifying things).
- The UAO, CAO and bump height are in alpha channels also, for maximum precision.
- Radiosity took a big hit, since previous plans for packing schemes; and only gets 6 RGB channels; but that's okay: self-radiosity is a subtle effect and doesn't need a lot of precision, probably.
- As explained elsewhere, for a fighter, all sub-textures sizes are standard 512×512 except the normalmap is 1024.
- So, each atlas is 1024×1024. Three atlases plus the 1024 normalmap = 4 million texels. And 4M texels is equivalent to having a single 2048 texture. I don't think this is bandwidth-excessive at all.
This packing is conditional, –tentative, Klauss is not sure about what effect doing four reads per texture might have on performance. His concern is with texture cache: Four reads around the same place are probably okay because of cache locality; but 4 reads spread around the texture might be problematic. His contention is that this requires testing and that we shouldn't set the texture packing in stone before we have more data. My contention, on the other hand, is that I wanted to have a packing we can start with, and modify later if necessary; just to push the project forward.
But so, what this all means is that instead of three 2×2 atlases we might have six 2×1 atlases (what are currently labeled sub-atlases would become atlases); or that we might end up with a whopping 13 textures.
But you might ask, won't this special packing make models textured for CineMut unable to be seen in other shaders?
Yes and no: Standard shaders won't be able to make heads or tails out of the CineMut texture packing; but by the same token, LaGrande will, out of curtesy, produce a sister set of standard textures for use with more standard shaders.
Where do I get it?
There's not much I can offer you right now, except the original, pre-beta release, which was announced here:
http://vegastrike.sourceforge.net/forums/viewtopic.php?p=103561#p103561
The files there should work; but the vegastrike engine I'm not sure.
The shader has evolved by leaps and bounds since then; but we don't have a single, packaged download, or even
a dependable version of the engine supporting CineMut. As of this writing, the emphasis is on enabling support of DDS cube-maps in the engine, and finding what the current compilation problems are that seem to make it impossible to get a binary that doesn't segfault in one version of windows or another.
Q&A
From a post at the VS forums:
Fendorin wrote:Hi I doesn't understand all But could it possible with Cinemut to use tiling texture mixed with uv mapped exemple 2 meshs : a station : the hull is tiling texture and the point of detail dock ,bridge,habitat .....etc is uv mapped? The render in game should be mice no? and very detailled?
Hey, Fendorin!
I've got good news for you. Indeed, you will be able to mix tiling and UV-mapped textures. And not only use one or the other, but actually blend them. In fact, this is how CineMut works by default. The tiling texture is called the “detail texture”, because the standard use of it is simply to add sub-texel detail; but nothing prevents you from giving your mesh a flat color and using the detail texture as your main texture.
And let me tell you, this is what you want: because even if you use the detail texture as your main texture for a part of a ship or station, you still want an overlapping UV-mapped texture to add global gradients of light and shadow, things like AO and lighting; as well as to paint over a tile somewhere so that it looks like it fell off.. Otherwise the tiles would look too uniform.
Moreover, there are two texture channels in the main texture that, by changing the color, you control the way the detail texture is applied. You can use one of those channels to specify if you want to use the detail texture as a color modulator, or as a shininess (gloss) modulator, or as a bump-map. And you can use the other channel to control its frequency and intensity.
By frequency I mean that you can make the tiles bigger or smaller, by powers of two; or even some blend in-between two powers of two.
There will be a default detail texture packed with CineMut, which has 4 channels (RGBA), one of which (red) has noise; another (green) has “clouds”, and the last two (blue and alpha) have dU/dV normals to add to the normalmap, to look like a bumpy, ripply surface. Remember the gas tank on the motorcycle?
But you *can*, through the techniques file, specify a detail texture of your own. However, you'll have to use the channels the same way (red channel for brightness modulation, green channel for shininess modulation, and blue and alpha for normalmapping). Which is okay; you probably don't need multiple colors for the tiles, would you? You can use a beige color for the main texture, for example; put like a thatch pattern in the normalmap channels of the detail texture, inside a square border, say; and a bit of noise in the green channel to represent wear of the surface, and you'd have awesome looking tiles without using any color patterns.






