?/TD>
Microsoft DirectX 9.0

High-Level Shader Language


Tired of writing shaders in assembly language? Try the high-level shader language. Microsoft?DirectX?9.0 contains the first release of a high-level shader language for developing and debugging shaders in a C-like language. This capability is in addition to the assembly language shader capability that is used to generate vertex shaders, pixel shaders, and effects, which began with DirectX 8.0.

The high-level shader language supports the development of shaders from C-like functions. The language will support many standard language features such as functions, expressions, statements, standard data types, user-designed data types, and preprocessor directives.

Data Types

Scalar Types

booltrue of false
int32-bit signed integer
half16-bit floating point value
float32-bit floating point value
double64-bit floating point value

Not all target platforms have native support for integer values. Integer values might need to be emulated using floating point hardware. Integer operations that go outside the range of integers that can be expressed as floats on these platforms are not guaranteed to function as expected.

Not all target platforms have native support for half or double values. If the target platform does not, these will be emulated using float. Intermediate results of floating point expressions may be evaluated at a precision higher than the operands or the result.

Vector Types

vectorA vector of dimension 4; each component is of type float.
vector < type, size >A vector of dimension size; each component is of scalar type type.

Individual components of a vector can be accessed by index, using the array access syntax. For example:

vec[0]		(same as vec.x)
vec[3]		(same as vec.w)

Individual components of a vector can be accessed by name, using the structure member access syntax. The following component name sets for vectors are defined.

Default set
 x	 y	 z	 w
Color set
 r	 g	 b	 a

Vectors containing swizzled components of the vector can be formed by concatenating two or more component names together. For example, yyzw or bgr. The concatenated names all must come from the same name set. The same component can be repeated more than once, but if it is, the swizzle is not valid as the target of an assignment.

Matrix Types

matrixA matrix with four rows and four columns, each component is of type float.
matrix < type, rows, columns?gt;A matrix with rows rows and cols columns; each component is of scalar type type.

Individual row-vectors of a matrix can be accessed by index, using the array access syntax. For example:

mat[2]     (same as mat.m20m21m22m23)
mat[2].w   (same as mat.m23)
mat[2][3]  (same as mat.m23)

Individual components of a matrix can be accessed by name, using the structure member access syntax. The following component name sets for matrices are defined.

One-based set

_11	_12	_13	_14
_21	_22	_23	_24
_31	_32	_33	_34
_41	_42	_43	_44

Zero-based set

_m00	_m01	_m02	_m03
_m10	_m11	_m12	_m13
_m20	_m21	_m22	_m23
_m30	_m31	_m32	_m33

Vectors containing swizzled components of the matrix can be formed by concatenating two or more component names together. For example, _41_42_43 or _m01_m02_m03_m04. The concatenated names all must come from the same name set. The same component can be repeated more than once, but if it is, the swizzle is not valid as the target of an assignment.

Object Types

string

ASCII string type. There are no operations or states that accept strings. String parameters and annotations can, however, be queried by the application through the ID3DXEffect interface.

pixelshader

A pixelshader object represents a Microsoft Direct3D?pixel shader object. While no operation within a shader function directly accepts pixel shaders, a pixel shader can be set to the device from within a technique. The following properties can be queried from a pixelshader object, using structure member access syntax.

const string version;

Literal pixelshader values can be expressed as an assembly block,

pixelshader ps = asm { ps.2.0 mov oC0, c0 };			

or as a compile call.

pixelshader ps = compile ps_2_0 psmain();	

sampler

A sampler object represents a Direct3D sampler stage. Sampler stages are used to sample textures. Samplers are assigned textures and filtering types.

sampler s = sampler_state { texture = NULL; mipfilter = LINEAR; };

texture

A texture object represents a Direct3D texture object. While no operation within a shader function directly accepts textures, textures can be set to the device from within a technique. The following properties can be queried from a texture object, using structure member access syntax.

const string type;	
const string format;
const int width;
const int height;
const int depth;			

vertexshader

A vertexshader object represents a Direct3D vertex shader object. While no operation within a shader function directly accepts vertex shaders, a vertex shader can be set to the device from within a technique. The following properties can be queried from a vertexshader object, using structure member access syntax.

const string version;

Literal vertexshader values can be expressed as an assembly block,

vertexshader vs = asm { vs.2.0 mov oPos, c0 };			

or as a compile call.

vertexshader vs = compile vs_2_0 psmain();	

Struct member access of object properties is not yet implemented.

Structure Types

The struct keyword is used to define a structure type. Once a structure has been defined, it can be referenced by using its identifier (ID).

	struct [id] { member_list }

A member_list consists of one or more member declarations. Member declarations are similar to variable declarations (described below), except they cannot have initializers and cannot individually be declared static, extern, volatile, or const.

User-Defined Types

The typedef keyword can be used to declare a name for a type. The const keyword can be used to explicitly mark the type as constant. Array suffixes can follow each ID (Or "id"). Once a type has been declared, it can be referenced by using its ID.

	typedef [const] type id [array_suffix] [, id ...] ;

An array_suffix consists of one or more [ literal_integer_expression ], representing the dimension.

For compatibility with Direct3D extensions (D3DX) 8.0 effects, the following types are automatically defined in a case-insensitive manner at the super-global scope.

	typedef int DWORD;
	typedef float FLOAT; 
	typedef vector VECTOR;
	typedef matrix MATRIX;
	typedef string STRING;
	typedef texture TEXTURE;
	typedef pixelshader PIXELSHADER;
	typedef vertexshader VERTEXSHADER;

For convenience, the following types are automatically defined at the super-global scope. (In these definitions, the pound sign represents a digit between 1 and 4.)

	typedef vector bool#;
	typedef vector int#;
	typedef vector half#;
	typedef vector float#;
	typedef vector double#;

	typedef matrix bool#x#;
	typedef matrix int#x#;
	typedef matrix half#x#;
	typedef matrix float#x#;
	typedef matrix double#x#;

Type Casts

