INPUT REGISTERS

The input registers are how data gets passed to the vertex shader. Direct3D provides input vertex registers, which will contain input data to the vertex shader. What this data is depends upon the format of the vertex stream(s) that are currently active.

The other set of input registers is the constant registers, which are set up prior to running the vertex shader. It's up to you to correctly set up these registers. For example, you probably want to pass in the current modelview matrix, light positions, etc., prior to calling the shader.

c[n]: The Constant Registers

Aside from the actual instructions that you enter into your shader, you will most probably need to get values into those instructions, and you do it through the constant floating-point registers. They are called the float constant registers simply because they are floating point values that are read only once they are passed to the shader and the shader is running. However, you'll frequently find that you'll be setting values of the constant registers prior to the beginning of each frame of rendering (e.g., setting the world/model/projection matrix values), or even prior to each render primitive call (to set a primitive or shader-specific value).

One optimization made in the assembly of vertex shaders is that there can be only one constant register referenced from any single instruction. However, you may use that constant more than once, and each reference to the constant can independently swizzle or negate the constant's vector elements.

 add    r5,    v0     v0             // fine add    r5,    c1     c2             // Error! 3 different registers add    r5,    c5     c5             // fine - doubles r5 add    r5,    c5    -c5             // fine - zero in r5 add    r5    c5.xxxx,    c5.yyyy    // OK fills r5 with x+y 

The syntax that allowed for constant registers is also a little more complex. You can reference them like any other, or you can place the numeric part inside square brackets. DirectX 8.1 introduced the address register, a0.x, which allows you to have a programmable index into the constant registers. Some examples are shown next.

 mov    oD1, c5         // fine - regular way mov oD1, c[5]          // using brackets mov oD1, c[5+a0.x]     // fine for DX8.1+ 

There are two ways to get the constant registers loaded. One way is to use the def statement and then (in DirectX 8) postprocess this to add the generated shader code fragment to the shader. The preferred (and easier) way is to just set the values using SetVertexShaderConstant() to take a vector of four floats and store them in the specified register. You can set an array of constants using this call.

There are at least 96 float constant registers in DirectX 8 shaders, while there are at least 256 float constants in DirectX 9 vertex shaders. You could check the number specified in the MaxVertexShaderConst member of the D3DCAPS structure.

DirectX 9.0 Constant update

 

DirectX 9 also introduced 16 integer constants and 16 bool constants as well as modifying the way that constants can be set. In addition to the SetVertexShaderConstantx() calls, the def instruction in vertex shaders 2.0 now actually does something. When the def instruction is encountered in a shader, the current value of the temporary register specified is pushed then set immediately to that value for the life of the shader. These are called immediate constants. When the shader exits the constant register is popped back to its original value. Any call to get a constant's value will necessarily be done after the shader. The post processing step required in DirectX 8 shaders is no longer supported.

vn: The Input Vertex Registers

The input vertex registers contain the vertex information that the shader is going to work on. There are a total of sixteen input registers designated as v0 through v15. Each vertex register is read only and consists of a four-element floating point vector. A vertex shader instruction may access only one input register at a time, but may use that register more than once in that instruction.

The vertex information is taken from the current vertex stream(s) and loaded into the vertex registers, and then the shader is run. What is stored in them and their order are completely up to you, and will consist of things like the vertex position, normal, color values (diffuse, specular), texture coordinates, and blending values. You specify what's in each input vertex register when you declare a shader register and use it in SetStreamSource(). This is where the mapping between your input vertex stream and the input vertex shader registers occurs. See Chapter 5 for more details on setting up a mapping between a stream and the input registers.

If you are using the FVF formats in DirectX 8, then the input vertex registers are given to the shader in the following order:

Table 8.1: FVF Vertex Shader Register Mapping

VECTOR COMPONENT

FVF TAG

SHADER DECLARATION NAME

REGISTER

Position

D3DFVF_XYZ

D3DVSDE_POSITION

v0

Blend weight

D3DFVF_XYZRHW

D3DVSDE_BLENDWEIGHT

v1

Blend indices 1 through 5

D3DFVF_XYZB1 through D3DFVF_XYZB5

D3DVSDE_BLENDINDICES

v2

Normal

D3DFVF_NORMA

D3DVSDE_NORMAL

v3

Point size

D3DFVF_PSIZE

D3DVSDE_PSIZE

v4

Diffuse

D3DFVF_DIFFUSE

D3DVSDE_DIFFUSE

v5

Specular

D3DFVF_SPECULAR

D3DVSDE_SPECULAR

v6

Texture
coordinates

D3DFVF_TEXO
through
D3DFVF_TEX7

D3DVSDE_TEXCOORDO
through
D3DVSDE_TEXCOORD7

v
through
v14

Position 2

 

D3DVSDE_POSITION2

v15

Normal2

 

D3DVSDE_NORMAL2

v16



Real-Time Shader Programming(c) Covering Directx 9. 0
Real-Time Shader Programming (The Morgan Kaufmann Series in Computer Graphics)
ISBN: 1558608532
EAN: 2147483647
Year: 2005
Pages: 104
Authors: Ron Fosner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net