Results 1 to 11 of 11

Thread: A mathematical overview of shaders and normal maps and lighting, for artists

  1. #1

    Default A mathematical overview of shaders and normal maps and lighting, for artists

    Greetings all, this is my first post here.

    As the fidelity of graphics increase, as there are more and more maps and models and polygons an artist must make to strive towards their intended graphical outcome, one can often feel lost in a sea of terms that we don't understand. Everyone knows what a normal map is, but how does it work? What is "gloss"? What is a specular texture?

    Most of know know what a normal map looks like, we know what gloss does, we know that specular means highlights. But its been my experience that actually knowing something about these techniques, getting under the hood of shaders (the things that drive the actual rendering, and all we are really concerned with as modelers and texture-artists), has increased my ability many times over.

    If this is popular, I'd like to continue this in a "series," as often as I can complete a new post. But, let me start with the most fundamental component of technical artistry, "Shaders."
    ---------------------------------
    Shaders


    Everyone heard of shaders, or shader-based engines or software, but most people don't know what they are, or what the craze is. The most succinct explanation I can think of for a shader is:

    A shader takes something, does stuff to it, and gives you something else.

    Depending on who you are, that is either the most mundane explanation, or the most intriguing explanation. Obviously, programmers find it intriguing. And I hope you will too.

    Shaders come in two sorts. Vertex shaders, and pixel shaders. There is a big difference between them... the difference is the difference in graphical quality between RTW and M2TW. For this article, I will only get into vertex shaders, I will save pixel shaders for next time (pixel shaders are the cool ones, obviously, but you can't have pixel shaders without vertex shaders... one step at a time).

    I'm going to ignore the traditional way of learning vertex and pixel shaders; that is, doing your rendering with a vertex shader, and then showing you how to do it so much better with a pixel shader. As artists, this is mostly pointless. Anyway, let's look at what is probably a traditional vertex shader when you are dealing with normal mapping:

    Code:
    // input from application 
    struct a2v { 
    	float4 position		: POSITION; 
    	float2 texCoord		: TEXCOORD0; 
    	float3 tangent		: TANGENT; 
    	float3 binormal		: BINORMAL; 
    	float3 normal		: NORMAL; 
    };
    These are the things the application passes into the vertex shader. The application says "this vector (float3) is your tangent, this is your normal, and this is your binormal. This float2 is the UV coordinates of the vertex. And this vector (float4) is the vertex's position. The only thing you need to understand, really, is the "position." This is in world space (well, not yet, but it gets converted to it), meaning, if the vertex was at 2, 3, 1 in 3ds, the vertex is at 2, 3, 1 in the application (assuming they use the same scale). Since everything we are doing is in world space, don't worry about object and tangent space (actually these terms - world, object, tangent- will come up when we discuss normal maps).

    Code:
    // output to fragment program 
    struct v2f { 
    	float4 position    		: POSITION; 
    	float3 lightVec    		: TEXCOORD4; 
    	float3 eyeVec	    	: TEXCOORD3; 
    	float2 texCoord			: TEXCOORD0; 
    	float3 worldTangent  	: TEXCOORD6; 
    	float3 worldBinormal 	: TEXCOORD7; 
    	float3 worldNormal   	: TEXCOORD5;
    };
    This is what the vertex shader outputs into the pixel shader (AKA, fragment program). The actual code of the vertex shader will show us how we go calculate these outputs.

    Code:
    v2f v(a2v In) 
    { 
    	v2f Out = (v2f)0; 
    Out.position = mul(In.position, wvp);
    Out.texCoord = In.texCoord;
    These are just your standard things to do. It converts your vertex position into something the pixel shader can use, and passes through your UV coordinates without modifying them.

    Code:
    float3 worldSpacePos = mul(In.position, world);	//world space position of vertex
    Out.lightVec = lightPosition - worldSpacePos; //light vector, in world space
    Out.eyeVec = viewInv[3] - worldSpacePos; //eye vector in world space
    Matrix multiplication is a doozy... don't even try to think about it mathematically. What this does, is find the world space position of the vertex (I mentioned this above, remember?). It then subtracts that from the light position (in world space), giving us the vector pointing from the light, towards the vertex. We do the same for the camera/eye.

    Code:
    Out.worldNormal = mul(In.normal, worldIT).xyz;
    Out.worldBinormal = mul(In.binormal, worldIT).xyz;
    Out.worldTangent = mul(In.tangent, worldIT).xyz;
    This just converts your normal, binormal, and tangent inputs, into world space. Having everything in the same space allows us to perform operations on one another.

    Well that's it. ***yaaaawn*** That's a vertex shader. Boring, eh? Yes, it is. And, honestly, there's only so much you can do in it... you can only get graphics as good as your textures, because all you can do is do calculations at each vertex, and limited ones at that. This doesn't deal with any rendering in the vertex shader; the output would be a black vertex, because we aren't rendering anything. This shader is merely meant to show that shaders are extremely manipulatable; they can do nothing, or they can give you decent graphics and rendering. They can also be used for skeletal animations, but that's neither here nor there (but it does demonstrate how versatile they are!).

    Before I get into pixel shaders, though, there are a couple fundamentals of lighting to get out of the way (what is diffuse lighting? specular lighting and gloss?). Then we can tackle pixel shaders, and normal maps.

    Anyway, tell me how useful you would find something like this, and if there is anything you are unclear about, just ask (but please check wikipedia or google first if you don't understand a word or two!).

    Buh-bye.

  2. #2

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    Is anyone reading this? Is anyone finding it helpful or learning from it? Are there avenues one can suggest so more people would read it?

  3. #3

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    I read it and found it interesting if a little hard to follow. As far as helpful goes its always helpful to know how things work. I'm sure the normal map info would be more useful but I fear most people are just going to use the photoshop plugin for that and accept the results. I think you'd probably get more interest though if we were able to put models ingame, until we get that ability the information here is more theory than practise. If you want to apply your knowledge to that grumpyoldmans made a start on deciphering the format: http://forums.totalwar.org/vb/showth...12#post1434412
    Any assistance you could give on this matter would get a better response

  4. #4
    KnightErrant's Avatar Decanus
    Join Date
    Jan 2007
    Location
    Huntsville, Alabama USA
    Posts
    578

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    I think this is very useful, especially for non-graphics types like me.
    Please continue if you would with more tutorials. Could you write
    something about vertex weighting? I'm following GrumpyOldMan's thread
    on the .mesh file format as well and don't understand this topic.

    Thanks!

  5. #5

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    Alright, I made up this diagram today. It is about what a normal map does, I figured that would be more useful. I will elaborate more about normal maps (and things like tangent/object/world space) in the coming days, hopefully.



    Keep one thing in mind though, and when we get into pixel shaders this will become apparent. A value of 0.5 (50% grey) in a channel, will equal "0" for that vector. In the shader, each pixel on the normal map is multiplied by two, and 1 is subtracted from it. So:
    1 -> 1
    .75 -> .5
    .5 -> 0
    .3 -> -.4
    0 -> -1

    You don't need to understand how a dot product mathematically operates, just understand a couple very simple rules.
    If the two vectors are facing each other (0 degrees), the return is 1.
    If the two vectors are perpendicular (90 degrees), the return is 0.
    If the two vectors are facing the same direction (180 degrees), the return is -1, but we clamp this to 0.
    A dot product returns between 1 and -1, but anything between 0 and -1 we shall consider equal to 0 (in "traditional" lighting models... special effects and whatnot require this to be manipulated and the negative returns become important).

    So, imagine a sphere, anything facing the light gets the pure value of the diffuse map. As we get closer to the 'terminating edge' of light, the NdotL falls linearly, and the diffuse color becomes darker (because it is multiplying the diffuse texture by a grey color... think of multiply mode in Photoshop).

    Note also, that the 0-255 values of photoshop channels aren't important to us, we are concerned with ranges between 0 and 1 (so 127 = .5). It is helpful to think of things somewhat mathematically; these are mostly simple equations and try to figure them out in your mind.

  6. #6
    KnightErrant's Avatar Decanus
    Join Date
    Jan 2007
    Location
    Huntsville, Alabama USA
    Posts
    578

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    Thanks Baldr, that is helpful!
    So if n is the facet normal in the World system
    and L is vector from point light source to the facet
    then L . n = cos(alpha). If alpha = 60 degrees so cos(alpha) = 0.5
    then if the pixel had RGB (0.2, 0.4, 0.8), after shading it would be
    (0.1, 0.2, 0.4) i.e. reduce the saturation but leave hue and value alone.

    Edit: Said that last bit wrong, leave hue and saturation alone,
    and reduce value or brightness, correct?
    Last edited by KnightErrant; February 20, 2007 at 01:34 PM.

  7. #7

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    Damn, TWC just crashed and I lost my post. Let me try again.

    Keep in mind we are dealing with vectors, not scalars. We are multiplying a series of numbers by a series of numbers; the way we multiply them varies, such as Dot Product, and Cross Product, etc.
    http://en.wikipedia.org/wiki/Dot_product

    One thing I screwed up on, are the vectors we are concerned with are normalized, ie, their three components add up to 1. We can only perform dot products on normalized vectors, or else we will get some strange results (ie, that aren't between -1 and 1). 0, 0, 1 is a normal vector, .4, 0, .6 is a normal vector, .4, .1, .6 is not (>1), nor is .4, 0, .5 (<1).
    If you do the math with those vectors I listed, you wouldn't get the proper dot product. Anyway, the idea is the same.

    As for the HSL issue (hue saturation luminance), the dot product multiplies the RGB value, so yes, you are correct, it only changes the luminance (value).

  8. #8
    KnightErrant's Avatar Decanus
    Join Date
    Jan 2007
    Location
    Huntsville, Alabama USA
    Posts
    578

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    I get your meaning, I meant that L was also a normalized vector
    for the light source. Normalized being the square root of the
    sum of the squares of the components being unity. My background
    is physics so I've got the dot products and cross products down, but
    for others reading this tutorial please keep explaining the basics
    so everyone can benefit.

  9. #9

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    Bumping this for something I'm doing for the wiki. Annoying to have to go to the fourth page, I hope no one minds.
    Count no man happy until he is dead.


  10. #10

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    I'm sort of confused... the shaders in MTW2 are almost direct copies from RTW. There's something like 10 new ones. Do the different versions of directx influence how they're used, or am I missing the files that implement them?

    Of course, the extension was .vsh... vertex shader helper or something?

    Admittedly I know little about graphics, but I thought it was strange the directories were nearly identical.

  11. #11
    Indefinitely Banned
    Join Date
    Dec 2006
    Posts
    1,640

    Default Re: A mathematical overview of shaders and normal maps and lighting, for artists

    I wish this guy wasn't banned.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •