introduction
High-rise Coloring Language (HLSL) is one of the most powerful new components of DirectX® 9. Using this standard high-level language, the writer can focus on the algorithm without using the colors, such as register read port restrictions, parallel processing instructions, etc. In addition to liberating developers from hardware details Outside it, HLSL also has all all of the advantages, such as: code reusability, readability, and an optimized compiler. Many of this book and Shaderx2 - Shader Tips & Tricks have used the book for HLSL written by HLSL. After reading this chapter, you will easily understand those shaders and use them at work.
This chapter, our outlines the basic structure of the language itself and integrates HLSL into your application.
A simple example
Before you thoroughly describe HLSL, let's take a look at the implementation of HLSL vertex coloring and HLSL pixels in the program. This program renders simple wood grain. The first HLSL color color shown below is a simple vertex coloring:
Float4x4 view_proj_matrix;
FLOAT4X4 TEXTURE_MATRIX0;
Struct vs_output
{
FLOAT4 POS: Position;
FLOAT3 PSHADE: TEXCOORD0;
}
Vs_output main (float4 vPosition: position)
{
Vs_output out = (vs_output) 0;
// Transform Position to Clip Space
Out.pos = mul (view_proj_matrix, vPosition);
// Transform pshade
Out.pshade = mul (Texture_Matrix0, VPosition);
Return Out;
}
The first line declares a pair of 4 × 4 matrices, named View_Proj_matrix and Texture_matrix0, respectively. After the global matrix, a structure is declared. This vs_output has two members: POS and PSHADE.
The shader's main function accepts a single-precision float4 type input parameter and returns a VS_OUTPUT structure. FLOAT4 Type VPosition is the unique input of shaders, and the returned VS_OUTPUT structure defines the output of the vertex shader. There is no need to care for keywords and texcoord0 after parameters and structures. They are called semantics, and their meaning will be discussed behind this chapter.
Look at the actual code section of the main function, you can see an internal function MUL that is used to multiply the input vector VPosition and matrix view_proj_matrix. This function is most commonly used in the vertex shader multiplication of the vertex-matrix. In this way, VPosition is used as column vector because it is the second parameter of MUL. If vector VPosition is the first parameter of MUL, it will be used as a line vector. The internal function MUL and other internal functions will be discussed in more detail behind this chapter. After switching the position of the input VPosition to the clipping space, VPosition multiplies another matrix Texture_Matrix0 to generate a 3D texture coordinate. The result of the two conversion is written to the returned structure vs_output. A vertex shader must always output to a clipping space location with a minimum value. Any additional value output from the vertex shader is obtained by running through the rasterized polygonal interpolation, and can be used to input to the pixel shader. In this way, through an interpolator, 3D PSHADE is passed from the vertex shader to the pixel shader.
Below, we see a simple HLSL wood grain pixel shader. This pixel shader works with the vertex shader just described, it will be compiled into model PS_2_0.
Float4 lightwood; // xyz == Light Wood Color
FLOAT4 DARKWOOD; // XYZ == Dark Wood Color
Float Ringfreq; // Ring Frequency
Sampler PulseTrainsample;
FLOAT4 HLSL_RINGS (FLOAT4 PSHADE: TEXCOORD0): Color
{
Float scaleddistfromzaxis = sqrt (dot (pshade.xy, pshade.xy) * RingFReq;
Float BlendFactor = TEX1D (Pulsetrainsample, ScaledDistFromzaxis);
Return Lerp (Darkwood, Lightwood, BlendFactor);
}
The first few lines declare a pair of floating point types of four-yuan arrays and a floating-point variable. After these variables, a sampler called Pulsetrainsampler is declared. The sampler will be discussed behind the chapters, and you can see it as a window in the memory, which is associated with the filter status and texture coordinate addressing mode. Behind the variable and sampler declaration is the main part of the shader code. You can see an input parameter PSHADE, which is worth it through the polygon. Its value is calculated from the vertex shader to each vertex. In the pixel shader, the Cartesian on the colored space Z axis is calculated, measured, used as a one-dimensional texture coordinates to access textures bound to the PulsetRainsampler. The color scalar returned by the TEX1D () sampling function is used as a mixed factor to mix two opposite colors declared within the shader global range. The pixel shader finally outputs a mixed quadruple vector result. All pixel shaders must at least return a quadruple RGBA color. We will discuss additional options for pixel shaders in a later chapter.
Assembly language and compilation object
Since we have already learned some HLSL shaders, here is a brief discussion on how to involve Direct3D, D3DX, assembled shader models and your programs in your code. The DirectX 8 introduced the shader in Direct3D in the first time. At that time, these virtual shaders were defined - each roughly equivalent to a graphics processor produced by a special 3D hardware. Each virtual shader is designed with assembly language. In DirectX 8.0 and DirectX 8.1, the programs of these shader models (named VS_1_1 and PS_1_1 and PS_1_1 until PS_1_4) are relatively short and generally written directly by developers directly with suitable assembly language. As shown in Figure 1, the binary representation of people readable assembly language code is passed to the D3DX library and returns the binary representation of the shader () or createvertexshader (). For more details on the traditional assembly coloring model, please refer to online and offline resources, including Shader X and DirectX SDK.
Figure 1. Use of d3dx for assembly and compiration in DirectX 8 and DirectX 9
As shown in Figure 1, the situation in DirectX 9 is very similar, with the D3DxCompileshader () API, the program passes the HLSL shader to D3DX and returns the binary representation of the compiler, which is represented by createpixelshader () or CreatevertexShader. ) Turns to Direct3D. The generated binary assembly code is a function, which depends only on the selected compilation object, not a special graphics device on the developer system. That is to say, the generated binary assembler is not related to the platform, you can compile or run anywhere. In fact, Direct 3D itself does not know anything of HLSL, except for binary assembly shader models. This is very good because this means that the Update of the HLSL compiler does not have to rely on Direct3D runtime. In fact, between the end of the 2003 Summer Summer, the Microsoft starts to publish DirectX SDK updates that contain updated HLSL compilers. In addition to the development of the HLSL compiler in D3DX, DirectX 9.0 also proposes additional assembler shader models to show the latest 3D graphics hardware. Directly use assembly language to develop models (vs_2_0, vs_3_0, ps_2_0, and ps_3_0), program developers feel freedom, but we hope that most developers will transfer to HLSL to focus on the development of shaders.
Actual hardware
Of course, just because you can write an HLSL program to express a special coloring algorithm is not equal to it can run on the hardware. As mentioned earlier, the application compiles the HLSL shader into a binary assembler by calling the D3DxCompileshader () API in D3DX. One of this API's entry parameters are such a parameter: it defines which assembly language model (or compile object) uses the HLSL compiler to represent the final shader code. If a program performs HLSL shader compilation at runtime, the program detects the performance of the Direct3D device and selects the matching compilation object. If the algorithm in the HLSL shader is too complicated so that the compile will fail on the selected compilation object. This means that although HLSL is greatly conducive to the development of shaders, it will not liberate developers from such a reality: the game is packaged to the user with various performance graphics equipment. As a game developer, you still have a series of steps to handle your image, write a better shader for a better display card, and write more basic. However, there is a well-written HLSL and the burden can be greatly reduced.
Compilation failed
As mentioned above, a given HLSL shader compiles a failure of a special object Instructions for complicating the compilation object. This means that the shader needs a large amount of resources or some features such as dynamic branches (not supported by the selected compilation object). For example, an HLSL shader may be written for access to a given hexraw apparatus for accessing in a shader. If this shader is compiled into PS_1_1, the compile will fail because the PS_1_1 model only supports four textures. Other compilation failures are often the maximum instruction counter that exceeds the selected compilation object. The algorithm represented in a HLSL may only require a large number of instructions to make the given compilation object cannot be executed.
It is important to note that the selected compilation object does not limit the HLSL syntax used by the writer. For example, the shader writer uses the 'for' loop, subroutine, 'if-else', etc., compiles the object that does not support the search, branch, or 'IF-ELSE' statement. In this case, the compiler will expand the cycle, the inline function call and execute two branches of the 'IF-ELSE' statement at the same time (the translator Note: The original value used in the statement is used to select the appropriate result. Of course, if the resulting shader (program) is too long or the opposite is beyond the resource of the compilation object, the compile will fail. Command line compiler: FXC
Many developers choose to compile it from HLSL into binary assembly language before the shader is encapsulated instead of compiling the HLSL shader when the program is being loaded or first runtime when using D3DX client. This guarantees that the HLSL source code is not peep, and it also ensures that all the programs can be permanently operated by their internal quality confirmation process. A convenient command line compiler FXC is provided in DirectX 9.0 SDK allows developers to compile shaders offline. This program has many convenient options, but you can not only compile your shaders in a command line, but also produce an anti-assessment code for designated compilation objects. If you want to optimize your shader or just want more detailed understanding of the performance of the virtual shader, it is very useful to study the anti-assembly code of the output during development. Table 1 lists these command line options.
Table 1. FXC command line options
-T target Compilation Object (Default: VS_2_0) -e Name Entry Point Name (Default: Main) -Od Prohibits Optimization - VD Disable Confirmation - Zi Allow Debug Information - ZPR Follow the Row Sequence Selection Matrix - FO FILE Output Target File -FC File Output The list of generated code - FH file outputs the head-D ID = text definition macro-Nologo without copyright information
Since you understand the contents of the HLSL compiler developed for shader, we can discuss the actual language structure. This is important to keep the concept of compilation objects as well as the concept of compilation objects and potential compilation shader models in our minds. Original: http://msdn.microsoft.com/library/en-us/dnhlsl/html/shaderx2_introductionTo.asp