HLSLwithoutEffects Sample

Description
This sample shows an example of how to use Microsoft Direct3D's High-Level Shader Language (HLSL), without the use of the Direct3D Extension (D3DX) effect interfaces. Not using the ID3DXEffect interface is a more difficult method of using HLSL. See the BasicHLSL sample for a simpler method of using HLSL.



Path
Source: DX90SDK\Samples\C++\Direct3D\HLSLwithoutEffects
Executable: DX90SDK\Samples\C++\Direct3D\Bin


User's Guide
General controls defined in the sample:

Key Action
W/S Move forward/backward
Q,E,A,D Strafe
F2 Change device
Esc Quit



Sample Overview
The sample demonstrates using High-Level Shader Language (HLSL) to write vertex shaders without using the Direct3D Extension (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 they are already familiar with, but also the great optimization capabilities offered by the D3DX shader compiler.

How does the sample work?
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 D3DXVECTOR2 member, for the X and Z coordinates.

During initialization, the sample calls D3DXCompileShaderFromFile() to compile the sample's shader function stored in a file into binary shader code, that can be understood by the 3D device. After this process, a ID3DXBuffer containing the shader code and a ID3DXConstantTable that allows the application to get and set the global variables of the shader are created. Then, the sample calls CreateVertexShader() with the shader code to obtain a IDirect3DVertexShader9 object that can be passed to the 3D device for execution.

In FrameMove(), the sample uses the ID3DXConstantTable interface obtained from initialization to set the shader's global variables "mViewProj" and "fTime", in order to update the view + projection transformation and time parameter for the shader. At render time, the sample calls SetVertexShader() to enable vertex shader rendering on the device. When DrawIndexedPrimitive() 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.vsh. 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² + Z² ), because the vertices are lying on the XZ plane. T is the fTime 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.





Copyright (c) Microsoft Corporation. All rights reserved.