This sample shows an example of how to use Microsoft Direct3D's high-level shader language (HLSL), without the use of the D3DX effect interfaces. Not using the Effect interface is a more difficult method of using HLSL. See BasicHLSL Direct3D Sample for a simpler method of using HLSL.
- Supported Languages
- Sample Overview
- How the Sample Works
The sample demonstrates using HLSL to write vertex shaders without using the D3DX Effect Interfaces. HLSL is a language that closely resembles C syntax and constructs. By writing shaders in HLSL instead of assembly language, developers can take advantage of not only the features and elements of the language with which they are already familiar, but also the great optimization capabilities offered by the D3DX shader compiler.
How the Sample Works
The scene that this sample renders consists of a square grid of triangles lying on the XZ plane. In each frame, the vertices of this grid will move up or down along the Y direction based on a function of their distance to the origin and time. The vertices are also lit using another function of the distance and time. The time is incremented for each frame. Because the Y coordinate and color of the vertices are generated in each frame, they do not need to be stored. Therefore, the vertex declaration only contains a Vector2 member, for the X and Z coordinates.
During initialization, the sample calls CompileShaderFromFile to compile the sample's shader function stored in a file into binary shader code, that can be understood by the 3-D device. After this process, a GraphicsStream object containing the shader code and a ConstantTable object that allows the application to get and set the global variables of the shader are created. Then, the sample creates a new vertex shader using the shader code to obtain a VertexShader object that can be passed to the 3-D device for execution.
In OnFrameMove(), the sample uses the ConstantTable obtained from initialization to set the shader's global variables worldViewProj and appTime, in order to update the view + projection transformation and time parameter for the shader. At render time, the sample sets the VertexShader property to enable vertex shader rendering on the device. When DrawIndexedPrimitives is called after that, the vertex shader will be invoked once for every vertex processed.
In the sample, the vertex shader is written in a text file called
HLSLwithoutEffects.fx. In this file, there are two global variables and a shader function called Ripple. Ripple takes a float2 as input (for X and Z of the vertex), and outputs two float4 representing the screen-space position and vertex color. The Y coordinate is generated using this formula:
Y = 0.1 * sin( 15 * L * sin(T) );
L is the distance between the vertex and the origin before the Y adjustment, so it has the value of sqrt( X^2 + Z^2 ), because the vertices are lying on the XZ plane. T is the appTime global variable.
The color of the vertex will be some shade of gray based on this formula:
C = 0.5 - 0.5 * cos( 15 * L * sin(T) );
C will be the value used for all red, green, blue, and alpha, and will range from 0 to 1, giving the vertex a color of black to white, respectively. The result looks like ripples with width changing back and forth between narrow and wide, and are properly shaded based on the slope.