Scalar-to-scalarAlways valid. When casting from bool type to an integer or floating point type, false is considered to be zero, and true is considered to be one. When casting from an integer or floating point type to bool, a zero value is considered to be false, and a nonzero value is considered to be true. When casting from a floating point type to an integer type, the value is rounded toward zero.
Scalar-to-vectorAlways valid. This cast operates by replicating the scalar to fill the vector.
Scalar-to-matrixAlways valid. This cast operates by replicating the scalar to fill the matrix.
Scalar-to-objectNever valid.
Scalar-to-structureValid if all elements of the structure are numeric. This cast operates by replicating the scalar to fill the structure.
Vector-to-scalarAlways valid. This selects the first component of the vector
Vector-to-vectorThe destination vector must not be larger than the source vector. The cast operates by keeping the left-most values, and truncating the rest. For the purposes of this cast, column matrices, row matrices, and numeric structures are treated as vectors.
Vector-to-matrixThe size of the vector must be equal to the size of the matrix.
Vector-to-objectNever valid.
Vector-to-structureValid if the structure is not larger than the vector, and all components of the structure are numeric.
Matrix-to-scalarAlways valid. This selects the upper-left component of the matrix.
Matrix-to-vectorThe size of the matrix must be equal to the size of the vector.
Matrix-to-matrixThe destination matrix must not be larger than the source matrix, in both dimensions. The cast operates by keeping the upper-left values, and truncating the rest.
Matrix-to-objectNever valid.
Matrix-to-structureThe size of the structure must be equal to the size of the matrix, and all components of the structure are numeric.
Object-to-scalarNever valid.
Object-to-vectorNever valid.
Object-to-matrixNever valid.
Object-to-objectValid only if the object types are identical.
Object-to-structureThe structure must not contain more than one member. The type of that member must be identical to the type of the object.
Structure-to-scalarThe structure must contain at least one member. This member must be numeric.
Structure-to-vectorThe structure must be at least the size of the vector. The first components must be numeric, up to the size of the vector.
Structure-to-matrixThe structure must be at least the size of the matrix. The first components must be numeric, up to the size of the matrix.
Structure-to-objectThe structure must contain at least one member. The type of this member must be identical to the type of the object.
Structure-to-structureThe destination structure must not be larger than the source structure. A valid cast must exist between all respective source and destination components.

Variables

Variables are declared as follows:

[static uniform extern shared volatile] [const] 
type id [array_suffix] [: semantic] [= initializers] [annotations] [, id ...] ;

Variable declarations can be prefixed with the static keyword. For global variables, this indicates that the variable is internal to the shader and not to be exposed externally. For local variables, this indicates that its value will persist from call to call. Initialization of local static variables happens only once. If they are not explicitly initialized, their initial value is assumed to be zero.

Global variable declarations can be prefixed with the uniform keyword, explicitly indicating that they are uniform inputs to the shader. All non-static global variables are uniform by default.

Global variable declarations can be prefixed with the extern keyword, explicitly indicating that they are external inputs to the shader. All non-static global variables are extern by default.

Global variable declarations can be prefixed with the shared keyword. This a hint to the effect framework that the value of this parameter is intended to be shared between effect objects.

Global variable declarations can be prefixed with the volatile keyword. This a hint to the effect framework that the value of this parameter changes frequently.

The initializers represents either an expression, or { expression [, expression [, ...]] }. For global externs, these expressions must be literal. For other global variables, and static local variables, these expressions must be constant.

Variables can be given a semantic. Semantics have no meaning in the language. They are simply associated with the variable, and passed down to the back-end. They are not case-sensitive. What semantics are valid, and what they mean, depends on what kind of function you are defining. (For vertex shaders, the semantics are used by the back-end to map inputs, and assign output registers. A complete list of shader input and output semantics appears later in this document.)

Global variables can have annotations. Annotations are of the form { member_list }. Where member_list represents a list of member declarations, where each member is initialized to a literal value. Annotation are only a method of communicating metadata about a parameter to an effect. They cannot be referenced from inside the program. Annotation members cannot have semantics.

Component Access and Swizzles

Individual float components of base types can be addressed much like accessing a structure member, using a subscript from the name table below.

_11, x, r_12, y, g_13, z, b_14, w, a
_21_22_23_24
_31_32_33_34
_41_42_43_44

Vectors containing specific components (swizzles) can be specified by using a subscript formed by concatenating two to four of these names together. Valid examples are:

bgr, yyzw, _12_22_32_42

All the names must come from the same subscript set, (xyzw, rgba, or _11 to _44). Sets cannot be mixed. The same component may be repeated more than once. However, if a component is repeated, the swizzle is not valid as the target of an assignment.

Statements and Expressions

Statements

Statements are used to control the flow of execution. The following kinds of statements are supported.

{ [statements] }
[expression] ;
return [expression] ;
if ( expression ) statement [else statement]
for ( [expression | variable_declaration] ; [expression] ; [expression] ) statement
do statement while ( expression ) ;
while ( expression ) statement ;

The for, do, while statements are not yet implemented.

Expressions

Expressions are literals, variables, or some combination of literals and variables composed using operators from the operator precedence table in the Appendix.

OperatorUsageMeaningAssociativity
()(value)Sub expressionLeft to right
()id(arguments)Function callLeft to right
type(arguments)Type constructorLeft to right
[]array[int]Array subscriptLeft to right
.structure.idMember selectionLeft to right
value.swizzleComponent swizzleLeft to right
++variable++Postfix increment (per component)Left to right
--variable--Postfix decrement (per component)Left to right
++++variablePrefix increment (per component)Right to left
----variablePrefix decrement (per component)Right to left
!!valueLogical not (per component)Right to left
--valueUnary minus (per component)Right to left
++valueUnary plus (per component)Right to left
()(type) valueType castRight to left
*value*valueMultiplication (per component)Left to right
/value/valueDivision (per component)Left to right
%value%valueModulus (per component)Left to right
+value+valueAddition (per component)Left to right
-value-valueSubtraction (per component)Left to right
<value < valueLess than (per component)Left to right
>value > valueGreater than (per component)Left to right
<=value <= valueLess than or equal to (per component)Left to right
>=value >= valueGreater than or equal to (per component)Left to right
==value == valueEquality (per component)Left to right
!=value != valueInequality (per component)Left to right
&&value && valueLogical AND (per component)Left to right
||value||valueLogical OR (per component)Left to right
?:float?value:valueConditionalRight to left
=variable=valueAssignment (per component)Right to left
*=variable*=valueMultiplication assignment (per component)Right to left
/=variable/=valueDivision assignment (per component)Right to left
%=variable%=valueModulus assignment (per component)Right to left
+=variable+=valueAddition assignment (per component)Right to left
-=variable-=valueSubtraction assignment (per component)Right to left
,value,valueCommaLeft to right

Unlike C, short-circuit evaluation of &&, ||, and ?: expressions never short-circuit any evaluation because they are vector operations, and all sides of the expression are always evaluated.

