Shader authoring/Anatomy of a Shader/Shader States

__TOC__
=Shadow And Dynamic State=
The meat and potatoes of a shader is inside SHADOW_STATE and DYNAMIC_STATE blocks. Both blocks are responsible for specifying all the rendering parameters necessary to render the shader. The difference between the two is that shadow state is only called once per material, so it can not change dynamically. Dynamic state is called every time something with a specific material is rendered, so it can change its parameters over time. The material system makes a distinction between the two for optimization purposes.
Note that each SHADOW_STATE/DYNAMIC_STATE pair is always followed by a Draw() call. Each SHADOW_STATE/DYNAMIC_STATE/Draw() sequence represents one rendering pass for your shader. You can use multiple rendering passes to achieve blending effects or to use more textures than you otherwise would be able to.
==Shadow State==
Most shadow state code uses pShaderShadow (of type IShaderShadow) to set its state. For a comprehensive list of the things pShaderShadow supports, look at IShaderShadow in src\public\materialsystem\ishaderapi.h. The table below summarizes the primary things done the SHADOW_STATE block.
Specification 	Description
pShaderShadow-> EnableTexture 	For each texture that you want to use in your shader, you need to enable that texture in shadow state. Each texture stage corresponds to a sampler inside your pixel shader's .FXC file (SHADER_TEXTURE_STAGE0 corresponds to sampler 0, and so on..)
pShaderShadow-> SetVertexShader pShaderShadow-> SetPixelShader	This is where you specify which .FXC (or .VSH/.PSH if you're using shader assembly) files your shader will use for its vertex shader and pixel shader. Usually, you'll have one .FXC file associated with each shader C++ class, but sometimes you'll want to choose a different .FXC file, and this call gives you the flexibility to do so. See Combo Variables for a description of the second parameter to these functions.
pShaderShadow-> VertexShaderVertexFormat 	
DefaultFog DisableFog 	These functions control how your shader uses fogging.
pShaderShadow-> EnableBlending pShaderShadow-> BlendFunc 	These functions control how your shader blends with the background (ie: translucency effects). By default, blending is disabled, so whatever your shader draws is opaque. You can use these to turn on translucency and different blending modes. When you enable translucency, all pixels produced by your shader go through this equation: 
[output color] = [your shader's output color] * SRC_FACTOR + [the destination pixel's current color] * DEST_FACTOR 
The two parameters to BlendFunc specify what SRC_FACTOR and DEST_FACTOR are. They are of typeShaderBlendFactor_t (see src\public\materialsystem\ishaderapi.h). The most common way to use translucency is standard alpha blending, where the alpha inside your texture specifies how opaque your texture is (an alpha of 1 means fully opaque and an alpha of 0 means fully translucent). In that case, you would want the equation to be: 
[output color] = [texture color] * [texture alpha] + [destination pixel's color] * [1 - texture alpha] 
and the code to produce that would be:
pShaderShadow->EnableBlending( true );
pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); 
Note that SHADER_BLEND_SRC_ALPHA refers to the alpha produced by your pixel shader, which can be any value you want. Sometimes it's as simple as the alpha that was in one of the textures.
pShaderShadow-> EnableDepthWrites 	This function specifies whether your shader writes to the Z buffer or not. Usually, translucent things do not write to the Z buffer, because if they did and something tried to draw behind them, it would get masked out by the Z buffer.
==Dynamic State==
Code inside the DYNAMIC_STATE block specifies rendering parameters like the SHADOW_STATE block does, but the parameters that it sets are things that are allowed to change over time. The table below lists the most common categories of things that are done inside a DYNAMIC_STATE block. For the complete list, look at the IShaderDynamicAPI class in src\public\materialsystem\ishaderapi.h. 
Specification	Description
BindTexture
pShaderAPI->BindLightmap
BindWhite
BindBlack
BindGrey	
These functions all tell which textures are bound to which texture samplers. They all take a parameter of type TextureStage_t, which tells which texture stage (or sampler in the pixel shader) you want the specified texture assigned to. 
BindTexture takes a second parameter that tells which texture to assign to the texture stage. The variable is one of your shader parameters (of type SHADER_PARAM_TYPE_TEXTURE). BindTexture also takes an optional third parameter which is another shader parameter that tells which frame of the texture you want to bind (if the texture has multiple frames built into it).
pShaderAPI->SetVertexShaderConstant
pShaderAPI->SetPixelShaderConstant	
These functions are used to set the vertex and pixel shader constants.
SetVertexShaderTextureTransform
SetVertexShaderTextureScaledTransform	
SetVertexShaderTextureTransform dumps a texture transform into two vertex shader constants, starting at the one you specify in the first parameter. The second parameter specifies the texture transform, which should be specified in one of your shader parameters (of type SHADER_PARAM_TYPE_MATRIX). 
The two vertex shader constants are setup with a 2x2 rotation/scaling matrix on the left, and the translation on the right: 
constant 1: [rot] [rot] 0 [u translation] 
constant 2: [rot] [rot] 0 [v translation] 
As an example, the code below would bind the default shader parameter called BASETEXTURETRANSFORM: 
SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); 
Then, your .FXC code would use it like this: 
const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 );
baseTexCoord.x = dot( i.texCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w;
baseTexCoord.y = dot( i.texCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; 
SetVertexShaderTextureScaledTransform is just like SetVertexShaderTextureTransform, but it takes a third parameter of type SHADER_PARAM_TYPE_FLOAT, which is a scaling factor for the matrix.
pShaderAPI->SetVertexShaderIndex
pShaderAPI->SetPixelShaderIndex	
These functions are used to set the values of the dynamic combo variables that your shader supports. The values passed to these functions come from the classes in your shader include file.