While there is a great deal of low-level information available about how each API function should be used, there is little documentation that shows how best to leverage these capabilities. Written by active members of the Direct3D community, Practical Rendering and Computation with Direct3D 11 provides a deep understanding of both the high and low level concepts related to using Direct3D The first part of the book presents a conceptual introduction to Direct3D 11, including an overview of the Direct3D 11 rendering and computation pipelines and how they map to the underlying hardware. It also provides a detailed look at all of the major components of the library, covering resources, pipeline details, and multithreaded rendering. Building upon this material, the second part of the text includes detailed examples of how to use Direct3D 11 in common rendering scenarios.
|Published (Last):||19 August 2011|
|PDF File Size:||11.8 Mb|
|ePub File Size:||13.37 Mb|
|Price:||Free* [*Free Regsitration Required]|
Top-level arguments are parameters to a top-level function. A top-level function is any function called by the application as opposed to a function that is called by another function. Uniform Shader Inputs Vertex and pixel shaders accept two kinds of input data: varying and uniform.
The varying input is the data that is unique to each execution of the shader. For a vertex shader, the varying data for example: position, normal, etc. The uniform data for example: material color, world transform, etc. For those familiar with the assembly shader models, uniform data is specified by constant registers and varying data by the v and t registers.
Uniform data can be specified by two methods. The most common method is to declare global variables and use them within a shader. Any use of global variables within a shader will result in adding that variable to the list of uniform variables required by that shader.
The second method is to mark an input parameter of the top-level shader function as uniform. This marking specifies that the given variable should be added to the list of uniform variables. Uniform variables used by a shader are communicated back to the application via the constant table. The constant table is the name for the symbol table that defines how the uniform variables used by a shader fit into the constant registers.
The dollar sign is required to avoid name collisions between local uniform inputs and global variables of the same name. The constant table contains the constant register locations of all uniform variables used by the shader. The table also includes the type information and the default value, if specified. Varying Shader Inputs and Semantics Varying input parameters of a top-level shader function must be marked either with a semantic or uniform keyword indicating the value is constant for the execution of the shader.
If a top-level shader input is not marked with a semantic or uniform keyword, then the shader will fail to compile. The input semantic is a name used to link the given input to an output of the previous part of the graphics pipeline. Pixel and vertex shaders have different sets of input semantics due to the different parts of the graphics pipeline that feed into each shader unit. Vertex shader input semantics describe the per-vertex information for example: position, normal, texture coordinates, color, tangent, binormal, etc.
The input semantics directly map to the vertex declaration usage and the usage index. Pixel shader input semantics describe the information that is provided per pixel by the rasterization unit.
The data is generated by interpolating between outputs of the vertex shader for each vertex of the current primitive. The basic pixel shader input semantics link the output color and texture coordinate information to input parameters. Input semantics can be assigned to shader input by two methods: Appending a colon and the semantic name to the parameter declaration. Defining an input structure with input semantics assigned to each structure member. Vertex and pixel shaders provide output data to the subsequent graphics pipeline stage.
Output semantics are used to specify how data generated by the shader should be linked to the inputs of the next stage. For example, the output semantics for a vertex shader are used to link the outputs of the interpolators in the rasterizer to generate the input data for the pixel shader.
The pixel shader outputs are the values provided to the alpha blending unit for each of the render targets or the depth value written to the depth buffer. Vertex shader output semantics are used to link the shader both to the pixel shader and to the rasterizer stage. A vertex shader that is consumed by the rasterizer and not exposed to the pixel shader must generate position data as a minimum. Vertex shaders that generate texture coordinate and color data provide that data to a pixel shader after interpolation is done.
Pixel shader output semantics bind the output colors of a pixel shader with the correct render target. The pixel shader output color is linked to the alpha blend stage, which determines how the destination render targets are modified. The pixel shader depth output can be used to change the destination depth values at the current raster location. The depth output and multiple render targets are only supported with some shader models.
The syntax for output semantics is identical to the syntax for specifying input semantics. The semantics can be either specified directly on parameters declared as "out" parameters or assigned during the definition of a structure that either returned as an "out" parameter or the return value of a function.
Semantics identify where data comes from. Semantics are optional identifiers that identify shader inputs and outputs. Semantics appear in one of three places: After a structure member. This example uses a structure to provide one or more vertex shader inputs, and another structure to provide one or more vertex shader outputs. Each of the structure members uses a semantic.
This shader maps the data from the position, normal, and blendweight elements of the vertex buffer into vertex shader registers. The input data type does not have to exactly match the vertex declaration data type.
For instance, if the normal data were defined to be of type UINT by the application, it would be converted into a float3 when read by the shader. If the data in the vertex stream contains fewer components than the corresponding shader data type, the missing components will be initialized to 0 except for w, which is initialized to 1. The output structure identifies the vertex shader output parameters of position and color. These outputs will be used by the pipeline for triangle rasterization in primitive processing.
The output marked as position data denotes the position of a vertex in homogeneous space. As a minimum, a vertex shader must generate position data. The screen space position is computed after the vertex shader completes by dividing the x, y, z coordinate by w. In screen space, -1 and 1 are the minimum and maximum x and y values of the boundaries of the viewport, while z is used for z-buffer testing. In general, an output structure for a vertex shader can also be used as the input structure for a pixel shader, provided the pixel shader does not read from any variable marked with the position, point size, or fog semantics.
These semantics are associated with per-vertex scalar values that are not used by a pixel shader. If these values are needed for the pixel shader, they can be copied into another output variable that uses a pixel shader semantic. Global variables are assigned to registers automatically by the compiler. Global variables are also called uniform parameters because the contents of the variable is the same for all pixels processed each time the shader is called.
Input semantics for pixel shaders map values into specific hardware registers for transport between vertex shaders and pixel shaders. Each register type has specific properties. Because there are currently only two semantics for color and texture coordinates, it is common for most data to be marked as a texture coordinate even when it is not.
Notice that the vertex shader output structure used an input with position data, which is not used by the pixel shader. HLSL allows valid output data of a vertex shader that is not valid input data for a pixel shader, provided that it is not referenced in the pixel shader.
Input arguments can also be arrays. Semantics are automatically incremented by the compiler for each element of the array. Just like input semantics, output semantics identify data usage for pixel shader output data. Many pixel shaders write to only one output color. Pixel shaders can also write out a depth value into one or more multiple render targets at the same time up to four. Like vertex shaders, pixel shaders use a structure to return more than one output. This shader writes 0 to the color components, as well as to the depth component.
When writing multiple colors, all output colors must be used contiguously. Pixel shader depth output must be of type float1. Samplers and Texture Objects A sampler contains sampler state. Sampler state specifies the texture to be sampled, and controls the filtering that is done during sampling. The sampler contains the sampler state inside of curly braces.
This includes the texture that will be sampled and, optionally, the filter state that is, wrap modes, filter modes, etc. If the sampler state is omitted, a default sampler state is applied specifying linear filtering and a wrap mode for the texture coordinates.
The sampler function takes a two-component floating-point texture coordinate, and returns a two-component color. This is represented with the float2 return type and represents data in the red and green components. In some rare scenarios, the compiler cannot choose an efficient y-component, in which case it will issue a warning. If the code is rewritten using a float2 input instead of a float1, the compiler can use the input texture coordinate because it knows that y is initialized to something.
With the "proj" suffix, the texture coordinate is divided by the w-component. With "bias," the mip level is shifted by the w-component. Thus, all texture lookups with a suffix always take a float4 input.
Samplers may also be used in array, although no back end currently supports dynamic array access of samplers. Therefore, the following is valid because it can be resolved at compile time: tex2D s,tex However, this example is not valid.
Writing Functions Functions break large tasks into smaller ones. Small tasks are easier to debug and can be reused, once proven. Functions can be used to hide details of other functions, which makes a program composed of functions easier to follow. HLSL functions are similar to C functions in several ways: They both contain a definition and a function body and they both declare return types and argument lists. Like C functions, HLSL validation does type checking on the arguments, argument types, and the return value during shader compilation.
This makes it easier to bind buffer data to a shader, and bind shader outputs to shader inputs. A function contains a declaration and a body, and the declaration must precede the body.
Writing HLSL Shaders in Direct3D 9
Direct3D.shaderX.vertex.and.Pixel.shader.tips.and.tricks Wolfgang.F.engel Wordware.pub 2002