The % operator is defined only in cases where either both sides are positive, or both sides are negative. Unlike C, it also operates on floating-point data types, as well as integer.

Many of the operators are designated as being "per component." This indicates that, for each component of the input, some operation is performed (independent from the operations happening on the other components), and the result is placed in the corresponding component of the output vector.

Comparison and binary operators also function on a per component basis. This means that if you compare two vectors, the result is a vector containing the Boolean result of the comparison for each component.

For expressions of binary operators, the size and component type of each side are promoted to be the same before the operation occurs. The promoted type determines the resolution at which the operation takes place, as well as the result type of the expression. For example an (int3 + float) expression would be promoted to (float3 + float3) for evaluation, and its result would be of type float3.

Functions

User-Defined Functions

Functions are defined very much like C functions.

[static inline target] [const] type id ( [parameter_list] ) ;
[static inline target] [const] type id ( [parameter_list] ) { [statements] } ;

The target represents an optional identifier specifying the platform for which the function has been authored. The parameter_list represents a list of one or more parameter declarations separated by commas.

[uniform in out inout] type id [: semantic] [= default]

Parameter values are always passed by value. The in parameter usage indicates that the value of the parameter should be copied in from the caller before the function begins. The out parameter usage indicates that the last value of the parameter should be copied out, and returned to the caller when the function returns. The inout parameter usage is simply a shorthand for specifying both in and out. The uniform parameter usage is a special of kind of in, indicating to a top-level function that the value for parameter comes from constant data. For non-top-level functions, uniform is synonymous with in. If no parameter usage is specified, the parameter usage is assumed to be in.

If a function is defined without a body, it is considered to be a prototype. The function must be redefined, with a body, later on in the code. If no body is defined and the function gets referenced, this is an error.

Functions can be overloaded. A function is uniquely identified by its name, the types of its parameters, and the target platform, if provided. Function overloading is not yet implemented.

Currently, all functions are inlined. Recursion is not supported.

Intrinsic Functions

absvalue abs(value a)Absolute value (per component).
acosacos(x)Returns the arccosine of each component of x. Each component should be in the range [-1, 1].
allall(x)Test if all components of x are nonzero.
anyany(x)Test is any component of x is nonzero.
asinasin(x)Returns the arcsine of each component of x. Each component should be in the range [-pi/2, pi/2].
atanatan(x)Returns the arctangent of x. The return values are in the range [-pi/2, pi/2].
atan2atan2(y, x)Returns the arctangent of y/x. The signs of y and x are used to determine the quadrant of the return values in the range [-pi, pi]. atan2 is well-defined for every point other than the origin, even if x equals 0 and y does not equal 0.
ceilceil(x)Returns the smallest integer which is greater than or equal to x.
clampclamp(x, min, max)Clamps x to the range [min, max].
clipclip(x)Discards the current pixel, if any component of x is less than zero. This can be used to simulate clip planes, if each component of x represents the distance from a plane.
coscos(x)Returns the cosine of x.
coshcosh(x)Returns the hyperbolic cosine of x.
crosscross(a, b)Returns the cross product of two 3-D vectors a and b.
D3DCOLORtoUBYTE4D3DCOLORtoUBYTE4(x)Swizzles and scales components of the 4-D vector x to compensate for the lack of UBYTE4 support in some hardware.
ddxddx(x)Returns the partial derivative of x with respect to the screen-space x-coordinate.
ddyddy(x)Returns the partial derivative of x with respect to the screen-space y-coordinate.
degreesdegrees(x)Converts x from radians to degrees.
determinantdeterminant(m)Returns the determinant of the square matrix m.
distancedistance(a, b)Returns the distance between two points a and b.
dotdot(a, b)Returns the dot product of two vectors a and b.
expexp(x)Returns the base-e exponent ex.
exp2value exp2(value a)Base 2 Exp (per component).
faceforwardfaceforward(n, i, ng)Returns -n * sign(dot(i, ng)).
floorfloor(x)Returns the greatest integer which is less than or equal to x.
fmodfmod(a, b)Returns the floating point remainder f of a / b such that a = i * b + f, where i is an integer, f has the same sign as x, and the absolute value of f is less than the absolute value of b.
fracfrac(x)Returns the fractional part f of x, such that f is a value greater than or equal to 0, and less than 1.
frcvalue frc(value a)Fractional part (per component).
frexpfrexp(x, out exp)Returns the mantissa and exponent of x. frexp returns the mantissa, and the exponent is stored in the output parameter exp. If x is 0, the function returns 0 for both the mantissa and the exponent.
fwidthfwidth(x)Returns abs(ddx(x))+abs(ddy(x)).
isfiniteisfinite(x)Returns true if x is finite, false otherwise.
isinfisinf(x)Returns true if x is +INF or -INF, false otherwise.
isnanisnan(x)Returns true if x is NAN or QNAN, false otherwise.
ldexpldexp(x, exp)Returns x * 2exp.
lenfloat len(value a)Vector length.
lengthlength(v)Returns the length of the vector v.
lerplerp(a, b, s)Returns a + s(b - a). This linearly interpolates between a and b, such that the return value is a when s is 0, and b when s is 1.
litlit(ndotl, ndoth, m)Returns a lighting vector (ambient, diffuse, specular, 1): ambient = 1; diffuse = (ndotl < 0) ? 0 : ndotl; specular = (ndotl < 0) || (ndoth < 0) ? 0 : (ndoth * m);
loglog(x)Returns the base-e logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF.
log10log10(x)Returns the base-10 logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF.
log2log2(x)Returns the base-2 logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF.
maxmax(a, b)Selects the greater of a and b.
minmin(a, b)Selects the lesser of a and b.
modfmodf(x, out ip)Splits the value x into fractional and integer parts, each of which has the same sign and x. The signed fractional portion of x is returned. The integer portion is stored in the output parameter ip.
mulmul(a, b)Performs matrix multiplication between a and b. If a is a vector, it treated as a row vector. If b is a vector, it is treated as a column vector. The inner dimension acolumns and brows must be equal. The result has the dimension arows x bcolumns.
noisenoise(x)Not yet implemented.
normalizenormalize(v)Returns the normalized vector v / length(v). If the length of v is 0, the result is indefinite.
powpow(x, y)Returns xy.
radiansradians(x)Converts x from degrees to radians.
reflectreflect(i, n)Returns the reflection vector v, given the entering ray direction i, and the surface normal n. Such that v = i - 2 * dot(i, n) * n
refractrefract(i, n, eta)Returns the refraction vector v, given the entering ray direction i, the surface normal n, and the relative index of refraction eta. If the angle between i and n is too great for a given eta, refract returns (0,0,0).
roundround(x)Rounds x to the nearest integer.
rsqrtrsqrt(x)Returns 1 / sqrt(x).
saturatesaturate(x)Clamps x to the range [0, 1].
signsign(x)Computes the sign of x. Returns -1 if x is less than 0, 0 if x equals 0, and 1 if x is greater than zero.
sinsin(x)Returns the sine of x.
sincossincos(x, out s, out c)Returns the sine and cosine of x. sin(x) is stored in the output parameter s. cos(x) is stored in the output parameter c.
sinhsinh(x)Returns the hyperbolic sine of x.
smoothstepsmoothstep(min, max, x)Returns 0 if x < min. Returns 1 if x > max. Returns a smooth Hermite interpolation between 0 and 1, if x is in the range [min, max].
sqrtvalue sqrt(value a)Square root (per component).
stepstep(a, x)Returns (x >= a) ? 1 : 0.
tantan(x) Returns the tangent of x.
tanhtanh(x)Returns the hyperbolic tangent of x.
tex1Dtex1D(s, t)1-D texture lookup. s is a sampler or a sampler1D object. t is a scalar.
tex1Dtex1D(s, t, ddx, ddy)1-D texture lookup, with derivatives. s is a sampler or sampler1D object. t, ddx, and ddy are scalars.
tex1Dprojtex1Dproj(s, t)1-D projective texture lookup. s is a sampler or sampler1D object. t is a 4-D vector. t is divided by its last component before the lookup takes place.
tex1Dbiastex1Dbias(s, t)1-D biased texture lookup. s is a sampler or sampler1D object. t is a 4-D vector. The mip level is biased by t.w before the lookup takes place.
tex2Dtex2D(s, t)2-D texture lookup. s is a sampler or a sampler2D object. t is a 2-D texture coordinate.
tex2Dtex2D(s, t, ddx, ddy)2-D texture lookup, with derivatives. s is a sampler or sampler2D object. t, ddx, and ddy are 2-D vectors.
tex2Dprojtex2Dproj(s, t)2-D projective texture lookup. s is a sampler or sampler2D object. t is a 4-D vector. t is divided by its last component before the lookup takes place.
tex2Dbiastex2Dbias(s, t)2-D biased texture lookup. s is a sampler or sampler2D object. t is a 4-D vector. The mip level is biased by t.w before the lookup takes place.
tex3Dtex3D(s, t)3-D volume texture lookup. s is a sampler or a sampler3D object. t is a 3-D texture coordinate.
tex3Dtex3D(s, t, ddx, ddy)3-D volume texture lookup, with derivatives. s is a sampler or sampler3D object. t, ddx, and ddy are 3-D vectors.
tex3Dprojtex3Dproj(s, t)3-D projective volume texture lookup. s is a sampler or sampler3D object. t is a 4-D vector. t is divided by its last component before the lookup takes place.
tex3Dbiastex3Dbias(s, t)3-D biased texture lookup. s is a sampler or sampler3D object. t is a 4-D vector. The mip level is biased by t.w before the lookup takes place.
texCUBEtexCUBE(s, t)3-D cube texture lookup. s is a sampler or a samplerCUBE object. t is a 3-D texture coordinate.
texCUBEtexCUBE(s, t, ddx, ddy)3-D cube texture lookup, with derivatives. s is a sampler or samplerCUBE object. t, ddx, and ddy are 3-D vectors.
texCUBEprojtexCUBEproj(s, t)3-D projective cube texture lookup. s is a sampler or samplerCUBE object. t is a 4-D vector. t is divided by its last component before the lookup takes place.
texCUBEbiastexCUBEbias(s, t)3-D biased cube texture lookup. s is a sampler or samplerCUBE object. t is a 4-dimensional vector. The mip level is biased by t.w before the lookup takes place.
transposetranspose(m)Returns the transpose of the matrix m. If the source is dimension mrows x mcolumns, the result is dimension mcolumns x mrows.

