Variable Syntax
Use the following syntax rules to declare HLSL variables.
[Storage_Class] [Type_Modifier] Type Name[Index]
[: Semantic]
[: Packoffset]
[: Register];
[Annotations]
[= Initial_Value] |
Parameters
- Storage_Class
-
Optional storage-class modifiers that give the compiler hints about variable scope and lifetime; the modifiers can be specified in any order.
Value Description extern Mark a global variable as an external input to the shader; this is the default marking for all global variables. Cannot be combined with static. nointerpolation Do not interpolate the outputs of a vertex shader before passing them to a pixel shader. precise Prevent the compiler from making IEEE unsafe optimizations that affect this variable. For example, the compiler cannot use fused mul + add as an optimization. Instead, you must explicitly use the mad intrinsic function. The precise modifier also ensures that the compiler preserves the order of operations and that it must account for the possibility of NaN (not a number) and INF (infinite) values from constants and stream inputs. Without the precisemodifier, the compiler can perform optimizations and mathematical operations that do not account for NaN and INF values. These optimizations and mathematical operations are not IEEE safe. When you use the precise keyword, these optimizations are prohibited for all calculations that affect the variable. The ability to control optimizations in this way is useful when you write shaders for tessellation to maintain water-tight patch seams.
shared Mark a variable for sharing between effects; this is a hint to the compiler. groupshared Mark a variable for thread-group-shared memory for compute shaders. In D3D10 the maximum total size of all variables with the groupshared storage class is 16kb, in D3D11 the maximum size is 32kb. See examples. static Mark a local variable so that it is initialized one time and persists between function calls. If the declaration does not include an initializer, the value is set to zero. A global variable marked static is not visible to an application. uniform Mark a variable whose data is constant throughout the execution of a shader (such as a material color in a vertex shader); global variables are considered uniform by default. volatile Mark a variable that changes frequently; this is a hint to the compiler. This storage class modifier only applies to a local variable.
Note The HLSL compiler currently ignores this storage class modifier.
- Type_Modifier
-
Optional variable-type modifier.
Value Description const Mark a variable that cannot be changed by a shader, therefore, it must be initialized in the variable declaration. Global variables are considered const by default (suppress this behavior by supplying the /Gec flag to the compiler). row_major Mark a variable that stores four components in a single row so they can be stored in a single constant register. column_major Mark a variable that stores 4 components in a single column to optimize matrix math. Note If you do not specify a type-modifier value, the compiler uses column_major as the default value.
- Type
-
Any HLSL type listed in Data Types (DirectX HLSL).
- Name[Index]
-
ASCII string that uniquely identifies a shader variable. To define an optional array, use index for the array size, which is a positive integer ≥ 1.
- Semantic
-
Optional parameter-usage information, used by the compiler to link shader inputs and outputs. There are several predefined semantics for vertex and pixel shaders. The compiler ignores semantics unless they are declared on a global variable, or a parameter passed into a shader.
- Packoffset
-
Optional keyword for manually packing shader constants. See packoffset (DirectX HLSL).
- Register
-
Optional keyword for manually assigning a shader variable to a particular register. See register (DirectX HLSL).
- Annotation(s)
-
Optional metadata, in the form of a string, attached to a global variable. An annotation is used by the effect framework and ignored by HLSL; to see more detailed syntax, see annotation syntax.
- Initial_Value
-
Optional initial value(s); the number of values should match the number of components in Type. Each global variable marked extern must be initialized with a literal value; each variable marked static must be initialized with a constant.
Global variables—that are not marked static or extern—are not compiled into the shader. The compiler does not automatically set default values for global variables and cannot use them in optimizations. To initialize this type of global variable, use reflection to get its value and then copy the value to a constant buffer. For example, you can use the ID3D11ShaderReflection::GetVariableByName method to get the variable, use theID3D11ShaderReflectionVariable::GetDesc method to get the shader-variable description, and get the initial value from the DefaultValue member of the D3D11_SHADER_VARIABLE_DESC structure. To copy the value to the constant buffer, you must ensure that the buffer was created with CPU write access (D3D11_CPU_ACCESS_WRITE). For more information about how to create a constant buffer, see How to: Create a Constant Buffer.
You can also use the effects framework to automatically process the reflecting and setting the initial value. For example, you can use the ID3DX11EffectPass::Apply method.
Examples
Here are several examples of shader-variable declarations.
float fVar;
float4 color; float fVar = 3.1f; int iVar[3]; int iVar[3] = {1,2,3}; uniform float4 position : SV_POSITION; const float4 lightDirection = {0,0,1};
Group Shared
HLSL enables threads of a compute shader to exchange values via shared memory. HLSL provides barrier primitives such as GroupMemoryBarrierWithGroupSync, and so on to ensure the correct ordering of reads and writes to shared memory in the shader and to avoid data races.
Note Hardware executes threads in groups (warps or wave-fronts), and barrier synchronization can sometimes be omitted to increase performance when only synchronizing threads that belong to the same group is correct. But we highly discourage this omission for these reasons:
- This omission results in non-portable code, which might not work on some hardware and doesn’t work on software rasterizers that typically execute threads in smaller groups.
- The performance improvements that you might achieve with this omission will be minor compared to using all-thread barrier.
In Direct3D 10 there is no synchronization of threads when writing to groupshared, so this means that each thread is limited to a single location in an array for writing. Use the SV_GroupIndex system value to index into this array when writing to ensure that no two threads can collide. In terms of reading, all threads have access to the entire array for reading.
struct GSData { float4 Color; float Factor; } groupshared GSData data[5*5*1]; [numthreads(5,5,1)] void main( uint index : SV_GroupIndex ) { data[index].Color = (float4)0; data[index].Factor = 2.0f; GroupMemoryBarrierWithGroupSync(); ... }
Packing
Pack subcomponents of vectors and scalars whose size is large enough to prevent crossing register boundarys. For example, these are all valid:
cbuffer MyBuffer { float4 Element1 : packoffset(c0); float1 Element2 : packoffset(c1); float1 Element3 : packoffset(c1.y); }
Cannot mix packing types.
Like the register keyword, a packoffset can be target specific. Subcomponent packing is only available with the packoffset keyword, not the register keyword. Inside a cbuffer declaration, the register keyword is ignored for Direct3D 10 targets as it is assumed to be for cross-platform compatibility.
Packed elements may overlap and the compiler will give no error or warning. In this example, Element2 and Element3 will overlap with Element1.x and Element1.y.
cbuffer MyBuffer { float4 Element1 : packoffset(c0); float1 Element2 : packoffset(c0); float1 Element3 : packoffset(c0.y); }
A sample that uses packoffset is: HLSLWithoutFX10 Sample.
Data Types
HLSL supports many different intrinsic data types. This table shows which types to use to define shader variables.
Use This Intrinsic Type | To Define This Shader Variable |
Buffer | Buffer, which contains one or more scalars |
Scalar | One-component scalar |
Vector, Matrix | Multiple-component vector or matrix |
Sampler, Shader, Texture | Sampler, shader, or texture object |
Struct, User Defined | Custom structure or typedef |
To help you better understand how to use vectors and matrices in HLSL, you may want to read this background information on how HLSL uses per-component math.
Semantics
A semantic is a string attached to a shader input or output that conveys information about the intended use of a parameter. Semantics are required on all variables passed between shader stages. The syntax for adding a semantic to a shader variable is shown here (Variable Syntax (DirectX HLSL)).
In general, data passed between pipeline stages is completely generic and is not uniquely interpreted by the system; arbitrary semantics are allowed which have no special meaning. Parameters (in Direct3D 10 and later) which contain these special semantics are referred to as System-Value Semantics.
- Semantics Supported in Direct3D 9 and Direct3D 10 and later
- Semantics Supported Only for Direct3D 10 and Newer.
- Migration from Direct3D 9 to Direct3D 10 and later
- Double Binding Semantics
- Related topics
Semantics Supported in Direct3D 9 and Direct3D 10 and later
The following types of semantics are supported in both Direct3D 9 and Direct3D 10 and later.
Vertex Shader Semantics
These semantics have meaning when attached to a vertex-shader parameter. These semantics are supported in both Direct3D 9 and Direct3D 10 and later.
Input | Description | Type |
---|---|---|
BINORMAL[n] | Binormal | float4 |
BLENDINDICES[n] | Blend indices | uint |
BLENDWEIGHT[n] | Blend weights | float |
COLOR[n] | Diffuse and specular color | float4 |
NORMAL[n] | Normal vector | float4 |
POSITION[n] | Vertex position in object space. | float4 |
POSITIONT | Transformed vertex position. | float4 |
PSIZE[n] | Point size | float |
TANGENT[n] | Tangent | float4 |
TEXCOORD[n] | Texture coordinates | float4 |
Output | Description | Type |
COLOR[n] | Diffuse or specular color | float4 |
FOG | Vertex fog | float |
POSITION[n] | Position of a vertex in homogenous space. Compute position in screen-space by dividing (x,y,z) by w. Every vertex shader must write out a parameter with this semantic. | float4 |
PSIZE | Point size | float |
TESSFACTOR[n] | Tessellation factor | float |
TEXCOORD[n] | Texture coordinates | float4 |
n is an optional integer between 0 and the number of resources supported. For example, POSITION0, TEXCOOR1, etc.
Pixel Shader Semantics
These semantics have meaning when attached to a pixel-shader input parameter. These semantics are supported in both Direct3D 9 and Direct3D 10 and later.
Input | Description | Type |
---|---|---|
COLOR[n] | Diffuse or specular color. | float4 |
TEXCOORD[n] | Texture coordinates | float4 |
VFACE | Floating-point scalar that indicates a back-facing primitive. A negative value faces backwards, while a positive value faces the camera.
Note This semantic is available in Direct3D 9 Shader Model 3.0. For Direct3D 10 and later, use SV_IsFrontFace instead. |
float |
VPOS | The pixel location (x,y) in screen space. To convert a Direct3D 9 shader (that uses this semantic) to a Direct3D 10 and later shader, see Direct3D 9 VPOS and Direct3D 10 SV_Position) | float2 |
Output | Description | Type |
COLOR[n] | Output color | float4 |
DEPTH[n] | Output depth | float |
n is an optional integer between 0 and the number of resources supported. For example, PSIZE0, COLOR1, etc.
The COLOR semantic is only valid in shader compatibility mode (that is, when the shader is created using D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY).
Semantics Supported Only for Direct3D 10 and Newer.
The following types of semantics have been newly introduced for Direct3D 10 and are not available to Direct3D 9.
System-Value Semantics
System-value semantics are new to Direct3D 10. All system-values begin with an SV_ prefix, a common example is SV_POSITION, which is interpreted by the rasterizer stage. The system-values are valid at other parts of the pipeline. For instance, SV_Position can be specified as an input to a vertex shader as well as an output. Pixel shaders can only write to parameters with the SV_Depth and SV_Target system-value semantics.
Other system values (SV_VertexID, SV_InstanceID, SV_IsFrontFace) can only be input into the first active shader in the pipeline that can interpret the particular value; after that the shader function must pass the values to subsequent stages.
SV_PrimitiveID is an exception to this rule of only being input into the first active shader in the pipeline that can interpret the particular value; the hardware can provide the same ID value as input to the hull-shader stage, domain-shader stage, and after that whichever stage is the first enabled: geometry-shader stage or pixel-shader stage.
If tessellation is enabled, the hull-shader stage and domain-shader stage are present. For a given patch, the same PrimitiveID applies to the patch’s hull-shader invocation, and all tessellated domain shader invocations. The same PrimitiveID also propogates to the next active stage; geometry-shader stage or pixel-shader stage if enabled.
If the geometry shader inputs SV_PrimitiveID and because it can output zero or one or more primitives per invocation, the shader must program its own choice of SV_PrimitiveID value for each output primitive if a subsequent pixel shader inputs SV_PrimtiveID.
As another example, SV_PrimitiveID cannot be interpreted by the vertex-shader stage because a vertex can be a member of multiple primitives.
These semantics have been added to Direct3D 10; they are not available in Direct3D 9.
System-value semantics for the rasterizer stage.
System-Value Semantic | Description | Type |
---|---|---|
SV_ClipDistance[n] | Clip distance data. SV_ClipDistance values are each assumed to be a float32 signed distance to a plane. Primitive setup only invokes rasterization on pixels for which the interpolated plane distance(s) are >= 0. Multiple clip planes can be implemented simultaneously, by declaring multiple component(s) of one or more vertex elements as the SV_ClipDistance. The combined clip and cull distance values are at most D3D#_CLIP_OR_CULL_DISTANCE_COUNT components in at most D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT registers.
Writable in the Vertex and Geometry shaders. The clipplanes attribute works like SV_ClipDistance but works on all hardware feature level 9_x and higher. For more info, see User clip planes on feature level 9 hardware. |
float |
SV_CullDistance[n] | Cull distance data. When component(s) of vertex Element(s) are given this label, these values are each assumed to be a float32 signed distance to a plane. Primitives will be completely discarded if the plane distance(s) for all of the vertices in the primitive are < 0. Multiple cull planes can be used simultaneously, by declaring multiple component(s) of one or more vertex elements as the SV_CullDistance. The combined clip and cull distance values are at most D3D#_CLIP_OR_CULL_DISTANCE_COUNT components in at most D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT registers.
Writeable in the Vertex and Geometry shaders. |
float |
SV_Coverage |
A mask that can be specified on input, output, or both of a pixel shader. For SV_Coverage on a pixel shader, OUTPUT is supported on ps_4_1 or higher. For SV_Coverage on a pixel shader, INPUT requires ps_5_0 or higher. |
uint |
SV_Depth | Depth buffer data. Writeable from the pixel shader. | float |
SV_DispatchThreadID | Defines the global thread offset within the Dispatch call, per dimension of the group. Available as input to compute shader. (read only) | uint3 |
SV_DomainLocation | Defines the location on the hull of the current domain point being evaluated. Available as input to the domain shader. (read only) | float2|3 |
SV_GroupID | Defines the group offset within a Dispatch call, per dimension of the dispatch call. Available as input to the compute shader. (read only) | uint3 |
SV_GroupIndex | Provides a flattened index for a given thread within a given group. Available as input to the compute shader. (read only) | uint |
SV_GroupThreadID | Defines the thread offset within the group, per dimension of the group. Available as input to the compute shader. (read only) | uint3 |
SV_GSInstanceID | Defines the instance of the geometry shader. Available as input to the geometry shader. (read only) | uint |
SV_InsideTessFactor | Defines the tessellation amount within a patch surface. Available in the Hull shader for writing, and available in the Domain shader for reading. | float|float[2] |
SV_IsFrontFace | For lines and points, IsFrontFace has the value true. The exception is lines drawn out of triangles (wireframe mode), which sets IsFrontFace the same way as rasterizing the triangle in solid mode. Available as input to the pixel shader. (read only) | bool |
SV_OutputControlPointID | Defines the index of the control point ID being operated on by an invocation of the main entry point of the hull shader. Available for input to the Domain shader. (read only) | uint |
SV_Position | When SV_Position is declared for input to a Pixel Shader, it can have one of two interpolation modes specified: linearNoPerspective or linearNoPerspectiveCentroid, where the latter causes centroid-snapped xyzw values to be provided when multisample antialiasing. When used in a pixel shader, SV_Position describes the pixel location. Available for read/write in the vertex shader and geometry shader. The pixel shader can use it as read only to get the pixel center with a 0.5 offset. | float4 |
SV_RenderTargetArrayIndex | Render-target array index. Applied to geometry shader output and indicates the render target array slice that the primitive will be drawn to by the pixel shader. SV_RenderTargetArrayIndex is only valid if the render target is an array resource. This semantic applies only to primitives, if a primitive has more than one vertex the value from the leading vertex will be used.
This value also indicates which array slice of a depthstencilview is used for read/write purposes. Can be written from the geometry shader and read by the pixel shader. |
uint |
SV_SampleIndex | Sample frequency index data | uint |
SV_Target[n],
where 0 <= n <= 7 |
The output value that will be stored in a render target. The index indicates which of the 8 possibly bound render targets to write to. The value is available as output from the pixel shader. (write only) | float |
SV_TessFactor | Defines the tessellation amount on each edge of a patch. Available for writing in the Hull shader and reading in the Domain shader. | float[2|3|4] |
SV_ViewportArrayIndex | Viewport array index. Applied to geometry shader output and indicates which viewport to use for the primitive currently being written out. The primitive will be transformed and clipped against the viewport specified by the index before it is passed to the rasterizer. This semantic applies only to primitives, if a primitive has more than one vertex the value from the leading vertex will be used. | uint |
SV_InstanceID | Per-instance identifier automatically generated by the runtime (seeUsing System-Generated Values (Direct3D 10)) | uint |
SV_PrimitiveID | Per-primitive identifier automatically generated by the runtime (seeUsing System-Generated Values (Direct3D 10)) | uint |
SV_VertexID | Per-vertex identifier automatically generated by the runtime (see Using System-Generated Values (Direct3D 10)) | uint |
Limitations when writing SV_Depth:
- When multisampling (MultisampleEnable is TRUE in D3D10_RASTERIZER_DESC) and writing a depth value (using a pixel shader), the single value written out is also used in the depth test; so the ability to render primitive edges at higher resolution is lost when multisampling.
- When using dynamic-flow control, it is impossible to determine at compile time whether a shader that writes SV_Depth in some paths will be guaranteed to write SV_Depth in every execution. Failure to write SV_Depth when declared results in undefined behavior (which may or may not include discard of the pixel).
- Any float32 value including +/-INF and NaN can be written to SV_Depth.
- Writing SV_Depth is still valid when performing Dual Source Color Blending.
Migration from Direct3D 9 to Direct3D 10 and later
The following issues should be considered when migrating code from Direct3D 9 to Direct3D 10 and later:
Mapping to Direct3D 9 Semantics
A few of the Direct3D 10 and later semantics map directly to Direct3D 9 semantics.
Direct3D 10 Semantic | Direct3D 9 Equivalent Semantic |
---|---|
SV_Depth | DEPTH |
SV_Position | POSITION |
SV_Target | COLOR |
Note to Direct3D 9 developers:
For Direct3D 9 targets, shader semantics must map to valid Direct3D 9 semantics. For backwards compatibility POSITION0 (and its variant names) is treated as SV_Position, COLOR is treated as SV_TARGET. |
Direct3D 9 VPOS and Direct3D 10 SV_Position
The D3D10 semantic SV_Position provides similar functionality to the Direct3D 9 shader model 3 VPOS semantic. For instance, in Direct3D 9 the following syntax is used for a pixel shader using screen space coordinates:
float4 psMainD3D9( float4 screenSpace : VPOS ) : COLOR { // code here }
VPOS was added for shader model 3 support, to specify screen space coordinates, since the POSITION semantic was intended for object-space coordinates.
In Direct3D 10 and later, the SV_Position semantic (when used in the context of a pixel shader) specifies screen space coordinates (offset by 0.5). Therefore, the Direct3D 9 shader would be roughly equivalent (without accounting for the 0.5 offset) to the following:
float4 psMainD3D10( float4 screenSpace : SV_Position ) : COLOR { // code here }
When migrating from Direct3D 9 to Direct3D 10 and later, you will need to be aware of this when translating your shaders.
User clip planes in HLSL
Starting with Windows 8, you can use the clipplanes function attribute in an HLSL function declaration rather than SV_ClipDistance to make your shader work on feature level 9_x as well as feature level 10 and higher. For more info, seeUser clip planes on feature level 9 hardware.
Double Binding Semantics
You can apply the same semantic to more than one parameter. For instance:
float4x4 WorldView[60] : WORLDVIEW : register(c16); float4 main( float3 Pos : SV_POSITION, int4 IPos : SV_POSITION ) : SV_POSITION { float3 P = mul(float4(Pos, 1), (float4x3)WorldView[IPos.w]); return float4(P,1); }
This function takes two arguments: a three-component, floating-point position and a four-component, integer position. The integer position is used as an index into the array of world-view matrices.
- 本文固定链接: http://www.wy182000.com/2015/03/03/shader-语法/
- 转载请注明: wy182000 于 Studio 发表