(SDK root)\Samples\Managed\Direct3D\BasicHLSL

Coded in both Microsoft Visual C# and Microsoft Visual Basic .NET, this is a simple example of using high-level shader language (HLSL) with the Effect class.

BasicHLSL sample

Supported Languages

  • C#
  • Visual Basic .NET

Path

Source: (SDK root)\Samples\Managed\Direct3D\BasicHLSL
Executable: (SDK root)\Samples\Managed\Direct3D\Bin\x86\csBasicHLSL.exe

Sample Overview

This sample simply loads a Mesh, creates an Effect from a file, and then uses the Effect to render the Mesh. The Effect that is used is a simple vertex shader that animates the vertices based upon time, along with the possibility to have multiple directional lights.

How the Sample Works

First the sample loads the geometry with Mesh.FromFile and calls ComputeNormals to create mesh normals if there are not yet any. The sample then calls OptimizeInPlace to optimize the mesh for the vertex cache. It then loads the textures using its CreateTextureFromFile method. Finally, it calls its CreateEffectFromFile method to compile the effect text file into an Effect object called effect.

Note that the CreateEffectFromFile call takes flags which are needed to debug shaders with the Microsoft Visual Studio .NET shader debugger. Debugging vertex shaders requires either reference or software vertex processing, and debugging pixel shaders requires reference vertex processing. The ForcePixelShaderSoftwareNoOptimizations and ForceVertexShaderSoftwareNoOptimizations flags improve the debug experience in the shader debugger. They enable source level debugging, prevent instruction reordering, prevent dead code elimination, and force the compiler to compile against the next highest available software target, ensuring that the unoptimized shaders do not exceed the shader model limitations. Setting these flags causes slower rendering because the shaders will be unoptimized and forced to run in software. To turn these flags on with the C# sample code, simply remove the comment marks from either the #define DEBUG_VS or the #define DEBUG_PS line near the top of the file. Turning on one of these flags also forces the device into software processing by adding some code to the ModifyDeviceSettings callback method.

The OnFrameRender callback method sets the appropriate technique with the effect.Technique property, which passes an EffectHandle (in this case a string). It is possible to pass an EffectHandle instead of a string, thereby improving performance because this high frequency call does not have to spend time performing a string comparison.

The OnFrameRender method then sets variables used by the technique, such as the World*View*Projection matrix and the time variable, with various effect.SetArrayRange calls. To render the scene, OnFrameRender calls effect.Begin, which returns pass, the number of passes required by the technique, then it loops through each pass calling effect.BeginPass(pass) and rendering the mesh with mesh.DrawSubset. After each pass, OnFrameRender calls effect.EndPass. When all the passes are completed, OnFrameRender calls effect.End.