Shader Semantics

Vertex Shader Input Semantics

Input semantics are annotations that identify data usage for the vertex shader input data. This is similar to the D3DDECLUSAGE parameter in the fixed function pipeline.

POSITION[n]position
BLENDWEIGHT[n]blend weights
BLENDINDICES[n]blend indices
NORMAL[n]normal vector
PSIZE[n]point size
DIFFUSE[n]diffuse color
SPECULAR[n]specular color
TEXCOORD[n]texture coordinates
TANGENT[n]tangent
BINORMAL[n]binormal
TESSFACTOR[n]tessellation factor

n is an optional, integer. As an example, PSIZE0, DIFFUSE1, etc.

Vertex Shader Output Semantics

Output semantics are annotations that identify data usage for the vertex shader output data. This is similar to the D3DDECLUSAGE parameter in the fixed function pipeline.

POSITIONPosition
PSIZEPoint size
FOGVertex fog
COLOR[n]Color (example: COLOR0)
TEXCOORD[n]Texture coordinates (example: TEXCOORD0)

n is an optional, integer. As an example, texcoord0.

Pixel Shader Input Semantics

Input semantics are annotations that identify data usage for the pixel shader input data. This is similar to the D3DDECLUSAGE parameter in the fixed function pipeline.

COLOR[n]Diffuse of specular color (example: COLOR0 or COLOR1)
TEXCOORD[n]Texture coordinates (example: TEXCOORD0)

n is an optional, integer. As an example, TEXCOORD0, TEXCOORD1, etc.

Pixel Shader Output Semantics

Output semantics are annotations that identify data usage for the pixel shader output data.

COLOR[n]Color (example: COLOR0)
TEXCOORD[n]Texture coordinates (example: TEXCOORD0)

n is an optional, integer. As an example, texcoord0.

Examples

Glow Example

See Apply a Glow.

Indexed blended character skinning

//----------------------------------------------------------------------------
// Global parameters 
//----------------------------------------------------------------------------

texture tDiffuse;
texture tNormal;
 
float4 cAmbient  = { 0.3f, 0.3f, 0.3f, 1.0f };  // ambient color
float4 cDiffuse  = { 1.0f, 1.0f, 1.0f, 1.0f };  // diffuse color
float4 cSpecular = { 0.6f, 0.6f, 0.6f, 1.0f };  // specular color

