?/TD> |
Microsoft DirectX 9.0 |
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.
bool | true of false |
int | 32-bit signed integer |
half | 16-bit floating point value |
float | 32-bit floating point value |
double | 64-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 | A 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 | A 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.
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.
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();
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; };
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;
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.
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.
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 vectorVECTOR; 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 vectorbool#; 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#;
Scalar-to-scalar | Always 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-vector | Always valid. This cast operates by replicating the scalar to fill the vector. |
Scalar-to-matrix | Always valid. This cast operates by replicating the scalar to fill the matrix. |
Scalar-to-object | Never valid. |
Scalar-to-structure | Valid if all elements of the structure are numeric. This cast operates by replicating the scalar to fill the structure. |
Vector-to-scalar | Always valid. This selects the first component of the vector |
Vector-to-vector | The 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-matrix | The size of the vector must be equal to the size of the matrix. |
Vector-to-object | Never valid. |
Vector-to-structure | Valid if the structure is not larger than the vector, and all components of the structure are numeric. |
Matrix-to-scalar | Always valid. This selects the upper-left component of the matrix. |
Matrix-to-vector | The size of the matrix must be equal to the size of the vector. |
Matrix-to-matrix | The 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-object | Never valid. |
Matrix-to-structure | The size of the structure must be equal to the size of the matrix, and all components of the structure are numeric. |
Object-to-scalar | Never valid. |
Object-to-vector | Never valid. |
Object-to-matrix | Never valid. |
Object-to-object | Valid only if the object types are identical. |
Object-to-structure | The structure must not contain more than one member. The type of that member must be identical to the type of the object. |
Structure-to-scalar | The structure must contain at least one member. This member must be numeric. |
Structure-to-vector | The 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-matrix | The 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-object | The structure must contain at least one member. The type of this member must be identical to the type of the object. |
Structure-to-structure | The destination structure must not be larger than the source structure. A valid cast must exist between all respective source and destination components. |
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.
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 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 are literals, variables, or some combination of literals and variables composed using operators from the operator precedence table in the Appendix.
Operator | Usage | Meaning | Associativity |
---|---|---|---|
() | (value) | Sub expression | Left to right |
() | id(arguments) | Function call | Left to right |
type(arguments) | Type constructor | Left to right | |
[] | array[int] | Array subscript | Left to right |
. | structure.id | Member selection | Left to right |
value.swizzle | Component swizzle | Left to right | |
++ | variable++ | Postfix increment (per component) | Left to right |
-- | variable-- | Postfix decrement (per component) | Left to right |
++ | ++variable | Prefix increment (per component) | Right to left |
-- | --variable | Prefix decrement (per component) | Right to left |
! | !value | Logical not (per component) | Right to left |
- | -value | Unary minus (per component) | Right to left |
+ | +value | Unary plus (per component) | Right to left |
() | (type) value | Type cast | Right to left |
* | value*value | Multiplication (per component) | Left to right |
/ | value/value | Division (per component) | Left to right |
% | value%value | Modulus (per component) | Left to right |
+ | value+value | Addition (per component) | Left to right |
- | value-value | Subtraction (per component) | Left to right |
< | value < value | Less than (per component) | Left to right |
> | value > value | Greater than (per component) | Left to right |
<= | value <= value | Less than or equal to (per component) | Left to right |
>= | value >= value | Greater than or equal to (per component) | Left to right |
== | value == value | Equality (per component) | Left to right |
!= | value != value | Inequality (per component) | Left to right |
&& | value && value | Logical AND (per component) | Left to right |
|| | value||value | Logical OR (per component) | Left to right |
?: | float?value:value | Conditional | Right to left |
= | variable=value | Assignment (per component) | Right to left |
*= | variable*=value | Multiplication assignment (per component) | Right to left |
/= | variable/=value | Division assignment (per component) | Right to left |
%= | variable%=value | Modulus assignment (per component) | Right to left |
+= | variable+=value | Addition assignment (per component) | Right to left |
-= | variable-=value | Subtraction assignment (per component) | Right to left |
, | value,value | Comma | Left 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 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.
abs | value abs(value a) | Absolute value (per component). |
acos | acos(x) | Returns the arccosine of each component of x. Each component should be in the range [-1, 1]. |
all | all(x) | Test if all components of x are nonzero. |
any | any(x) | Test is any component of x is nonzero. |
asin | asin(x) | Returns the arcsine of each component of x. Each component should be in the range [-pi/2, pi/2]. |
atan | atan(x) | Returns the arctangent of x. The return values are in the range [-pi/2, pi/2]. |
atan2 | atan2(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. |
ceil | ceil(x) | Returns the smallest integer which is greater than or equal to x. |
clamp | clamp(x, min, max) | Clamps x to the range [min, max]. |
clip | clip(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. |
cos | cos(x) | Returns the cosine of x. |
cosh | cosh(x) | Returns the hyperbolic cosine of x. |
cross | cross(a, b) | Returns the cross product of two 3-D vectors a and b. |
D3DCOLORtoUBYTE4 | D3DCOLORtoUBYTE4(x) | Swizzles and scales components of the 4-D vector x to compensate for the lack of UBYTE4 support in some hardware. |
ddx | ddx(x) | Returns the partial derivative of x with respect to the screen-space x-coordinate. |
ddy | ddy(x) | Returns the partial derivative of x with respect to the screen-space y-coordinate. |
degrees | degrees(x) | Converts x from radians to degrees. |
determinant | determinant(m) | Returns the determinant of the square matrix m. |
distance | distance(a, b) | Returns the distance between two points a and b. |
dot | dot(a, b) | Returns the dot product of two vectors a and b. |
exp | exp(x) | Returns the base-e exponent ex. |
exp2 | value exp2(value a) | Base 2 Exp (per component). |
faceforward | faceforward(n, i, ng) | Returns -n * sign(dot(i, ng)). |
floor | floor(x) | Returns the greatest integer which is less than or equal to x. |
fmod | fmod(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. |
frac | frac(x) | Returns the fractional part f of x, such that f is a value greater than or equal to 0, and less than 1. |
frc | value frc(value a) | Fractional part (per component). |
frexp | frexp(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. |
fwidth | fwidth(x) | Returns abs(ddx(x))+abs(ddy(x)). |
isfinite | isfinite(x) | Returns true if x is finite, false otherwise. |
isinf | isinf(x) | Returns true if x is +INF or -INF, false otherwise. |
isnan | isnan(x) | Returns true if x is NAN or QNAN, false otherwise. |
ldexp | ldexp(x, exp) | Returns x * 2exp. |
len | float len(value a) | Vector length. |
length | length(v) | Returns the length of the vector v. |
lerp | lerp(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. |
lit | lit(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); |
log | log(x) | Returns the base-e logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF. |
log10 | log10(x) | Returns the base-10 logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF. |
log2 | log2(x) | Returns the base-2 logarithm of x. If x is negative, the function returns indefinite. If x is 0, the function returns +INF. |
max | max(a, b) | Selects the greater of a and b. |
min | min(a, b) | Selects the lesser of a and b. |
modf | modf(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. |
mul | mul(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. |
noise | noise(x) | Not yet implemented. |
normalize | normalize(v) | Returns the normalized vector v / length(v). If the length of v is 0, the result is indefinite. |
pow | pow(x, y) | Returns xy. |
radians | radians(x) | Converts x from degrees to radians. |
reflect | reflect(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 |
refract | refract(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). |
round | round(x) | Rounds x to the nearest integer. |
rsqrt | rsqrt(x) | Returns 1 / sqrt(x). |
saturate | saturate(x) | Clamps x to the range [0, 1]. |
sign | sign(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. |
sin | sin(x) | Returns the sine of x. |
sincos | sincos(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. |
sinh | sinh(x) | Returns the hyperbolic sine of x. |
smoothstep | smoothstep(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]. |
sqrt | value sqrt(value a) | Square root (per component). |
step | step(a, x) | Returns (x >= a) ? 1 : 0. |
tan | tan(x) | Returns the tangent of x. |
tanh | tanh(x) | Returns the hyperbolic tangent of x. |
tex1D | tex1D(s, t) | 1-D texture lookup. s is a sampler or a sampler1D object. t is a scalar. |
tex1D | tex1D(s, t, ddx, ddy) | 1-D texture lookup, with derivatives. s is a sampler or sampler1D object. t, ddx, and ddy are scalars. |
tex1Dproj | tex1Dproj(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. |
tex1Dbias | tex1Dbias(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. |
tex2D | tex2D(s, t) | 2-D texture lookup. s is a sampler or a sampler2D object. t is a 2-D texture coordinate. |
tex2D | tex2D(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. |
tex2Dproj | tex2Dproj(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. |
tex2Dbias | tex2Dbias(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. |
tex3D | tex3D(s, t) | 3-D volume texture lookup. s is a sampler or a sampler3D object. t is a 3-D texture coordinate. |
tex3D | tex3D(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. |
tex3Dproj | tex3Dproj(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. |
tex3Dbias | tex3Dbias(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. |
texCUBE | texCUBE(s, t) | 3-D cube texture lookup. s is a sampler or a samplerCUBE object. t is a 3-D texture coordinate. |
texCUBE | texCUBE(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. |
texCUBEproj | texCUBEproj(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. |
texCUBEbias | texCUBEbias(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. |
transpose | transpose(m) | Returns the transpose of the matrix m. If the source is dimension mrows x mcolumns, the result is dimension mcolumns x mrows. |
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.
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.
POSITION | Position |
PSIZE | Point size |
FOG | Vertex fog |
COLOR[n] | Color (example: COLOR0) |
TEXCOORD[n] | Texture coordinates (example: TEXCOORD0) |
n is an optional, integer. As an example, texcoord0.
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.
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.
See Apply a Glow.
//---------------------------------------------------------------------------- // 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; } }
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* | bool | compile | const |
decl * | do | double | else |
extern | false | float | for |
half | if | in | inline |
inout | int | matrix | out |
pass * | pixelshader | return | sampler |
shared | static | string | struct |
technique * | texture | true | typedef |
uniform | vector | vertexshader | void |
volatile | while |
The following keywords are unused, but are reserved.
asm* | bool | compile | const |
auto | break | case | catch |
char | class | const_cast | continue |
default | delete | dynamic_cast | enum |
explicit | friend | goto | long |
mutable | namespace | new | operator |
private | protected | public | register |
reinterpret_cast | short | signed | sizeof |
static_cast | switch | template | this |
throw | try | typename | union |
unsigned | using | virtual |
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 | #line | pragma | #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
SPACE |
TAB |
EOL |
C style comments (/* */) |
C++ style comments (//) |
Assembly style comments in asm blocks (;) |
digit-sequence exponent-part floating-suffix(opt)
digit-sequence(opt) . digit-sequence
digit-sequence .
e sign(opt) digit-sequence
E sign(opt) digit-sequence
+ -
digit
digit-sequence digit
h H f F
# (decimal number)
0# (octal number)
0x# (hex number)
u U l L
'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.
"s" (s is any string with escapes).
[A-Za-z_][A-Za-z0-9_]*
##, #@, ++, --, &&, ||, ==, ::, <<, <<=, >>, >>=, ..., <=, >=, !=, *=, /=, +=, -=, %=, &=, |=, ^=, ->
Also any other single character that did not match another rule.
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 '{' ; ///////////////////////////////////////////////////