For those who dont know what HLSL (High Level Shader Language) is its a propreoraty shading language made by Micrsoft for use with Direct3D API.
Autodesk FBX (FilmBox) format is currently the standard format for game assests, including most games now developed for the XBOX 360.
Note : Since i originally come from using 3d artist tools, i will be refrencing the common simplicities that are taken for granted. other than starting out with a blank pad in the game programming world :)
- Before we get into shading we need something to shade.. namely a model, and its not as simple as saying file>Open.. in the game programming world, new objects need to be drawn onto the viewable space, which includes itterating through every seperate piece of geometry that a single character is made of. generally speaking, when u need to draw something in 2d or 3d, u obviously need something to draw it on u cant draw in thin air, so u need to build the space on which u can draw. to archieve this we need 3 matrices namely the world, view, and projection matrix.
World Matrix - Is basically defining the origin of the worldspace, a point from which everyother object can form a relation, or be relative too.
View Matrix - is the position of the camera in 3d space i.e XYZ values, the camera target and a camera up vector which defines the up director for the camera.
Projection Matrix - is the behavior of a world matrix to the view matrix, simply speaking its the calcuation between the world as seen through the camera, which could be orthagonal or perspective, properties like the field of view, aspect ratio ( viewport width / viewport height ), near and Far ClipPlaneDIstance.
Gettin these three things in place will let you successfully load up anykind of model for basic shading purposes.
- A Background on shading in the computer world, is that all graphical data is vector based data, meaning that if this data was to be rendered as is, u would get a huge block of continiously flowing numbers, Yes exactly like the matrix, expections that it would be green.. so to see this data in the form that we humans find more apealling, that is through pictures, this vecotor needs to be converted to pixel based information, a process nowdays commonly known as rasterization, in doing so the processor read every vector data and calculates the equivalent pixel based value, to show the final shaded model.
Now we can get down to the actual HLSL ShadingModel, a standard file structure consists of 4 major parts the Input(Incoming Vertex Data), Vertex Shader Functions, Output, Pixel Shader Functions, Techniques.
Input(Incoming Vertex Data) – This is where all the incoming vertex data is stored for futther calculation, this includies data from other textures, models, cameras, matrixes etc. it is basically a storage block ( Buffer ) for migrating data.
Vertex Shader Functions – This is where all the various methods for processing the input data reside, with a combination of these functions, a variety of results can be archieved, like calculating object normal space, or normals in relation to light, basically all kind of vector data.
Output(Outgoing Vertex Data) - This is again a buffer for vertex data, the only difference is that this data has already been worked on by the vertex shader functions, and is now ready to go to the next level which is processing by the pixel shader class.
Pixel Shader Functions – This is where all the calculated vector data, is re-calculated with pixel based logic, so that the realtime renderer can finally get the needed values to display the required object in worldspace.
Techniques - A technique is a function where a specific vector and pixel rendering function can be put together as a combination of different varities of rendering. like if u had an object that required normal vector rendering and another didnt not require that logic, then u could write 2 techniques, where 1 would have a function for calculating normal data and the other would be for stuff that didnt need normal calculations.
- Below is the DirectX API to more define the ShadingModel Pipeline.
The Microsoft Direct3D 10 API defines a process to convert a group of vertices, textures, buffers, and state into an image on the screen. This process is described as a rendering pipeline with several distinct stages.
The different stages of the Direct3D 10 pipeline are:
- Input Assembler: Reads in vertex data from an application supplied vertex buffer and feeds them down the pipeline.
- Vertex Shader: Performs operations on a single vertex at a time, such as transformations, skinning, or lighting.
- Geometry Shader: Processes entire primitives such as triangles, points, or lines. Given a primitive, this stage discards it, or generates one or more new primitives.
- Stream Output: Can write out the previous stage’s results to memory. This is useful to recirculate data back into the pipeline.
- Rasterizer: Converts primitives into pixels, feeding these pixels into the pixel shader. The Rasterizer may also perform other tasks such as clipping what is not visible, or interpolating vertex data into per-pixel data.
- Pixel Shader: Determines the final pixel colour to be written to the render target and can also calculate a depth value to be written to the depth buffer.
- Output Merger: Merges various types of output data (pixel shader values, alpha blending, depth/stencil…) to build the final result.
- Now getin down to some shader logic,
- Now some theory of shaders,
Standard Shader – The major re-quiste for texutures is UV which is available to us in the FBX model, but that information needs to be imported into the Shader Logic, that is go by itterating through the texutre co-ordinates and wraping it around the vector data and continously transorming that with the skin transform data, so as to always keep the data live and updated with new current snapshots of the model. Then that vecor data needs to be sent to the pixel shader, so that the vector is then compared with the texture file, to produced the write colors in the write space.
Diffuse Shading / Lighting - Diffuse shading is based on a principle that a surface is brightest when its facing the light and it tapers into darkness as is faces away from the light, basically if we normalize a vector, we end up keeping its direction, but the magnitude gets set to a value of 1, and this makes it a unit vector, the dot product of two unit vectors eqauls to the cos of the angle between the two vectors, — dot( unit vector , unit vector ) = cos ( angle ) — so with this we can determine if the surface is facing the light based on the result of the dot product, a value of 1 means that it is dirrectly facing the light and a value of -1 is that its in total darkness. so 1 is the brightest and -1 is the darkest area. the cos(angle) is a floating point value.
Normal Map Shading – Normal Mapping works on the principle that we do not need to use the normals from the vertices of a mesh, like in a generic vertex shader, in this case we can use the normals information stoed in an image. Normals contain XYZ information, and a normal map stores theses XYZ co-ordinates in the form of RGB color data, so in a normal shader, it basically overwrites the low number of normals derieved from the mesh, which a higher number which is then derieved from the normal map. The normal map can be generated from a high resolution object and can be used to shade a low detail mesh. normal maps are calculated in tangent space.
Specular Shading – For specularity, light is reflected from a surface to the camera or eye, it is always dependent on these two factors, whihc is the reflected light and the placement of the camera, in shader terms this would be the light reflection direction and the view(eye) vector, calulating reflected light can be a very intensive method, since it is depended on various bounce levels, so James F. Blinn (1977) devised something called as a Half Vector. THe Half Vector is the vector which is between the light and the eye, and the angle between the vector and the normal, is the same as the angle between the reflected light and the eye. This process is much quicker to calculate. For more information on Half vecotor u can see Models of light reflection for computer synthesized pictures by James F. Blinn. but thats not enough, speuclar depends on how smooth of rough an object really is, and thats where the specular exponent calculation comes in.
Reflection Shading – For reflection, we need a reflection vector, which can be archieved by calculating what the camera is seeing based of the normals. This then will reflect a specified texture data in form of a cube map, so as to fake the surroundings of the world, in realtime. On a more complex level these maps are also gnenerated in realtime so as to continously be updated with the environment that the object resides in.
Simple Shadows - For basic shadows, we need to make a shadow matrix that will draw a flattened version fo the object on a ground plane, the object can then be shaded with a constant color, so that it can look like a shadow on a ground plane. This can be quite an overkill at times, since it is basically making an instance of the character, and it still needs to calculate another set of vertices for the shadow.
Stencil Buffer Shadows – The Flexibility of the stencil mesh is not to draw the shadow as a flattened mesh but to draw its shape like a sillothettes. the shadow matrix will still calculate a flattened version fo the object, but when the shadow needs to be draw, it will go throught a stencil mode, in which the pre-processor will check to see if there is overlapping of shadow pixels or no, so as to always keep only one value to a shadow pixel at any given time. This is also a better option for alpha blending, since there is no overlapping of information, it would not tend to jitter in realtime.


































4:50 am
Dude,
Thanks for the effort, and tackling the entire process of 3D from soup to nuts in one blog is quite a mountain to climb! I don’t mean to be rude, but it (the article) would be much better if it had proper spelling & grammar. Otherwise an interesting read.
viz