float3 vDiffuse  = { 0.0f, 1.0f, 0.0f };        // diffuse direction
float3 vSpecular = { 0.0f, 0.0f, 0.0f };        // specular direction

struct VS_INPUT
{
    float4 vPosition        : POSITION;
    float3 vBlendWeights    : BLENDWEIGHT;
    float4 vBlendIndices    : BLENDINDICES;
    float3 vNormal          : NORMAL;
    float2 vTexCoords       : TEXCOORD0;
    float3 vTangent         : TANGENT;
    float  fFlip            : TEXCOORD1;
    float  fDisplacement    : TEXCOORD2;   
};

struct VS_OUTPUT
{
    float4 vPosition        : POSITION;
    float4 vTexCoord0       : TEXCOORD0;
    float4 vTexCoord1       : TEXCOORD1;
    float3 vDiffuse         : COLOR0;
    float3 vSpecular        : COLOR1;
};

struct PS_OUTPUT
{
    float4 vColor           : COLOR0;
};


//----------------------------------------------------------------------------
// Shader body 
//----------------------------------------------------------------------------

VS_OUTPUT main(const VS_INPUT v)
{
    VS_OUTPUT o = (VS_OUTPUT) 0;


    // Compute last blend weight.
    // An application supplies one fewer bone weights than 
    //   the number of bones. So, the last bone weight is 
    //   calculated using a dot product.

    float fLastBlendWeight = 1 - dot(v.vBlendWeights, 1);

    // The dot product is a convenient way of subtracting 
    //   the other three weights from 1.



    // Skin position(to world space)    
    // Each vertex is influenced by four bones. Each bone 
    //   must be transformed to world space, and then the result 
    //   is combined using the bone weight.
 
    float3 vPosition = 
        mul(v.vPosition, mWorld[v.vBlendIndices.x]) * v.vBlendWeights.x +
        mul(v.vPosition, mWorld[v.vBlendIndices.y]) * v.vBlendWeights.y +
        mul(v.vPosition, mWorld[v.vBlendIndices.z]) * v.vBlendWeights.z +
        mul(v.vPosition, mWorld[v.vBlendIndices.w]) * fLastBlendWeight;



    // Each normal is also influenced by four bones. Because normals 
    //   cannot be transformed using the world matrix (because they 
    //   end up with orientation problems if x,y,z scaling is not 
    //   uniform), normals need to be transformed using an 
    //   inverse-transpose matrix (mNormal). Otherwise, the mathematics 
    //   is nearly the same (the data types are different) as the 
    //   vertex position computation.

    // Skin normal (to world space)
    float3 vNormal =
        mul(v.vNormal, mNormal[v.vBlendIndices.x]) * v.vBlendWeights.x +
        mul(v.vNormal, mNormal[v.vBlendIndices.y]) * v.vBlendWeights.y +
        mul(v.vNormal, mNormal[v.vBlendIndices.z]) * v.vBlendWeights.z +
        mul(v.vNormal, mNormal[v.vBlendIndices.w]) * fLastBlendWeight;

  
    // Skin tangent (to world space)
    // A tangent is also influenced by four bones. Tangents, like 
    //   normals, cannot be transformed using the world matrix 
    //   (because they end up with orientation problems if x,y,z 
    //   scaling is not uniform). Tangents need to be transformed 
    //   using the inverse-transpose matrix (mNormal). Otherwise, the transform 
    //   is the same for tangents as it is for normals - each tangent 
    //   is transformed into world space ( using the world matrix 
    //   transpose ) resulting in 4 possible tangent vectors. Weights 
    //   are used to combine all four tangent vectors into a final 
    //   tangent vector.
 
    float3 vTangent =
        mul(v.vTangent, mNormal[v.vBlendIndices.x]) * v.vBlendWeights.x +
        mul(v.vTangent, mNormal[v.vBlendIndices.y]) * v.vBlendWeights.y +
        mul(v.vTangent, mNormal[v.vBlendIndices.z]) * v.vBlendWeights.z +
        mul(v.vTangent, mNormal[v.vBlendIndices.w]) * fLastBlendWeight;



    // Compute binormal
    // The binormal vector is the third axis in tangent space. You already 
    //   have the vertex normal vector and the vertex tangent vector. So, 
    //   a cross product will give you the third axis that is perpendicular 
    //   to the other two axes. To generate an axis in left-handed 
    //   coordinates, the result has to be flipped.
		
    float3 vBinormal = cross(vNormal, vTangent) * v.fFlip;        



    // Light direction (to vertex space)
    // Load the vertex tangent, bi-normal, and normal unit vectors 
    //   into a matrix for transforming the light direction vector.

    float3x3 mLight =  
        float3x3(vTangent.x, vBinormal.x, vNormal.x,
                 vTangent.y, vBinormal.y, vNormal.y, 
                 vTangent.z, vBinormal.z, vNormal.z);


    // Displace position    
    // To find the final vertex position, move each vertex with 
    // displacement data in the direction of the normal vector and 
    // transform the vertices into projection space.

    o.vPosition = mul(float4(vPosition + vNormal * v.fDisplacement, 1), 
                      mViewProj);    


    // vDiffuse and vSpecular contain the lights diffuse and specular 
    //   direction. This is a float3 vector. Theses direction vectors 
    //   need to be transformed to projection space also. Once transformed, 
    //   the direction vectors may contain components between -1 and +1. 
    // Because they are being loaded into the pixel shader diffuse and 
    //   specular registers, the data needs to be in the 0 to +1 range. 
    // The data is converted by scaling (* 0.5) and biasing (+ 0.5) 
    //   the data.
 
    o.vDiffuse  = mul(vDiffuse, mLight) * 0.5 + 0.5;
    o.vSpecular = mul(vSpecular, mLight) * 0.5 + 0.5;


    // No change is needed for the texture coordinates, so copy them 
    //   as is to both sets of output texture coordinates.

    o.vTexCoord0.xy = o.vTexCoord1.xy = v.vTexCoords.xy;


    return o;
}

sampler DiffuseMap = sampler_state
{
Texture   = <tDiffuse>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
};

sampler NormalMap = sampler_state
{
Texture   = <tNormal>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
};


