FragmentLinker Direct3D Sample |
This sample shows how to use the FragmentLinker class. Shader source code can be split into a series of shader fragments which are compiled separately and linked together to form a complete shader. This linking stage is very efficient, making it suitable for run-time use. In this way, a Microsoft Direct3D application can custom-build an appropriate shader for the current graphics card.
Source: | (SDK root)\Samples\Managed\Direct3D\FragmentLinker |
---|---|
Executable: | (SDK root)\Samples\Managed\Direct3D\Bin\x86\csFragmentLinker.exe |
Large-scale Direct3D applications commonly employ a large set of redundant shaders covering every supported fallback case for a given technique (often generated by uniform parameters) from which the appropriate shader for the current graphics hardware is selected at run time. This approach can result in a large amount of compiled shaders being included with the application, only a small fraction of which are ever used on a given machine. Using shader fragments, the desired shader for the current graphics card can be built at run time.
This sample links together one of two vertex shader fragments that handles projection (vertex animated or static) and one of two vertex shader fragments that handles vertex lighting (diffuse enabled or ambient only). These fragments are compiled once during initialization and are then linked together at run time.
Only a few steps need to be followed when using shader fragments in your application:
The following sample application performs these steps upon device creation within the sample's OnCreateDevice function:
[C#]
private void OnCreateDevice( object sender, DeviceEventArgs e ) . . . // Create the fragment linker interface fragmentLinker = new FragmentLinker( e.Device, 0 ); // Compile the fragments to a buffer. The fragments must be linked // together to form a shader before they can be used for rendering. path = Utility.FindMediaFile( "FragmentLinker.fx" ); compiledFragments = Microsoft.DirectX.Direct3D.FragmentLinker.GatherFragmentsFromFile( path, null, null, ShaderFlags.None ); // Build the list of compiled fragments fragmentLinker.AddFragments( compiledFragments ); // Store the fragment handles ComboBox cb1 = sampleUI.GetComboBox( Lighting ); cb1.Clear(); cb1.AddItem( "Ambient", fragmentLinker.GetFragmentHandle( "AmbientFragment" ) ); cb1.AddItem( "Ambient & Diffuse", fragmentLinker.GetFragmentHandle( "AmbientDiffuseFragment" ) ); ComboBox cb2 = sampleUI.GetComboBox( Animation ); cb2.Clear(); cb2.AddItem( "On" , fragmentLinker.GetFragmentHandle( "ProjectionFragment_Animated" ) ); cb2.AddItem( "Off", fragmentLinker.GetFragmentHandle( "ProjectionFragment_Static" ) ); // Link the desired fragments to create the vertex shader LinkVertexShader();
The final linking step is performed within the FragmentLinker.LinkVertexShader method. In addition to being called upon device creation, this method is also called whenever the user changes a fragment combobox selection. The currently selected fragments are retrieved from the user interface controls and the shader data is updated.
[C#]
private void LinkVertexShader() { const int NumberFragments = 2; Device device = sampleFramework.Device; EffectHandle[] aHandles = new EffectHandle[NumberFragments]; aHandles[0] = sampleUI.GetComboBox( Animation ).GetSelectedData() as EffectHandle; aHandles[1] = sampleUI.GetComboBox( Lighting ).GetSelectedData() as EffectHandle; if ( vertexShader != null ) { vertexShader.Dispose(); } string errors; using (GraphicsStream code = fragmentLinker.LinkShader( "vs_1_1", ShaderFlags.None, aHandles, out errors ) ) { vertexShader = new VertexShader( device, code ); constTable = ConstantTable.FromShader( code ); } // Set the global variables device.VertexShader = vertexShader; if ( constTable != null ) { constTable.SetValue( device, "g_vMaterialAmbient", MaterialAmbient ); constTable.SetValue( device, "g_vMaterialDiffuse", MaterialDiffuse ); constTable.SetValue( device, "g_vLightColor", LightColor ); constTable.SetValue( device, "g_vLightPosition",LightPosition ); } }
Send comments about this topic to Microsoft. © Microsoft Corporation. All rights reserved.
Feedback? Please provide us with your comments on this topic.
For more help, visit the DirectX Developer Center