I hope you're all having a great week and looking forward to the weekend. By popular demand, I've put together a video tutorial to explain how to build a basic shader with ShaderFX inside MayaLT. Hey, I'm no math genius, nor did I go to school for programming, but if I can wrap my brain around shader programming, so can you guys. Of course, ShaderFX helps by doing most of the heavy lifting in that department. For those of you who are a bit adventurous, have no fear of linear algebra, and want to learn more about some of the topics I cover in the video tutorial, here are some great links:
- Dot Product Explanation
- Matrix Multiplication
- Semantics - see also notes below.
Here is the final ShaderFX graph I build in the tutorial, along with the original HLSL shader - MyDiffuseLightShader
And finally, on to the show!
Some notes on the video:
- At 20:50 I tell you to enable Tweak texcoord. The reason for this is that we are using a previously defined TexCoord (SV_Position). To be able to write to that TexCoord, we need to enable Tweak.
- At 33:10, I made a mistake by indicating that the lighting calculations need to be plugged into the Process input of the Vertex Shader. In this case, as everything we're doing in the vertex shader is automatically passed to the pixel shader, this is not actually nescessary. Just plug the calculations (specifically the Color TexCoord Output node) into the Add operation of the Pixel Shader as indicated later. If we had some calculations in the vertex shader that are never passed to the pixel shader, we could use the process socket to include those calculations.
- The diffuse lighting direction values work like this: X (-1 to 1) = left to right side lighting; Y (-1 to 1) = bottom to top lighting; Z (-1 to 1) = back to front lighting. So an X value of -1 would mean the light direction is coming from the left side of the model, etc. Values beyond -1 and 1 simply increase the intensity of the light from that direction.
An explanation of Semantics (quoted from the nVidia Developer website):
Semantics are, in a sense, the glue that binds a Cg program to the rest of the graphics pipeline. The semantics POSITION and COLOR indicate the hardware resource that the respective member feeds when the Cg program returns its output structure. They indicate how the variables preceding them connect to the rest of the graphics pipeline.
The POSITION semantic (in this case, in an output structure used by a Cg vertex program) is the clip-space position for the transformed vertex. Later graphics pipeline stages will use the output vector associated with this semantic as the post-transform, clip-space position of the vertex for primitive assembly, clipping, and rasterization. You will be introduced to clip space later in this chapter, and more formally in Chapter 4. For now, you can think of a 2D vertex's clip-space position simply as its position within a window.
The COLOR semantic in this context is what Direct3D calls the "diffuse vertex color" and OpenGL calls the "primary vertex color." Color interpolation for a triangle or other geometric primitive during rasterization depends on the primitive's per-vertex colors.
...Input and output semantics are not the same, even though some have the same names. For example, for an input parameter to a vertex program, POSITION refers to the application-specified position assigned by the application when it sends a vertex to the GPU. However, an output structure element with the POSITION semantic represents the clip-space position that is fed to the hardware rasterizer. Both semantics are named POSITION and, indeed, each is a position. However, each position semantic refers to a position at different points along the graphics pipeline. Your Cg vertex program transforms the application-supplied vertex position into a vertex suited for primitive assembly, clipping, and rasterization. In the C2E1v_green program, this transformation is trivial (the vertex position is passed along unchanged), but later in this book, particularly in Chapters 4 and 5, you will learn more useful and interesting ways to transform vertices.