technique T0
{
    pass P0
    {
        // Vertex shader
        VertexShader = compile vs_1_1 main();

        // Pixel shader
        PixelShader =
            asm
            {
                ps_1_1
                tex t0
                tex t1

                // Specular
                dp3_sat r1, t1_bx2, v1_bx2
                dp3_x4  r0, t1_bx2, v0_bx2

                mul_sat r1, r1, r0
                mul_sat r1, r1, r1
                mul_sat r1, r1, c2

                // Diffuse + Ambient
                dp3_sat r0, t1_bx2, v0_bx2          
                mad_sat r0, r0, c1, c0
                mad_sat r0, r0, t0, r1
            };

        PixelShaderConstant1[0] = <cAmbient>;
        PixelShaderConstant1[1] = <cDiffuse>;
        PixelShaderConstant1[2] = <cSpecular>;

        Sampler[0] = (DiffuseMap);
        Sampler[1] = (NormalMap);

        // Clip/Raster state
        CullMode = CW;
    }
}


Appendix

Keywords

Keywords are predefined reserved identifiers that have special meanings. They cannot be used as identifiers in your program. The following keywords are reserved. (Keywords marked with '*' are case insensitive.

asm*boolcompileconst
decl *dodoubleelse
externfalsefloatfor
halfif ininline
inoutintmatrixout
pass *pixelshaderreturnsampler
sharedstaticstringstruct
technique *texturetruetypedef
uniformvectorvertexshadervoid
volatilewhile

The following keywords are unused, but are reserved.

asm*boolcompileconst
autobreakcasecatch
charclassconst_castcontinue
defaultdeletedynamic_castenum
explicitfriendgotolong
mutablenamespacenewoperator
privateprotectedpublicregister
reinterpret_castshortsignedsizeof
static_castswitchtemplatethis
throwtrytypenameunion
unsignedusingvirtual

Preprocessor Directives

The preprocessor recognizes the following directives. These are all implemented to be compatible with the Microsoft Visual C++?preprocessor, except as noted below. Please refer to the Visual C++ documentation for a full description of these directives.

#define#elif#else#endif
#error#if#ifdef#ifndef
#include#linepragma#undef
#row_major#column_major

Function-style #defines are not yet implemented. The following tokens are automatically defined.

#define D3DX
#define D3DX_VERSION 0x0900
#define DIRECT3D
#define DIRECT3D_VERSION 0x0900
#define __FILE__ 
#define __LINE__ 

The #include directive is valid only when compiling from a file. The filename specified can be either an absolute or relative path. If it is a relative path, it is assumed to be relative to the directory of the file issuing the #include. Because there is no concept of an INCLUDE path, the <filename> syntax is unsupported and invalid. Use "filename" instead.

There are no defined uses for the #pragma directive yet; unrecognized pragmas are silently ignored.

row_major and column_major specify how a matrix variable is stored. Some examples and their sizes:

row_major half1x4 fh1By4;
column_major half1x4 fh4By1;
row_major half3x2 fh3By2;
column_major half3x2 fh2By3;

//   matrix name   constant register   size
//     fh4By1            c620           4
//     fh3By2            c624           3
//     fh2By3            c627           2
//     fh1By4            c636           1

These can also be specified by compiler pragma's.

#pragma PACK_MATRIX (ROW_MAJOR)
#pragma PACK_MATRIX (COLUMN_MAJOR)

Register is used to specify a particular constant to associate with a variable. For instance:

float4 vColor : register(vs_2_0, c14) ;  

associates the variable vColor with register c14.

Other examples include:

float4 vDisplace : register (c0); // puts the vDisplace constant into C0

It can be used in more complicated expressions like:

float4 vDisplace : register (c0)    

which puts the vDisplace constant into C0 for pixel shader versions != 2.0.

float4 vDisplace : register(vs, c10)

which puts the vDisplace constant into C10 for all vertex shaders.

float4 vDisplace : register(ps_2_0, c10) 

which puts the vDisplace constant into C10 for pixel shader version 2.0

Lexical Conventions

Whitespace

SPACE
TAB
EOL
C style comments (/* */)
C++ style comments (//)
Assembly style comments in asm blocks (;)

Floating point numbers

Integer numbers

Characters

'c'(character)
'\a' '\b' '\f' '\b' '\r' '\t' '\v'(escapes)
'\###'(octal escape, each # is an octal digit)
'\x#'(hex escape, # is hex number, any number of digits)
'\c'(c is other character, including backslash and quotation marks)

Escapes are not supported in preprocessor expressions.

Strings

"s" (s is any string with escapes).

Identifiers

	[A-Za-z_][A-Za-z0-9_]*

Operators

	##, #@, ++, --, &&, ||, ==, ::, <<, <<=, >>, >>=, ..., 
	<=, >=, !=, *=, /=, +=, -=, %=, &=, |=, ^=, ->

Also any other single character that did not match another rule.

Language Syntax

Program Options

///////////////////////////////////////////////////
Program         :
                | Decls
                ;
///////////////////////////////////////////////////
Decls           : Decl
                | Decl Decls
                ;
///////////////////////////////////////////////////
Decl            : TypeDecl
                | VariableDecl
                | VarStructDecl
                | FunctionDecl
                | TechniqueDecl
                ;
///////////////////////////////////////////////////

Usages

///////////////////////////////////////////////////
Usages          : Usage
                | Usage Usages
                ;
///////////////////////////////////////////////////
Usage           : T_KW_STATIC
                | T_KW_UNIFORM
                | T_KW_EXTERN
                | T_KW_VOLATILE
                | T_KW_INLINE
                | T_KW_SHARED
                | Target
                ;
///////////////////////////////////////////////////
UsageType       : Type
                | Usages Type
                ;
///////////////////////////////////////////////////
UsageStructDef  : StructDef
                | Usages StructDef
                ;
///////////////////////////////////////////////////

Types

TypeDecl        : T_KW_TYPEDEF Type TypeDefs ';'
                | StructDef ';'
                ;
///////////////////////////////////////////////////
TypeDefs        : VariableDim
                | VariableDim ',' TypeDefs
                ;
///////////////////////////////////////////////////
TypeDim         : Type
                | TypeDim '[' ConstantExpr ']'
                ;
///////////////////////////////////////////////////
Type            : SimpleType
                | T_KW_CONST SimpleType
                ;
///////////////////////////////////////////////////
SimpleType      : BaseType
                | Struct
                | TypeId
                ;
///////////////////////////////////////////////////
BaseType        : T_KW_VOID
                | ScalarType
                | VectorType
                | MatrixType
                | ObjectType
                ;
///////////////////////////////////////////////////
ScalarType      : T_KW_BOOL
                | T_KW_INT
                | T_KW_HALF
                | T_KW_FLOAT
                | T_KW_DOUBLE
                ;
///////////////////////////////////////////////////
VectorType      : T_KW_VECTOR
                | T_KW_VECTOR '<' ScalarType ',' AddExpr '>'
                ;
///////////////////////////////////////////////////
MatrixType      : T_KW_VECTOR
                | T_KW_VECTOR '<' ScalarType ',' ConstantExpr ',' AddExpr '>'
                ;
///////////////////////////////////////////////////
ObjectType      : T_KW_STRING
                | T_KW_TEXTURE
                | T_KW_SAMPLER
                | T_KW_PIXELSHADER
                | T_KW_VERTEXSHADER
                ;
///////////////////////////////////////////////////

Structures

///////////////////////////////////////////////////
Struct          : T_KW_STRUCT StructStart StructEnd
                | T_KW_STRUCT StructStart StructDecls StructEnd
                ;
///////////////////////////////////////////////////
StructDef       : SimpleStructDef
                | T_KW_CONST SimpleStructDef
                ;
///////////////////////////////////////////////////
SimpleStructDef : T_KW_STRUCT Id StructStart StructEnd
                | T_KW_STRUCT Id StructStart StructDecls StructEnd
                ;
///////////////////////////////////////////////////
StructStart     : '{'
                ;
///////////////////////////////////////////////////
StructDecls     : VariableDecl
                | VariableDecl StructDecls
                ;
///////////////////////////////////////////////////
StructEnd       : '}'
                ;
///////////////////////////////////////////////////

Annotations

///////////////////////////////////////////////////
Annotation      : AnnotationStart AnnotationEnd 
                | AnnotationStart AnnotationDecls AnnotationEnd 
                ;
///////////////////////////////////////////////////
AnnnotationStart : '{'
                 ;
///////////////////////////////////////////////////
AnnotationDecls : VariableDecl
                | VariableDecl AnnotationDecls
                ;
///////////////////////////////////////////////////
AnnotationEnd   : '}'
                ;
///////////////////////////////////////////////////

Variables

///////////////////////////////////////////////////
VariableDecl    : UsageType Variables ';'
                ;
///////////////////////////////////////////////////
VarStructDecl   : UsageStructDef Variables ';'
                ;
///////////////////////////////////////////////////
Variables       : Variable
                | Variable ',' Variables
                ;
///////////////////////////////////////////////////
Variable        : VariableAnn
                | VariableAnn '=' InitExpr
                ;
///////////////////////////////////////////////////
VariableAnn     : VariableSem
                | VariableSem Annotation
                ;
///////////////////////////////////////////////////
VariableSem     : VariableDim
                | VariableDim ':' Id
                ;
///////////////////////////////////////////////////
VariableDim     : Id
                | VariableDim '[' ConstantExpr ']'
                ;
///////////////////////////////////////////////////

Functions

///////////////////////////////////////////////////
FunctionDecl    : FunctionDef FunctionBody
                ;
///////////////////////////////////////////////////
FunctionDef     : UsageType Id ParamList
                | UsageType Id ParamList ':' Id
                ;
///////////////////////////////////////////////////
FunctionBody    : ';'
                | StmtBlock
                ;
///////////////////////////////////////////////////
ParamList       : ParamListStart ParamListEnd
                | ParamListStart T_KW_VOID ParamListEnd
                | ParamListStart ParameterDecls ParamListEnd
                ;
///////////////////////////////////////////////////
ParamListStart  : '('
                ;
///////////////////////////////////////////////////
ParamListEnd    : ')'
                ;
///////////////////////////////////////////////////
ParameterDecls  : ParameterDecl
                | ParameterDecl ',' ParameterDecls
                ;
///////////////////////////////////////////////////
ParameterDecl   : ParamUsageType Variable
                ;
///////////////////////////////////////////////////
ParamUsageType  : Type
                : ParamUsages Type
                ;
///////////////////////////////////////////////////
ParamUsages     : ParamUsage
                : ParamUsage ParamUsages
                ;
///////////////////////////////////////////////////
ParamUsages     : T_KW_IN
                : T_KW_OUT
                : T_KW_INOUT
                : T_KW_UNIFORM
                ;
///////////////////////////////////////////////////

Techniques

///////////////////////////////////////////////////
TechniqueDecl   : T_KW_TECHNIQUE TechniqueBegin TechniqueEnd
                | T_KW_TECHNIQUE Id TechniqueBegin TechniqueEnd
                ;
///////////////////////////////////////////////////
TechniqueBegin  : '{'
                ;
///////////////////////////////////////////////////
TechniqueEnd    : '}'
                | Passes '}'
                ;
///////////////////////////////////////////////////
Passes          : Pass
                | Pass Passes
                ;
///////////////////////////////////////////////////
Pass            : T_KW_PASS PassBegin PassEnd
                | T_KW_PASS Id PassBegin PassEnd
                | VariableDecl
                ;
///////////////////////////////////////////////////
PassBegin       : '{'
                ;
///////////////////////////////////////////////////
PassEnd         : '}'
                | States '}'
                ;
///////////////////////////////////////////////////
States          : State
                | State States
                ;
///////////////////////////////////////////////////
State           : Id StateExprBegin StateExpr StateExprEnd
                | Id '[' Uint ']' StateExprBegin StateExpr StateExprEnd
                ;
///////////////////////////////////////////////////
StateExprBegin  : '='
                ;
///////////////////////////////////////////////////
StateExprEnd    : DwordExpr ';'
                ;
///////////////////////////////////////////////////

Statements

SimpleStmt      : ';'
                | Expr ';'
                | T_KW_RETURN ';'
                | T_KW_RETURN Expr ';'
                | T_KW_DO Stmt T_KW_WHILE '(' Expr ')' ';'
                | StmtBlock
                ;
///////////////////////////////////////////////////
NonIfStmt       : SimpleStmt
                | T_KW_WHILE '(' Expr ')' NonIfStmt
                | T_KW_FOR '(' ForInit ForCond ForStep ')' NonIfStmt
                ;
///////////////////////////////////////////////////
Stmt            : SimpleStmt
                | T_KW_WHILE '(' Expr ')' Stmt
                | T_KW_FOR '(' ForInit ForCond ForStep ')' Stmt
                | T_KW_IF '(' Expr ')' Stmt
                | T_KW_IF '(' Expr ')' NonIfStmt T_KW_ELSE Stmt
                ;
///////////////////////////////////////////////////
ForInit         : ';'
                | Expr ';'
                | VariableDecl
                ;
///////////////////////////////////////////////////
ForCond         : ';'
                | Expr ';'
                ;
///////////////////////////////////////////////////
ForStep         :
                | Expr
                ;
///////////////////////////////////////////////////
DeclStmt        : TypeDecl
                | VariableDecl
                | VarStructDecl
                | Stmt
                ;
///////////////////////////////////////////////////
DeclStmts       : DeclStmt
                | DeclStmt DeclStmts
                ;
///////////////////////////////////////////////////
StmtBlock       : StmtBlockStart StmtBlockEnd
                | StmtBlockStart DeclStmts StmtBlockEnd
                ;
///////////////////////////////////////////////////
StmtBlockStart  : '{'
                ;
///////////////////////////////////////////////////
StmtBlockEnd    : '}'
                ;
///////////////////////////////////////////////////

Expressions

///////////////////////////////////////////////////
DwordExpr       : Dword
                | Dword '|' DwordExpr 
                ;
///////////////////////////////////////////////////
StateExpr       : DwordExpr
                | ComplexExpr 
                | '{' InitExprs '}' 
                | '<' RelationalExpr '>'
                ;
///////////////////////////////////////////////////
SimpleExpr      : T_KW_TRUE
                | T_KW_FALSE
                | UINT
                | Float
                | String
                | NonTypeId
                ;
///////////////////////////////////////////////////
ComplexExpr     : '(' Expr ')'
                | TypeId '(' ArgumentExprs ')'
                | BaseType '(' ArgumentExprs ')'
                | NonTypeId '(' ArgumentExprs ')'
				| Asm
				| AsmDecl
				| AsmDecl Asm
				| T_KW_COMPILE Target NonTypeId '(' ArgumentExpr ')'
                ;
///////////////////////////////////////////////////
Primary         : SimpleExpr
                | ComplexExpr
                ;
///////////////////////////////////////////////////
PostfixExpr     : PrimaryExpr
                | PostfixExpr '[' Expr ']'
                | PostfixExpr '.' Id
                | PostfixExpr T_OP_INC
                | PostfixExpr T_OP_DEC
                ;
///////////////////////////////////////////////////
UnaryExpr       : PostfixExpr
                | T_OP_INC UnaryExpr
                | T_OP_DEC UnaryExpr
                | '!' CastExpr
                | '-' CastExpr
                | '+' CastExpr
                ;
///////////////////////////////////////////////////
CastExpr        : UnaryExpr
                | '(' TypeDim ')' CastExpr
                ;
///////////////////////////////////////////////////
MulExpr         : CastExpr
                | MulExpr '*' CastExpr
                | MulExpr '/' CastExpr
                | MulExpr '%' CastExpr
                ;
///////////////////////////////////////////////////
AddExpr         : MulExpr
                | AddExpr '+' MulExpr
                | AddExpr '-' MulExpr
                ;
///////////////////////////////////////////////////
RelationalExpr  : AddExpr
                | RelationalExpr '<' AddExpr
                | RelationalExpr '>' AddExpr
                | RelationalExpr T_OP_LE AddExpr
                | RelationalExpr T_OP_GE AddExpr
                ;
///////////////////////////////////////////////////
EqualityExpr    : RelationalExpr
                | EqualityExpr T_OP_EQ RelationalExpr
                | EqualityExpr T_OP_NE RelationalExpr
                ;
///////////////////////////////////////////////////
AndExpr         : EqualityExpr
                | AndExpr T_OP_AND EqualityExpr
                ;
///////////////////////////////////////////////////
OrExpr          : AndExpr
                | OrExpr T_OP_OR AndExpr
                ;
///////////////////////////////////////////////////
AssignmentExpr  : OrExpr
                | CastExpr '=' AssignmentExpr
                | CastExpr T_OP_ME AssignmentExpr
                | CastExpr T_OP_DE AssignmentExpr
                | CastExpr T_OP_RE AssignmentExpr
                | CastExpr T_OP_AE AssignmentExpr
                | CastExpr T_OP_SE AssignmentExpr
                ;
///////////////////////////////////////////////////
ConditionalExpr : AssignmentExpr
                | AssignmentExpr  '?' AssignmentExpr  ':' ConditionalExpr
                ;
///////////////////////////////////////////////////
ArgumentExprs   : ConditionalExpr
                | ConditionalExpr ',' ArgumentExprs
                ;
///////////////////////////////////////////////////
ArgumentExpr    : ArgumentExpr
                ;
///////////////////////////////////////////////////
ArgumentExprs   : ArgumentExpr
                ;
///////////////////////////////////////////////////
InitExpr        : ConditionalExpr
                | '{' InitExprs '}'
                ;
///////////////////////////////////////////////////
InitExprs       : InitExpr
                | InitExpr ',' InitExprs
                ;
///////////////////////////////////////////////////
ConstantExpr    : ConditionalExpr
                ;
///////////////////////////////////////////////////
Expr            : ConditionalExpr
                | ConditionalExpr ',' Expr
                ;
///////////////////////////////////////////////////

Tokens

///////////////////////////////////////////////////
Dword           : Uint
                | '-' Uint
                | Float
                | '-' Float
                | DwordId
                | Uint DwordId
                ;
///////////////////////////////////////////////////
DwordId         : Id
                | T_KW_TRUE
                | T_KW_FALSE
                | T_KW_TEXTURE
                ;
///////////////////////////////////////////////////
Id              : TypeId
                | NonTypeId
                ;
///////////////////////////////////////////////////
Target          : NonTypeId
                ;
///////////////////////////////////////////////////
Uint            : T_UINT
                | T_INT32
                | T_UINT32
                ;
///////////////////////////////////////////////////
Float           : T_FLOAT
                | T_FLOAT16
                | T_FLOAT32
                | T_FLOAT64
                ;
///////////////////////////////////////////////////
String          : T_STRING
                ;
///////////////////////////////////////////////////
TypeId          : T_TYPE_ID
                ;
///////////////////////////////////////////////////
NonTypeId       : T_NON_TYPE_ID
                ;
///////////////////////////////////////////////////
Asm             : T_KW_ASM '{'
                ;
///////////////////////////////////////////////////
AsmDecl         : T_KW_DECL '{'
                ;
///////////////////////////////////////////////////


© 2002 Microsoft Corporation. All rights reserved.