+ All Categories
Home > Documents > User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... ·...

User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... ·...

Date post: 10-Jul-2020
Category:
Upload: others
View: 4 times
Download: 0 times
Share this document with a friend
55
User Guide DU-01057-001_v03 November 2004
Transcript
Page 1: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

User Guide

DU-01057-001_v03 November 2004

Page 2: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 i November 2004

Table of Contents

Chapter 1. About FX Composer..........................................................................1 1.1. System Requirements ............................................................................................ 3 1.2. References and Recommended Reading .................................................................. 3

Chapter 2. Using FX Composer ..........................................................................4 2.1. Panels .................................................................................................................. 4 2.2. Materials Panel ...................................................................................................... 7 2.3. Textures Panel ...................................................................................................... 8 2.4. Text Edit Panel ...................................................................................................... 8 2.5. Properties Panel .................................................................................................... 9 2.6. Scene Panel ........................................................................................................ 11 2.7. Scene Graph Panel............................................................................................... 14

Chapter 3. DirectX Standard Annotations and Semantics 0.8.........................15 3.1. ScriptExecute Example ......................................................................................... 16 3.2. Apply Materials to a Scene.................................................................................... 17

Chapter 4. Miscellaneous Hints and Tidbits… .................................................18 4.1. Scripting & Automation ........................................................................................ 18

Script Advantages ....................................................................................................... 19 Script Disadvantages................................................................................................... 19 Script Tips.................................................................................................................. 19

4.2. Projects vs. Packages........................................................................................... 20 4.3. Configuration Files ............................................................................................... 21 4.4. Mesh Sections ..................................................................................................... 22 4.5. Preprocessor Directives ........................................................................................ 22 4.6. Matrix Order........................................................................................................ 22 4.7. Reset on Window Resize ...................................................................................... 22 4.8. Shadow Map Formats........................................................................................... 23 4.9. FX Composer CAMERAPOSITION........................................................................... 23

Tutorial #1. Building an FX Composer Plug-in ...............................................24 Step 1: Create the Project ............................................................................................... 25 Step 2: Create a Plug-in Class.......................................................................................... 27

Page 3: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 ii November 2004

Step 3: Supporting the Plug-in Interface........................................................................... 28 Step 4: Registering the Plug-in ....................................................................................... 31 Step 5: Adding the Scene Import Code............................................................................. 33

Creating the Material................................................................................................... 34 Creating the Transform ............................................................................................... 35 Creating the Geometry Pipe ......................................................................................... 35

Step 6: Adding Animation................................................................................................ 39 Tutorial #2 Measuring and Managing Shader Performance with FX Composer.........................................................................................................................41

Sources of Performance Information ................................................................................ 41 Try It Yourself: The PerfTutor.fx Shader .......................................................................... 42

Looking at the Shader Perf Panel.................................................................................. 44 GPU Efficiency ............................................................................................................ 44 Tweaking the Code ..................................................................................................... 45 Frames per Second ..................................................................................................... 45

4.10. What’s Next? ................................................................................................... 46 Tutorial #3. Optimizing a Bump Mapping Shader ...........................................47

Shader Optimization ....................................................................................................... 47 FX Composer Shader Performance Tools....................................................................... 49

Optimizing Your Shader One Step at a Time .................................................................... 49

Page 4: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 iii November 2004

List of Figures

Figure 1-1. FX Composer Main Window ............................................................................. 2 Figure 2-1. Accessing Panels ............................................................................................ 4 Figure 2-2. Application Toolbar......................................................................................... 6 Figure 2-3. Interconnection of Panels................................................................................ 9 Figure 2-4. Color Selection Tear-off Panel........................................................................ 10 Figure 3-1. Using ScriptExecute Sorter ............................................................................ 17

List of Tables

Table 2-1. Window Panel Tool Icons ................................................................................ 5 Table 2-2. Description of Application Toolbar Icons ........................................................... 6 Table 4-1. CAMERAPOSITION Semantic ......................................................................... 23

List of Examples

Example 1. perftutor.fx .................................................................................................. 43

Page 5: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 1 November 2004

Chapter 1. About FX Composer

FX Composer empowers developers to create high performance shaders in an integrated development environment with real-time preview and optimization features available only from NVIDIA. FX Composer was designed with the goal of making shader development and optimization easier for programmers while providing an intuitive user interface for artists customizing shaders in a particular scene

FX Composer supports all the standard features you would expect in an integrated development environment for high performance shaders:

Sophisticated text editing with Intellisense and syntax highlighting Work directly with HLSL .FX files, creating multiple techniques and passes.

Use the .FX files you create with FX Composer directly in your application Convenient, artist-friendly graphical editing of shader properties and some

attributes Supports Microsoft DirectX 9.0 standard HLSL semantics and annotations Provides a plug-in architecture supporting import of custom scene data so you

can view your shaders on your own models with lighting, animation, etc.

FX Composer also provides developers with visual debugging and advanced performance tuning features previously unavailable:

Visible preview of intermediate (generated) textures Capture of precalculated functions to texture look-up table Interactive compiler shows where the problems are – jump directly to problems

in your HLSL source code Simulated performance results for the entire family of NVIDIA GeForce FX

GPUs Empirical performance metrics such as GPU instruction count,

efficiency/utilization and frames per second (FPS)

Page 6: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Getting Started with FX Composer

DA-01057-001_v03 2 November 2004

FX Composer consists of several panels that can be docked in the main window, as shown in Figure 1-1, or arranged outside of the main window to a more convenient place.

Figure 1-1. FX Composer Main Window EverQuest® content courtesy Sony Online Entertainment Inc. EverQuest is a registered trademark of Sony Computer Entertainment America Inc. (c) 2004 Sony Computer Entertainment America Inc. All rights reserved.

Page 7: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Getting Started with FX Composer

DA-01057-001_v03 3 November 2004

1.1. System Requirements NVIDIA GeForce3 or later

An NVIDIA GeForce FX, GeForce 6 Series, or more recent GPU is recommended

Microsoft DirectX 9.0 SDK Summer 2003 Update (9.0c) or later Windows XP or Windows 2000

1.2. References and Recommended Reading

Microsoft DirectX web site http://www.microsoft.com/windows/directx/default.aspx

NVIDIA Developer Relations web site http://www.developer.nvidia.com/page/home

GPU Gems: Programming Techniques, Tips, and Tricks for Real-Time Graphics http://developer.nvidia.com/object/gpu_gems_home.html

Page 8: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 4 November 2004

Chapter 2. Using FX Composer

FX Composer allows the user to configure their development environment in several ways. The Text Editor panel is always displayed in the main window. Each optional element of the UI is displayed in a separate panel that can be moved, hidden, resized, docked to the main window, or free floating any where on the desktop. FX Composer supports systems with multiple displays, allowing free floating panels to be used on a second monitor and can be configured to display any combination of the following panels:

Log panel Error panel Properties panel Materials panel Textures panel Shader Perf panel Scene panel Scene Graph panel

2.1. Panels To display the various panels, use the View Panels and select the panels to be displayed in your work area (Figure 2-1).

Each panel is adjustable and can be dragged away from its docked position to float freely above the main window. Double-clicking the title bar of a dockable panel will also dock or undock it.

Several panels have buttons at the top associated with their major functions.

Table 1 lists these buttons and provides a description of each. These buttons are only displayed in panels where they can be used.

The main window of FX Composer is shown in Figure 1-1.

Figure 2-1. Accessing Panels

Page 9: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 5 November 2004

Table 2-1. Window Panel Tool Icons

Where applicable, a toolbar is located at the top of each window panel. The toolbar contains only those icons that are relevant to the panel operation.

Tool Icon Description

Select Object: Selects an object in the window.

Rotate Scene: Rotates a scene in the window.

Pan Scene: Pans over the scene in the window.

Dolly Scene: Resizes an object from the center.

Zoom Extents: Zooms in on an object/scene.

Apply Material: Applies the selected material to the currently mesh selection.

Delete Material: Removes this material and close the corresponding .fx file.

New Material: Creates new materials and corresponding .fx file.

Object size display Small: Changes object size to a small representation. Medium: Changes object size to a medium representation (selected). Large: Changes object size to a large representation.

Actual Size: Changes object representation to reflect its actual size.

Save: Saves current selection

Rotate Scene: Rotates all objects in the window in the direction you drag. (CTRL + L-mouse)

Pan Scene: Moves the camera up/down or left/right. (SHIFT + L-mouse)

Zoom Scene: Moves the camera closer or further away. (CTRL + SHIFT + L-mouse)

Categorize: Shows panel contents organized by category.

Alphabetize: Shows panel contents organized alphabetically.

Stop/Start Animation: Controls playback of scene animation. (CTRL+G=Start, CTRL+H=Stop)

Table 2-1 lists the icons and their function and 2-2 shows the toolbar.

Page 10: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 6 November 2004

Figure 2-2. Application Toolbar

Table 2-2. Description of Application Toolbar Icons

Tool Icon Description

Open File: Opens the browser to find a file. (CTRL+O)

Save: Saves a file. (CTRL+S)

Cut: Deleted or cut code from the .fx file. (Shift+Delete)

Copy: Copies highlighted text. (CTRL+C)

Paste: Pastes the last copied text. (CTRL+V)

Undo: Undoes the last action. (ALT+Backspace)

Redo Redoes the last action. (CTRL+Y)

Bookmarks: Flags lines of code and skip quickly between them.

Toggle (apply/delete) Bookmark. (CTRL+F2)

Go to Next Bookmark. (F2)

Go to Previous Bookmark. (Shift+F2)

Clear ALL Bookmarks

Find: Finds specific words in a file. (CTRL+F)

Indent/Un-indent: Indents and un-indents lines of code.

Compile .fx: Compiles the code displayed in the Text Editor panel. Note that the compiler stops at each instance of an error in the code and does not continue until the error is corrected. Click the Compile key again to continue compiling. (CTRL+F7)

Page 11: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 7 November 2004

2.2. Materials Panel The Materials panel is a collection of 3D viewports displaying a real-time preview of each material currently loaded, applied to a simple shape. This allows you to visualize a material and see it applied in 3D.

To open materials, use the File Load Material… and select the material to load. See Table 1-1 on page 5 for a description of the toolbar icons.

Use the Apply button to apply the selected material to an object in a scene. Select the desired material, select an object in the scene and click the Apply icon. You can also Right-click on a material to access a list of actions and select Apply To Selection.

Use the Rotate button to spin the materials around and see the different effects.

You can also Right-click within the panel to access Materials panel display options in a context menu. The menu allows you to apply a material to the current selection in the Scene panel, create new materials, open or close existing materials, select the geometric primitive to which the materials should be applied, and set the display dimensions and rendermode.

Note that the Materials panel renders all the previews it displays in real-time, and therefore incurs a performance cost. You can reduce the performance impact by closing the Materials panel.

Page 12: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 8 November 2004

2.3. Textures Panel The Textures panel displays the current textures for the selected material as well as any procedurally-generated textures and render targets. The Texture panel also enables visualization of cube maps and normal maps, since it's really just the same window as the materials panel, and it is displaying the textures in an FX file.

The icons in the toolbar are described in Table 1-1 on page 5. You can also Right-click anywhere in the Texture panel to access a context menu with options to set the display dimensions and save the currently selected texture.

2.4. Text Edit Panel The Text Edit panel contains the FX file code and is enabled with syntax highlighting (keywords in colors). It acts like the editor in Microsoft Visual Studio. All Material files opened are listed as tabs across the top of the panel to allow you to switch between files easily. Use the scrollbars and bookmarks to move through the file.

The Text Editor panel uses syntax highlighting to automatically color HLSL keywords and comments. It also provides convenient Intellisense completion, allowing you to select from a list of supported keywords appropriate in the current context. For example, you can type fillmode= and select from a list of options that are displayed.

Page 13: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 9 November 2004

Every time you open a project or a material, a tab is placed along the top of the Text Editor panel. Clicking on the tab displays the source code in the Text Editor panel and the objects properties in the Properties panel. To close a project or material, click on the tab and then click the X box (Close) located at the far right.

2.5. Properties Panel The Properties panel is used to view and change object properties. It is primarily used for material properties; however it can be used to view/change shapes, textures, and other items in the scene graph such as light. Table 1-1 on page 5 lists the functions of the toolbar icons.

The options displayed in the Properties panel are created by parsing through the current FX file and evaluating the HLSL semantics and annotations used to describe each variable. For example, a specular exponent might be declared as shown in Figure 2-2, defining how the variable should be displayed in the Properties panel.

Figure 2-3. Interconnection of Panels

Important: Changing the values in the Parameter box or the properties panel does not change the default values specified in the source code. It does change the current values being used to render the scene.

If you click on the content of Light Direction 1, the following pop-up window displays allowing you to change the values without having to scroll through the code.

Page 14: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 10 November 2004

Vectors and matrices also get special treatment in the Properties panel. When defined with the proper semantics and annotations as shown in Figure 2-2, a matrix editor tear-off panel provides users with a convenient way to experiment with different values. Note that clicking on the scene graph icon next to Light Direction 1 causes FX Composer to display the assembly language calculations performed for this light in a pop-up window.

FX Composer supports special color selection tear-off panels for editing color information (Figure 2-3). Semantics and annotations can be used to tell FX Composer that a variable is used to store color information and provide a descriptive name for the Properties panel.

Figure 2-4. Color Selection Tear-off Panel

Click on the attribute to change the color. Click Other to display the Standard and Custom color palettes.

Page 15: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 11 November 2004

2.6. Scene Panel The Scene panel displays the current scene and has the usual controls for manipulating scenes. FX Composer includes GeoPipe plug-ins that support importing scenes stored in .nvb and .x files, both of which can contain skinning information. Use the File Import Scene… command to load a scene.

Select an object in the scene and apply a different material to it to change its appearance. Note that the light source remains the same; only the material of the surface changes.

Select a material and click Apply. The material is applied to the selected object in the Scene panel.

Page 16: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 12 November 2004

Use the tool icons in the Scene panel to manipulate objects and scenes.

Zoom Extents Dolly Scene Pan Scene Rotate Scene Scale Object Move Object Rotate Object Select Object

Use the animation controls in the toolbar to run the frames and see the animation associated with your scene. Note that the frame displayed is shown in the upper left corner of the window.

Rotated Scene

To move frame-by-frame, use Animation in the application toolbar or F10 fpr Next frame and F9 for Previous Frame.

Page 17: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 13 November 2004

Dolly Scene Pan Scene

Move an Object Scale an Object

Note that turning on Tools Options Draw will always cause FPS (frames per second) to be displayed in the upper left.

Page 18: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Using FX Composer

DA-01057-001_v03 14 November 2004

2.7. Scene Graph Panel The Scene Graph panel is used to browse through the current scene transform hierarchy and select objects. You can use it to select items that would not easily be available in the UI, such as individual bone transforms, etc. It is also useful to see how a scene is built.

To use this window, you can, for example, select GeoPipe : Spot01 and then Right-Click to display the GeoPipe properties in the Properties panel (if not already displayed).

Page 19: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 15 November 2004

Chapter 3. DirectX Standard Annotations and

Semantics 0.8

FX Composer supports version 0.8 of Microsoft’s DXSAS (DirectX Standard Annotations and Semantics) specification. This enables the shader author to take control of the process by which effect files are rendered. Standard annotations and semantics provide a rich way to describe the details of how a shader should be setup, in a standard format that is compatible with major DCC tools. With a standard system of annotations and semantics, it is possible for tools to interchange complete shaders with ease. Such shaders contain all the information necessary to render them in an engine—texture creation information, shader details, shader parameters, user interface hints, etc.

DXSAS replaced the previous scene command framework in FX Composer 1.0. All sample effect files that ship with FX Composer are compatible with version 0.8 of the specification. The full set of annotations and semantics supported by FX Composer are accessed through the Help men (including a small selection of private annotations and semantics that FX Composer supports to enable useful features of the tool). Version 0.8 of the specification is obtained from Microsoft and is part of the DirectX 9.0 SDK Summer 2004 Update.

A powerful new feature of DXSAS is ScriptExecute. ScriptExecute is a scripting language that is attached to annotations in the effect file and controls the shader flow through the engine. With DXSAS, it is possible to control the creation of and rendering of texture targets, and full screen effects such as motion blur or glow.

Any XML between these two elements is treated as a scene command. Table 3-1 lists the current scene commands.

Page 20: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

FX Composer Scene Commands

DA-01057-001_v03 16 November 2004

3.1. ScriptExecute Example The screenshot below is of an edge-detect effect file, implemented using ScriptExecute. The entry point to the script in the effect file is shown after the screenshot.

float Script : STANDARDSGLOBAL < string UIWidget = "none"; string ScriptClass = "scene"; string ScriptOrder = "postprocess"; string ScriptOutput = "color"; string Script = "Technique=Main;"; > = 0.8;

The entry point to the script is always labeled with the STANDARDSGLOBAL annotation, and is a float value. The 0.8 signifies the version of the script, and helps tools understand which DXSAS version the effect file supports.

You can see from this entry point that the Script is calling a Technique called Main. You can also see that the shader is designed to output color information; that it is a post process effect and that it works on the whole scene.

If you look at the Main technique, you see the following code: technique Main < string Script = "RenderColorTarget0=SceneTexture;" "RenderDepthStencilTarget=DepthBuffer;" "ClearSetColor=ClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;"

Page 21: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

FX Composer Scene Commands

DA-01057-001_v03 17 November 2004

"Clear=Depth;" "ScriptExternal=color;" "Pass=ImageProc;"; > { pass ImageProc < string Script = "RenderColorTarget0=;" "Draw=Buffer;";

The script code is quite logical. The first thing the shader does is to switch the depth and color targets to a texture declared earlier in the effect file. It then clears the contents of these buffers with color and depth values also stored in the file, before calling ScriptExternal, which has the effect of calling all other effects in the effect stack to complete their rendering to the current targets – this will result in the scene being drawn into the declared texture. The final call in the technique script jumps to the pass script, which simply restores the default render target and calls the pass shader to do the rendering, which in this case does edge detection based on the scene information in the texture.

3.2. Apply Materials to a Scene Figure 3-1 shows how to apply a material containing a full screen effect to the scene.

Figure 3-1. Using ScriptExecute Sorter

Notice that the material has a blue square at the top left, indicating that it is a scene command material. The scene shows the toothadil model, being rendered using a script that first sets the background to a texture image.

To enable a scene command material, right-click the material in the panel and select Apply to scene. The blue outline shows that it is the active scene command . Another right-click menu lets you sort the effects (ScriptExecute Sorter):

Page 22: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 18 November 2004

Chapter 4. Miscellaneous Hints and Tidbits…

4.1. Scripting & Automation Scripting and automation takes advantage of FX Composer's scripting features to gain greater control over the application and import or export data.

FX Composer has new C# scripts that can be loaded and compiled just like .fx files, and executed using a new Play button on the main toolbar.

The C# scripts that ship with FX Composer give an overview of what is possible. Using the script code, you can access the FX Composer scene graph, and some additional application services designed to help with common tasks such as taking screenshots.

A good first example to try is export_materials.cs, found in the MEDIA\Scripts directory. This script exports the materials currently loaded into FX Composer, along with the parameters in effect, as set on the properties panel.

The entry point to all FX Composer scripts is the Run method. When play is pressed on the toolbar, this is the function that is called. It looks like this: public int Run(NVSystem Sys) { }

The parameter passed to the script is the interface to the FX Composer engine, called NVSystem. Through this interface it's possible to access the entire FX Composer engine. For example, the following code accesses the scene: NVScene Scene; Sys.GetScene(out Scene);

Looking at the export_materials.cs file, you can see that this simple script walks through the scene finding all of the materials, and then writes them to a simple XML style of data file. It is not a huge leap to change this code to export data in any fashion so desired.

Other scripts of note are:

export_materials_keys.cs - Export materials and key frame information

material_export_images.cs - Given a list of .fx files, will generate a series of screenshots of each material.

fxcomposer_export_images.cs - Given a list of .fxproj projects will load each and save a screenshot.

Page 23: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 19 November 2004

spiral_scene.cs - Given a list of .fx files will build a spiral shape containing a sphere for each material.

In particular, it is worth trying the material_export_images script and choosing all the .fx files in the MEDIA\HLSL directory. This is a quick way to preview all materials, and build a directory full of material screenshots.

Script Advantages The C# scripts can be compiled in FX Composer, with full compilation error

reports, making them easy to build with fast turn-around. The scripts do not require a compiler or a custom DLL to function. The scripts can replace most plug-ins since they have the same access to the FX

Composer API as plug-ins do. Using C# it is often easier to read or write data files, such as XML.

Script Disadvantages Scripts cannot currently be loaded at startup or added to menus. The scripts

must be manually started. Scripts cannot be debugged - using messages, debug logs, etc. is the only way to

test script output. Scripts cannot run during frame ticks, in response to animations (though they

can cause a sequence of frames to be drawn).

Script Tips Always wrap the script in an exception handler and report errors (makes it

easier to debug) Modify the fxcomposer.config file to include the assembly This adds

additional .NET assemblies to FX Composer so that the script can call them. Use a tool such as .NET Reflector to example the nv_sys.interop dll.

This is a good way to discover the API methods available. The methods.cs script uses reflection to list the methods in the main system

interface - NVSystem. FX Composer also supports VB.NET scripts. Plug-inList.vb lists all the loaded

plug-ins using VB.NET If your script has an unhandled exception, FX Composer displays a dialog

pointing to the cause.

Page 24: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 20 November 2004

4.2. Projects vs. Packages FX Composer 1.5 introduced .fxproj project files, while keeping support for .fxcomposer packages.

Both file formats describe a complete scene, with shader, texture & geometry info. The differences between the two formats are below; the essential difference being how the various components are stored:

Packages keep textures as part of the package; Projects reference textures. Packages embed geometry as base64 encoded; Projects reference a binary geometry chunk for optimal storage.

Packages store .fx files separately, Projects store .fx files as part of the XML.

Note: While we may add features to the file format, FX Composer always loads previous versions.

Packages (.fxcomposer)

FX Composer package files are actually .zip archives. They currently contain:

An XML scene/material description (SceneGraph.xml) - see later. A binary component for mesh/animation data (Binary.bin) .fx files and textures.

The package file tries to be the best of both worlds: an easy XML parseable file format, with a binary chunk for data that doesn't store well as text (the XML refers to this data via an offset). You can explore .fxcomposer packages simply by renaming to .zip.

Package files are ideal for shipping a complete scene with effects and textures in a single binary. They are also compressed and store geometry optimally, so save space.

Package files aren't so good if you have a lot of packages all using the same texture maps - this results in duplicated media being stored in each package.

Projects (.fxproj)

Projects are standalone XML files describing an entire FX Composer scene, and its geometry. Geometry data is stored as base64 encoded binary at various nodes in the XML.

Project files are a great way to store your scene if you want to hand modify the file or read it from an external tool. They also save file size, since they store references to texture files, not the actual media.

Projects have the disadvantage that you need to ship the textures with the project.

Page 25: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 21 November 2004

XML Data

Both projects and packages have similar XML tree elements. The main difference is that geometry data is stored in a separate binary chunk for packages, but it is embedded in the XML for projects (because they are intended to be standalone). As far as the XML content is concerned:

The first line or so contains the file version and the build version of FX Composer made to save it.

Then come the project-specific search paths. Then the scene graph, with materials, hierarchy, parameter data, etc. Then a list of FX Composer objects/plug-ins required to successfully display this package.

Last in the file come the original paths of the media objects in the .fxcomposer compressed zip, so FX Composer knows where they were originally stored.

Full paths to all media and .fx files are always stored in the FX Composer package or project. When you open them, the current behavior is that FX Composer will look for your original drive copies, and if they aren't found, it will load the archived version into a 'MediaCache' directory underneath the main binary. If found, you'll be prompted to use the alternative. This behavior is configurable under File... Settings.

4.3. Configuration Files The FX Composer/data directory has a few useful configuration files that can be changed. All files are XML, and should be backed up before you tweak!

fxcomposer_config.xml Contains the list of standard materials offered when you click the 'new material' button. You can add your own standard materials along with text descriptions here, useful to give your artists a game-specific list of effects to use. fxedit.xml Contains rules for syntax highlighting. You can change the keywords that get highlighted and the colors used to highlight them.

fxmapping.xml Lists the standard set of semantics and annotations supported by FX Composer. The <semantic name="foo"> field represents FX Composer's standard internal names for these values. Optional <mapping name="foo"> fields enable you to remap your semantic/annotation names to those used by FX Composer.

plug-ins.inf Lists the plug-ins FX Composer should load, including ShaderPerf and geometry import plug-ins for .NVB and .x files. A future FX Composer SDK will allow developers to create their own plug-ins.

Page 26: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 22 November 2004

4.4. Mesh Sections Both .nvb and .x have mesh sections. But .x has the concept of polygon attributes which means that within a mesh section you can have different material properties. Each mesh section in a .nvb file has its own material.

It is up to the FX Composer importer as to how it gets this data in. Internally FX Composer has mesh sections, and per-polygon materials. However, the UI currently only exposes the mesh sections in the scene window (you can also modify all materials in the Materials panel).

An FX Composer material refers to a .fx file, and a list of parameters for that .fx file. More than one material can refer to the same .fx file with different parameters for each material.

In the future, FX Composer will get better at manipulating these things.

4.5. Preprocessor Directives Following are the preprocessor directives that FX composer defines as necessary. The user can add their own to the File Settings Compile Options dialog:

FXCOMPOSER_FP16, FXCOMPOSER_FP32,

FXCOMPOSER_FP16TARGET, FXCOMPOSER_FP32TARGET (all related to supported texture formats) FXCOMPOSER_SHADER_MODEL == 1, 2, 3, etc. based on pixel shader support.

4.6. Matrix Order You can now specify row or column major matrices in the same dialog. Row major will break all of our shipping files and projects, so is only intended for developer-supplied shaders that expect this orientation.

4.7. Reset on Window Resize bool bValue : FXCOMPOSER_RESETPULSE can be used for a Boolean that is reset to true when the window is resized (backbuffer reallocated), or when the user sets to true in the properties panel, or at start of day. It automatically resets to false after a frame of rendering. It is useful for initializing surfaces in shaders since it can select out a section of script code using the loop trick: “loopbycount=bValue;” “…. Script commands…” “loopend=;”.

The middle section is only run when the reset pulse is true.

Page 27: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 23 November 2004

4.8. Shadow Map Formats Shadow map formats can be created using format=”” annotation by supplying:

D24S8_SHADOWMAP, D24X8_SHADOWMAP, D16_SHADOWMAP

In this case, a texture is created with USAGE_DEPTHSTENCIL bit set.

4.9. FX Composer CAMERAPOSITION The CAMERAPOSITION semantic is unique to FX Composer and gives the camera position in world space to a float3.

Table 4-1. CAMERAPOSITION Semantic lightumbra Light cone umbra float

lightpenumbra Light cone penumbra float

lightrange Light effective range float

lightfalloff Spotlight cone falloff between umbra and penumbra

float4

mouseposition The mouse position on screen (x,y,time) float3

leftmousedown The left mouse down state, and its position at that time ( x, y, isdown, timedown)

float4

rightmousedown The right mouse down state, and its position at that time (x, y, isdown, timedown)

float4

cameraposition Viewer position in world space (replaced by position with space=view annotation).

float3

fxcomposer_ resetpulse

A pulsed boolean, reset on window resize or from the FX Composer user interface.

bool

All semantics and annotations supported by FX Composer are described in the Help Annotations and Semantics menu.

Page 28: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 24 November 2004

Tutorial #1. Building an FX Composer Plug-in

This tutorial will walk you through the steps required to build an FX Composer plug-in. The plug-in we will build is a simple scene importer, which imports an imaginary scene into FX Composer by creating necessary geometry and materials. The first part of the tutorial goes through the mechanics of writing the importer, the second part shows how to talk to the FX Composer scene graph and supply the imported data to it.

The example plug-in shown here is just a starting point. The FX Composer SDK ships with full source to a .X file importer, which includes support for skinning. An example of a proprietary, full-scene exporter is also included in the SDK. This tutorial will give you the knowledge to understand why they work in the way that they do, and a basic understanding of how to get data into FX Composer. You should review these examples for more details on how to build an FX Composer plug-in after completing this tutorial.

The tutorial is broken up into several sections:

Step 1: Create the Project Step 2: Create a Plug-in Class Step 3: Supporting the Plug-in Interface Step 4: Registering the Plug-in Step 5: Adding the Scene Import Code Step 6: Adding Animation

Page 29: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 25 November 2004

Step 1: Create the Project In this first step you are going to use the Visual Studio new project wizard to build a simple plug-in component for FX Composer.

1. In Visual C++, select File New Project.

2. Select Visual C++ Projects in the tree view, and choose ATL Project as the template type.

Page 30: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 26 November 2004

3. Select Attributed and Dynamic Link Library (DLL) from the ATL Wizard.

Notice that two projects have been created for you.

4. Remove the PS project. This is an optional proxy/stub library, and is not needed

Page 31: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 27 November 2004

Step 2: Create a Plug-in Class In Step 2 you will add a COM component to the plug-in, again using a wizard in Visual Studio.

FX Composer plug-ins are COM objects. The plug-in is implemented using ATL, since it enables you to build the plug-in with a minimum amount of effort, and hides the implementation details.

1. Select Add Class from the Visual C++ Project window.

2. Select Visual C++, ATL Simple Object template.

3. Select a name for your plug-in object and type the name into the ShortName box. This creates a default interface.

4. Rename the interface INVImportScene in the Interface box since you are creating a scene importer.

Page 32: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 28 November 2004

Step 3: Supporting the Plug-in Interface

In Step 3, the plug-in interfaces for a scene importer are added to the project.

Now you have a framework application to modify the plug-in component to support the interfaces you need. In FX Composer, all plug-ins must support the INVPlug-in interface. We are also supporting the INVImportScene interface, since we are building a geometry importer in this case.

At this point , you have source files for the plug-in (in the example, we chose MyPlug-in as the short name, and therefore got myplug-in.h and myplug-in.cpp as implementation files). The first thing to do is to remove the interface declaration for INVImportScene that the wizard created, since we are using an interface already declared in the SDK for FX Composer.

// !!! REMOVE THESE LINES // INVImportScene [ object, uuid("76CBB2A1-05DC-4A00-B929-21BA61B956B6"), dual, helpstring("INVImportSceneInterface"), pointer_default(unique) ] __interface INVImportScene: IDispatch { };

Farther down in the myplug-in.h file is the class definition. It should currently look like this:

class ATL_NO_VTABLE CMyPlug-in : public INVImportScene { ... }

Page 33: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 29 November 2004

You can now add the INVPlug-in interface to the class declaration, and the methods for the plug-in interfaces. The result is as follows #include "nv_sys\nv_sys.h" // CMyPlug-in [ coclass, threading("apartment"), vi_progid("tutorial.MyPlug-in"), progid("tutorial.MyPlug-in.1"), version(1.0), uuid("5A6613BB-4F22-42AA-8E50-2C9D96B44C3F"), helpstring("MyPlug-in Class") ] class ATL_NO_VTABLE CMyPlug-in : public INVImportScene, public INVPlug-in { public: CMyPlug-in() { } // INVSceneImporter interface methods (from "nv_sys\nv_sys_idecl.h" virtual BOOL INTCALLTYPE ImportScene(INVScene* pScene, INVString* pszPath); virtual BOOL INTCALLTYPE GetFileExtension(unsigned int i, INVString** pszName, INVString** pszExtension); virtual unsigned int INTCALLTYPE GetNumFileExtensions(); // INVPlug-in interface methods implemented by this macro IMPLEMENT_PLUG-IN("scene_importer", "My custom file importer", "Imports our custom file format into FX Composer", "", "", "") public: DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } }

Page 34: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 30 November 2004

The following items were added to the class:

#include "nv_sys\nv_sys.h". This is the only included file from the FX Composer SDK. To include nv_sys.h, you also added the FX Composer SDK\include directory to the project paths. At the same time, you added the SDK\lib directory to the project linker options.

The 3 methods required by the INVImportScene interface: ImportScene, GetFileExtension, GetNumFileExtensions. You implement these functions in Step 4. The definition for these methods are found in the _nv_sys.h file supplied in the SDK\src\nv_sys directory.

A macro that implements the INVPlug-in interface methods. This is just a short cut and saves some typing. The macro parameters are:

The category of the plug-in we are supporting. scene_importer indicates that we are a scene importer plug-in. A plug-in category is a contract between FX Composer and the plug-in that it will implement a certain set of interfaces. In the case of a scene importer, the only interface required is INVImportScene (and INVPlug-in, required by all plug-ins). A description of plug-in categories, and the interfaces required to support them can be found here.

The user interface name for the plug-in, which will appear in FX Composer - in this case My custom file importer.

A long description of what your plug-in does, for the benefit of users of FX Composer.

The final three empty strings are for future features, and are left blank.

Now you almost have a valid FX Composer plug-in. To make the plug-in compile you need to add some code to myplug-in.cpp. The following shows the necessary work: // MyPlug-in.cpp #define INITNVGUID // Required in one file only, without precompiled headers! #include "stdafx.h" #include "MyPlug-in.h" IMPLEMENT_GETSYSINTERFACE; // Enable us to call GetSYSInterface()-> // Basic interface support // Import scene is where we do the work in the plug-in. Here we just reset the scene BOOL CMyPlug-in::ImportScene(INVScene* pScene, INVString* pszPath) { pScene->Reset(); return TRUE; } // We return the list of file extensions we support here. BOOL CMyPlug-in::GetFileExtension(unsigned int i, INVString** ppName, INVString** ppExtension)

Page 35: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 31 November 2004

{ if (i == 0) { INVStringPtr pName = MAKE_NVSTRING("My plug-in"); INVStringPtr pExtension = MAKE_NVSTRING("zzz"); // The smart pointers will release when out of scope. We are returning them, so addref the count pName->AddRef(); pExtension->AddRef(); *ppName = pName; *ppExtension = pExtension; return TRUE; } return FALSE; } // How many file extensions do we support? unsigned int CMyPlug-in::GetNumFileExtensions() { return 1; }

The IMPLEMENT_GETSYSINTERFACE macro enables your plug-in to get access to the FX Composer engine using the GetSYSInterface() global function. The INITNVGUID #define is required to instantiate some COM interface types. Turn off precompiled headers for this file, since the INITNVGUID macro will not work through a precompiled header (DirectX programmers may recognize this problem as a classic COM issue).

The remaining code implements an empty ImportScene function, where you later add our import code and two functions to return the file formats that are supported.

You are now done with the plug-in framework and can compile the plug-in.

Step 4: Registering the Plug-in At this point you need to register your plug-in with the FX Composer application, and test that it functions as expected.

The new plug-in is not useful until FX Composer can find it. This part is very easy. If you look in the myplug-in.h file, you see the component attributes just above the class declaration:

Page 36: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 32 November 2004

[ coclass, threading("apartment"), vi_progid("tutorial.MyPlug-in"), progid("tutorial.MyPlug-in.1"), version(1.0), uuid("5A6613BB-4F22-42AA-8E50-2C9D96B44C3F"), helpstring("MyPlug-in Class") ]

The text you need from here is progid. This gives FX Composer all the information it needs to load the plug-in. FX Composer scans for progid's by looking in the plug-ins.xml file in the FXComposer\data directory. We need to add the following text to the file: <plug-in progid="tutorial.MyPlug-in.1"/>

Run FX Composer and go to the File Import Scene menu. You should see the plug-in displayed in the scene import dialog:

The plug-in is also visible in the Tools Plug-ins List... dialog, shown third from the bottom in this example:

Page 37: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 33 November 2004

Now that you have a working plug-in, you can test the functionality to see how it works so far.

Remember, by adding that call to Scene Reset() in the plug-in you removed all geometry from the current scene. If you create a dummy file, with the extension we chose (.zzz), then you can use the import scene dialog to import it. If all goes well, you should see that the sphere in the default FX Composer scene disappears.

Step 5: Adding the Scene Import Code

Now it is time to interact with the FX Composer scene graph and add your data. At the end of this step you will have a working importer with a shiny reflective triangle. For the purposes of this plug-in, you are going to make up the data that is imported. A real plug-in would, of course, read a proprietary file format and generate the data from it. In this case, the imported data consists of a single triangle with a material.

Page 38: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 34 November 2004

You already have the starting point for the plug-in. It is the ImportScene method, which is currently emptying the scene of geometry:

BOOL CMyPlug-in::ImportScene(INVScene* pScene, INVString* pszPath) { pScene->Reset(); return TRUE; }

Creating the Material To help build the plug-in in stages, start by creating the material. This is a relatively easy step, and involves creating the material object and setting an effect, before attaching the material to the scene. Here is the code:

pScene->RemoveAllMaterials(); INVMaterialPtr pMat(__uuidof(NVMaterial), true); pMat->Create(MAKE_UNIQUENAME("Triangle Material", NULL)); INVStringPtr pFound; GetSYSInterface()->FindFile(MAKE_NVSTRING("bumpreflecthlsl.fx"), NULL, NVFFC_ALL, &pFound, NULL); if (!pFound->Empty()) { pMat->LoadEffect(pFound); } pScene->AddMaterial(pMat);

The first thing to do is remove all existing materials from the scene. Then create a material object, and give it a unique name. The MAKE_UNIQUENAME macro can be used for this purpose, and is designed to ensure that no two objects in the FX Composer scene have the same name.

Next, find the effect file using the FindFile API. Load the material and add it to the scene. Running the plug-in at this point should show a single material being created and the scene being reset. The material is a bumpy shiny effect.

Page 39: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 35 November 2004

Creating the Transform The scene graph for FX Composer is fairly straightforward. It consists of a network of objects connected by transform links. Transform links form the scene graph, and the nodes form the geometry that is to be rendered. Transform links have pointers to nodes. Any node in the scene must support the INVNode interface, and any transform link supports the INVTransformLink interface.

Now you are going to create a transform for the triangle. Here is the code: // A transform for the triangle INVTransformLinkPtr pTransform; pScene->CreateTransform(&__uuidof(NVTransformLink), &pTransform); // The NVTransformLink object supports INVTransformLink pTransform->SetAnimated(true); // We will add animation data to the transform pTransform->SetSeparable(true); // Keep scale, translation & rotation data seperate pTransform->SetName(MAKE_NVSTRING("triangle_frame")); // Get the scene root transform, and add ours to it // NB: The scene reset will have removed all other transforms. INVTransformLinkPtr pRoot; pScene->GetRootTransform(&pRoot); pRoot->AddChild(pTransform);

This code creates a transform and adds it to the scene. It is call SetAnimated on the link to enable time-based updates of its parameters. If animation is not enabled, then any updates to the transform will always happen at time key '0'. SetSeparable is called to ensure that you can modify scale, translation and rotation parts of the transform. The alternative is a transform that is simply a matrix, and this cannot be animated. No separable transforms are supported for data import where the original components of the transform are no longer available, such as in non-animated nodes of .x files.

Creating the Geometry Pipe Now that you have a transform, it’s time to add a geometry pipe to it.. Vertices are stored in streams in FX Composer. Each stream represents a single chunk of vertex or primitive data, such as 'position', 'normal', 'bone weight'. Data streams remain separate in FX Composer until they reach the top of the geometry pipe, at which point they are assembled into vertex buffers and sent to the GPU. Each stream has semantic information to enable FX Composer to understand the nature of the data. A plug-in can provide any number of streams, and FX Composer can be told to build missing ones by adding NVGeoPipeObject's to a geometry pipe. A special kind of stream, a primitive stream, holds drawing commands such as triangle lists, etc.

Page 40: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 36 November 2004

Streams are collected together into NVGeoPipeBundle objects, which transport the stream data up the NVGeometryPipe. To build the triangle you must build the geometry streams, add them to a bundle, and create a geometry pipe. Geometry pipes consist of a stack of NVGeoPipeObject's which modify the geometry bundle as it flows up the pipe. In this case, add NVGeoPipeObject_Mesh to the front of the geometry pipe and add the geometry bundle to it. Then attach the geometry pipe to the NVTransformLink, since a geometry pipe also supports the INVNode interface. The code below shows the complete steps: // Create a geometry bundle INVGeoPipeBundlePtr pBundle(__uuidof(NVGeoPipeBundle), true); // Create a geo pipe, add a mesh INVGeoPipePtr pGeoPipe; INVNodePtr pPipeNode; pScene->CreateNode(&__uuidof(NVGeoPipe), &pPipeNode); pGeoPipe = pPipeNode; INVGeoPipeObject_MeshPtr pMesh = INVGeoPipeObject_MeshPtr(__uuidof(NVGeoPipeObject_Mesh), true); pMesh->SetBundle(pBundle); // Add the mesh to the geometry pipe. pGeoPipe->AddObject(PIPE_FRONT, (INVGeoPipeObjectPtr)pMesh); // Add the geometry pipe to the transform pTransform->AddNode(pPipeNode); // The streams we'll provide. INVGeoStreamPtr pPositionStream; INVGeoStreamPtr pNormalStream; INVGeoStreamPtr pTextureStream; INVGeoStreamPtr pPrimitiveStream; INVGeoStreamPtr pTangentStream; INVGeoStreamPtr pBinormalStream; // Offset into the streams unsigned long StartPosition; unsigned long StartNormal; unsigned long StartTexture; unsigned long StartTangent; unsigned long StartBinormal; unsigned long TriangleIndex; // Get the data streams, and the start location pBundle->GrowStreamByUsage(NVGEOSTREAMUSAGE_POSITION, 0, 3, &StartPosition, &pPositionStream);

Page 41: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 37 November 2004

pBundle->GrowStreamByUsage(NVGEOSTREAMUSAGE_NORMAL, 0, 3, &StartNormal, &pNormalStream); pBundle->GrowStreamByUsage(NVGEOSTREAMUSAGE_TEXCOORD, 0, 3, &StartTexture, &pTextureStream); pBundle->GrowStreamByUsage(NVGEOSTREAMUSAGE_TANGENT, 0, 3, &StartTangent, &pTangentStream); pBundle->GrowStreamByUsage(NVGEOSTREAMUSAGE_BINORMAL, 0, 3, &StartBinormal, &pBinormalStream); pBundle->GrowStreamByUsage(NVGEOSTREAMUSAGE_PRIMITIVES, 0, 1, &TriangleIndex, &pPrimitiveStream); // Triangles for the primitive stream INVIndexSetPtr pSet; INVPrimitivesPtr pTriangles(__uuidof(NVTriangles), true); pTriangles->GetIndexSet(&pSet); // Currently only support one index set. pSet->AddSet(NVGEOSTREAMUSAGE_POSITION, 0); // Triangle attributes INVPrimitiveAttributesPtr pAttr; pTriangles->GetAttributes(&pAttr); pAttr->AddAttribute(NVPRIMITIVEATTRIBUTE_MATERIAL); pTriangles->Resize(1); NVFloat3 Pos[3]; NVFloat3 Tex[3]; Pos[0].x = 0.0f; Pos[0].y = 1.0f; Pos[0].z = 0.0f; Pos[1].x = -1.0f; Pos[1].y = 0.0f; Pos[1].z = 0.0f; Pos[2].x = 1.0f; Pos[2].y = 0.0f; Pos[2].z = 0.0f; Tex[0].x = 0.5f; Tex[0].y = 1.0f; Tex[0].z = 1.0f; Tex[1].x = 0.0f; Tex[1].y = 0.0f; Tex[1].z = 0.0f; Tex[2].x = 1.0f; Tex[2].y = 0.0f;

Page 42: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 38 November 2004

Tex[2].z = 0.0f; DWORD Index[3] = { 0, 1, 2 }; pTriangles->SetIndices(TriangleIndex, 1, &Index[0]); // Tangent/binormal is simple on a triangle! NVFloat3 Binormal, Tangent, Normal; Tangent.x = 1.0f; Tangent.y = 0.0f; Tangent.z = 0.0f; Binormal.x = 0.0f; Binormal.y = 1.0f; Binormal.z = 0.0f; Normal.x = 0.0f; Normal.y = 0.0f; Normal.z = -1.0f; for (unsigned int k = 0; k < 3; k++) { pNormalStream->SetVec3(StartNormal + k, &Normal); pTangentStream->SetVec3(StartTangent + k, &Tangent); pBinormalStream->SetVec3(StartBinormal + k, &Binormal); pPositionStream->SetVec3(StartPosition + k, &Pos[k]); pTextureStream->SetVec3(StartTexture + k, &Tex[k]); } // Add the triangles to the primitive stream pPrimitiveStream->SetPrimitives(TriangleIndex, pTriangles); // Assign the material NVMEDIAHANDLE* pAttributeMat; pAttr->GetPointerByAttribute(NVPRIMITIVEATTRIBUTE_MATERIAL, (void**)&pAttributeMat); INVMediaPtr pMedia = (INVMediaPtr)pMat; pAttributeMat[0] = pMedia->GetHandle();

This code section is relatively straightforward. First, it built the geometry pipe, added a mesh to it, adds a bundle of streams to the mesh, and fills in the geometry streams for the bundle. The geometry data supplied is for a simple triangle, with tangent and binormal data for bump mapping. The final part of the code sets an attribute stream associated with the triangles. The attribute is set to the handle for the material (all materials in FX Composer support the INVMedia interface, which can be used to retrieve an NVMEDIAHANDLE).

Page 43: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 39 November 2004

When you run the plug-in, the following image is displayed:

Step 6: Adding Animation Step 6 shows how to animate and set key frames in FX Composer. To demonstrate animation in FX Composer, add a simple modification to your triangle plug-in.

FX Composer stores animation keys for all properties. Any value displayed in the properties panel can potentially have an animation associated with it. This also applies to transformations. To view your current transform, expand the scene panel to navigate to it.

Page 44: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Miscellaneous Hints and Tidbits

DA-01057-001_v03 40 November 2004

The Properties panel looks like the following:

To modify the translation property of the triangle transform, set the number of animation ticks the engine will go through. GetSYSInterface()->SetTicks(100);

Assign key frames to the translation part of the transform: NVFloat3 Trans; Trans.x = 0.0f; Trans.y = 0.0f; Trans.z = 0.0f; pTransform->SetTranslation(0, &Trans); Trans.x = 1.0f; pTransform->SetTranslation(33, &Trans); Trans.x = -1.0f; pTransform->SetTranslation(66, &Trans);

Run the sample. Pressing the Play button the toolbar causes the triangle to slide left and right. Observe that in between key frames, FX Composer is interpolating the results.

Page 45: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 41 November 2004

Tutorial #2 Measuring and Managing

Shader Performance with FX Composer

FX Composer does more than provide you with a way to view, edit, and test shaders on models and scenes. By using FX Composer’s performance tools and Shader Perf Panel display, you can assess and modify the efficiency and performance of your shaders—not just in general terms, but even for running on various different specific GPUs.

In this brief tutorial, we’ll look at a sample shader file and make some changes to see how they affect the performance of that shader. You will find the accompanying sample code in \MEDIA\fxcomposer\tutorials\perf_tutor.fxcomposer project.

Sources of Performance Information FX Composer provides performance information through two major sources: the Shader Perf panel and the Scene panel. These panels are visible by default – the Scene panel displays your model with the currently-assigned shader(s), and the Shader Perf panel will be hidden under the Properties panel (tap the Shader Perf tab to reveal it). Both panels are dockable anywhere on screen or can be their own free-floating windows. If you don’t see these panels, you can enable them from View Panels ShaderPerf panel to see them.

The Shader Perf panel contains a large text area showing you the compiled DirectX 9.0 assembly-language instructions that are executed for your HLSL shader. The pulldown menus at the top of the Shader Perf panel allow you to select each part of the selected HLSL FX shader – the technique, pass within that technique, vertex or pixel shaders, and (for pixel shaders) specific profiling based upon the GPU used (DirectX 9 is smart enough when compiling to consider this aspect at runtime). This last pulldown allows you to evaluate shader performance against a wide range of GPUs, from low-end consumer to the high-end workstation, to assess their specific problems and find their “sweet spots.”

Page 46: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Measuring and Managing Shader Performance with FX Composer

DA-01057-001_v03 42 November 2004

Performance analysis is presented in the main body of the Shader Perf panel, first with an instruction count before the shader begins, and then (for pixel shaders) with a report of its scheduling efficiency at the bottom of the listing.

The Scene panel can give you further assessment of the efficiency of your shader, by displaying a frames-per-second number for the render. This number will be visible for supported GPUs (that is, those with scheduling info available) when Tools Options Draw Always is turned on.

Try It Yourself: The PerfTutor.fx Shader

To try the Performance Tools yourself, use a shader called PerfTutor.fx. The PerfTutor.fx is a very generic shader using per-pixel lighting, two different kinds of lamps, and a variety of options (set by #define flags) that permit you to try different methods to get the same or nearly-the-same results and see the effects on final image and scene performance.

Use the following steps to create the scene in the example shown in Example 1:

1. Start FX Composer.

2. Make sure that the Scene panel is visible and the Shader Perf panel is available.

3. From the File menu, select File Load Project.

4. Open MEDIA/projects/tutorials/perftutor.fxproj.

5. Select the Perf Tutor material in the Materials panel.

6. Your display should look something like that shown in Example 1 (this shader can be applied to any object, if you want to alter the default)

Page 47: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Measuring and Managing Shader Performance with FX Composer

DA-01057-001_v03 43 November 2004

Example 1. perftutor.fx The PerfTutor.fx file contains a number of compile-time #define flags that let you change the way the code functions with a minimum of typing. These flags can turn on and off specific features of the shader, or control the way shading is calculated. The flags are right at the head of the shader code: // Compile-time flags // feature flags //#define DO_COLORTEX //#define DO_BUMP //#define DO_GLOSSMAP //#define DO_QUADRATIC //#define DO_REFLECTION // performance flags //#define USE_NORMALIZATION_CUBEMAP

By default, these flags are all commented-out. We’ll change them later to see their effects on final shader performance.

Page 48: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Measuring and Managing Shader Performance with FX Composer

DA-01057-001_v03 44 November 2004

Looking at the Shader Perf Panel Playing with the pulldowns Shader Perf panel, you can select any of the available techniques within PerfTutor.fx (OnePass, MultiPass, AmbiOnly, DirOnly, PtOnly).

Select AmbiOnly, the pass p0 (the only pass in this particular technique), Pixel Shader, and NV36.

The display of the shader panel fills with NV30-specific information about this particular (a deliberately very short) pixel shader: Pixel Shader: Target: GeForce FX 5700 Ultra (NV36) :: Unified Compiler: v66.81 Cycles: 1 :: # R Registers: 2 Pixel throughput (assuming 1 cycle texture lookup) 950 MP/s ======================================================== Shader performance using all FP16 Cycles: 1: :: # R Registers: 2 Pixel throughput (assuming 1 cycle texture lookup) 950 MP/s ======================================================== Shader performance using all FP32 Cycles: 1: :: # R Registers: 2 Pixel throughput (assuming 1 cycle texture lookup) 950 MP/s ======================================================== PS Instruction: 4 ps_2_x def c2, 1, 0, 0, 0 mov r0.xyz, c1 mul r0.xyz, r0, c0 mov r0.w, c2.x mov oC0, ro --- # of R register: 2 ---

Note: performance metrics may vary slightly depending on the Unified Compiler version used by the Shader Perf panel, which is determined by the version of the performance DLLs installed on your system.

GPU Efficiency A value is printed for the expected number of GPU processor cycles required to execute this shader. The note “assuming 1 cycle texture lookup” reminds you that sometimes issues external to the pixel shader itself can affect the overall performance – for example, if you declare huge cube maps or otherwise start thrashing the GPU texture cache, then in some cases texture-access functions, which can usually take only a single processor cycle, may stall and run slower. Good resource management is the key to overcoming such situations.

Alternative evaluations are made for each shader. As you see above, the shader is evaluated for a range of floating-point precision, from performing all operations in FP16 (“half”) precision, to FP32 (“float” or IEEE floating point). One option for improving efficiency on many shaders (but not all, as this example shows) is to move operations to the “half” type. FP16 data often can use only half the GPU bandwidth of FP32, providing better efficiency.

Page 49: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Measuring and Managing Shader Performance with FX Composer

DA-01057-001_v03 45 November 2004

Let’s switch to a more complex example. Select “OnePass” and the Pixel Shader. The compiled code for NV36 is now much longer – 42 instructions. At the top of the panel, we’ll see a variance in the number of cycles, depending on the floating point precision.

Tweaking the Code In this example, we are going to set a compile-time flag and see the results on shader performance.

In the Editing Panel, un-comment the definition of //#define USE_NORMALIZATION_CUBEMAP by removing the leading // marks so the line appears as: #define USE_NORMALIZATION_CUBEMAP

You are able to see the color shift immediately from green to blue and black, showing that FX Composer recognizes these instructions.

Now press Ctrl-S or select File Save to save these changes and press the Build button to recompile the shader (or select Build Compile or press Ctrl-F7). The panel information is updated. You can see a new texture in the Textures panel (if displayed), showing a normalization cube map. When this option is enabled, the cube map is generated by PerfTutor.fx, using the DirectX 9.0 virtual machine (the specific functions are defined in the header file normalization.fxh). PerfTutor.fx is written to replace all calls to normalize() in the pixel shaders with texCUBE() calls when this texture is present.

What effect does this have on our shader performance numbers? We can check in the Shader Perf Panel.

The newly-compiled shader actually has more assembly-language instructions—51 instructions, versus the previous 42—but checking the efficiency and pass counts tell us that instruction counts can be deceptive.

For NV36, still at 100% efficient use of the GPU, the number of shader passes, the default count of clock cycles needed to execute this shader, has declined from 37 to 31, a substantial improvement. So, even though the shader itself is longer, the execution of the shader on NV36 is faster.

The story for different GPU models will vary. You can verify this by selecting them as options..

Frames per Second For GPUs that the performance analyzer recognizes an FPS counter can be displayed in the Scene panel. To see the counter, turn on the Tools Options Draw Always option, and then either wiggle the model in the render window using the transform tools (e.g., Rotate Scene

) or press the green Run Animation button (you can use Ctrl-G/Ctrl-H to toggle animation on/off).

A few things to remember when using this frame counter:

The frame counter is showing you the speed of FX Composer in this window on this model. It is not showing you the frame rate of your model in your game engine. The

Page 50: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Measuring and Managing Shader Performance with FX Composer

DA-01057-001_v03 46 November 2004

frame counter is there as a means for you to evaluate relative performance between shader methods within FX Composer on your computer with your GPU—not as an absolute counter of efficiency and speed. Use the Shader Perf panel numbers to create those estimates and calibrate them against your game engine’s own characteristics.

The technique used in the Scene panel is the one specified in the Properties panel for this shader—not the technique specified in the Shader Perf panel.

While the Shader Perf panel can evaluate many different GPUs, the Scene panel FPS counter shows you the value for just one—the GPU installed in your system.

When Draw Always is engaged, FX Composer is using the CPU to the maximum. When Draw Always is turned off, FX Composer only draws the scene when something changes. If you’re multitasking (running Microsoft’s Visual Studio or a game engine simultaneously with FX Composer) you may see resource fighting. Turn off Draw Always to get best performance from external applications.

4.10. What’s Next? Now you can experiment with setting other PerfTutor options, checking the characteristics of other GPUs, editing the code, and more importantly, applying these same lessons to your own .fx shaders. Have fun!

Page 51: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

DA-01057-001_v03 47 November 2004

Tutorial #3. Optimizing a Bump Mapping Shader

Building on what you learned in Tutorial #1, this tutorial provides some additional techniques you can use in performance tuning your shaders, using a simple tangent-space bump mapping example. You can find the accompanying sample code in the following location: \MEDIA\projects\tutorials\perf_bumpplastic.fxproj

Shader Optimization Optimizing pixel shaders for modern graphics processors is a non-trivial task. In previous generations of hardware there was usually a one-to-one correspondence between pixel shader assembly code and the instructions that got executed by the hardware. One could often assume that each instruction would take a single clock cycle to execute. As GPUs have become more complex, and more like CPUs in many ways, the gap between the assembly language abstraction and the hardware has become larger. Modern GPUs include multiple pixel pipelines, each of which may include multiple math units and texture units. This means that the GPU can potentially execute multiple math and texture instructions in a single cycle. The ordering of instructions can affect the extent to which these execution units are used optionally.

Performance is also affected by register usage. The GPU processes groups of pixels in parallel, but only has a finite amount of register storage. Therefore using more registers means that fewer pixels can be processed at a time, and performance is reduced. NVIDIA GPUs support 16-bit “half” precision floating point numbers, which can help to improve performance by reducing register storage requirements. Data dependencies between instructions can also affect performance. In addition, these performance characteristics can vary widely between different GPUs. Using high level shading languages such as HLSL adds another layer of abstraction which can further obscure performance issues.

Fortunately, technology has come to the rescue. NVIDIA’s Unified Compiler, which is built into the graphics driver, takes high-level pixel and vertex shader assembly code and generates optimized micro-code for the target GPU. The Shader Perf panel in FX Composer simulates the Unified Compiler to allow you to analyze the performance of your shaders and report how they will execute on different GPUs.

Page 52: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Optimizing Tangent-space Bump Mapping Shader

DA-01057-001_v03 48 November 2004

Despite the automated optimization in the Unified Compiler, there are still a few simple rules that you can follow to ensure that your shaders run as fast as possible on all hardware.

Optimize your algorithms Premature optimization is the root of all evil. Before attempting any of the lower-level optimizations described below, take a high-level look at the shader and see if there is some way you could rearrange the code so that it that requires less work.

Perform calculations only as often as necessary Some calculations can be moved from the pixel shader to the vertex shader, and the results passed to the pixel shader as texture coordinates. A common example is calculating a view vector. This varies linearly, so can be calculated per-vertex and interpolated. Texture coordinate interpolation is not always free, but this is almost always a performance win overall. In a similar way, sometimes calculations can be moved off the hardware completely. For example, multiplying a light color by a material color can be done on the CPU.

Replace complex math functions with texture look-ups Complex expressions such as lighting functions can be encoded into textures, and then accessed using a single texture lookup. This sacrifices some interactivity (the parameters can not be changed without rebuilding the texture), but is almost always faster on current hardware. The FX runtime includes a virtual machine that allows you to write functions in HLSL that can be used to generate textures very easily.

Use half precision where possible Half precision is almost always sufficient for representing colors and unit-length vectors, and requires half the register storage. Vectors representing distances in world coordinates will usually need to use full float precision. Remember that there are an infinite number of real numbers, but half precision floats can only represent 65536 of them!

Use lower pixel shader versions if possible GeForce FX series GPUs include support for the fixed-point type and instructions used in Direct3D Pixel Shader v1.4 and below. If your shader can be expressed in a lower version pixel shader, it may run faster than the equivalent operations in pixel shader v2.0 and FX Composer supports all of these shader profiles

Page 53: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Optimizing Tangent-space Bump Mapping Shader

DA-01057-001_v03 49 November 2004

FX Composer Shader Performance Tools The Shader Perf panel in FX Composer makes it easy to see how much modifying your shader effects performance. It is based on an architectural simulator of the GeForce FX shader hardware, and can simulate hardware from the GeForce FX 5200 to the FX 5950. It displays several important statistics:

PS Instructions The number of Direct3D pixel shader instructions used

Cycles The number of clocks cycles the optimized shader will take to execute on the selected hardware. Note that this is often lower than the number of instructions, since multiple instructions can be executed per clock cycle.

# R registers This is how many full-precision “R” registers the optimized shader uses. This is affected by how many temporary variables your shader uses, and can have a big effect on performance. Note that two half-precision registers can fit in a single R register, so if you are using half-precision, double this number to get the actual number of registers used.

Optimizing Your Shader One Step at a Time

Once you have loaded the perf_bumpplastic.fxproj project, click on the BumpPlasticPerf.fx material to make it the active material and look in the Properties panel. Each step in optimizing the shader is implemented as a separate “technique”. You can switch between the techniques by selecting them from the Techniques pull-down menu in the properties panel. By clicking on the Shader Perf panel and selecting Pixel Shader from the pull down menu, you can compare the performance of the different optimization steps.

The shader implements simple tangent space bump mapping with a color map, using the Blinn/Phong lighting model.

If you read through the BumpPlasticPerf.fx file you will see the section of HLSL code that corresponds to each technique. The vertex shader is the same for each technique; we only modify the pixel shader.

Step 1. The initial version of the shader BumpPlasticPS_0 uses math for the lighting calculation. It calls a function Phong to calculate the Blinn/Phong lighting model given the dot products between the normal vector, light vector and half angle vector. It uses float precision for everything.

Step 2. In this version of the shader, we remove the code to normalize the normal vector “N”. Since the normal is being read from a normal map, we can assume that it will be almost unit length, apart from de-normalization caused by linear texture filtering. If you switch between step 1 and step 2 you might be able to notice a slight change in the appearance of the specular highlights. Note that although this only reduces the number of

Page 54: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

Optimizing Tangent-space Bump Mapping Shader

DA-01057-001_v03 50 November 2004

instructions by one (the NRM instruction), it reduces the number of cycles by 2 because the NRM macro is expanded to several instructions (DP3, RSQ, MUL).

Step 3. In this step we replace the lighting math with a texture lookup. We use the same Phong to build a texture that encodes the lighting function. In the shader we can then replace the function call with a 2D texture lookup based on N.L and N.H.

Step 4. This is identical to step 2, but we have changed all the variables to half precision. This reduces the number of R registers required to 2.

Step 5. In the final step we convert the shader to pixel shader version 1.1. Obviously this will not be possible with all shaders, but for this example it illustrates the performance benefits..

The table below shows the relative performance of each optimization step. Frames per second numbers were measured on a NV35 with a full screen window.

Step FPS Instrs. Cycles #R regs Comment 0 75 23 14 4 Original shader

1 85 22 12 4 Remove normalize (N)

2 103 21 9 4 Replace math with texture lookup

3 143 21 5 2 Change floats to half precision

4 148 10 4 2 Convert to PS1.1

Note: performance metrics may vary slightly depending on the Unified Compiler version used by the Shader Perf panel, which is determined by the version of the performance DLLs installed on your system.

Working through all four optimization steps in this sample shader yields a 2x performance improvement (measured by FPS). The largest benefits come from replacing math with texture lookups and using half precision. By following these same simple rules and making use of the performance tools in FX Composer, you can ensure that your shaders will run as fast possible and provide the best end user experience on all hardware.

Page 55: User Guide - Lunds tekniska högskolafileadmin.cs.lth.se/cs/Education/EDA101/papers/FX... · integrated development environment with real-time preview and optimization features available

NVIDIA Corporation 2701 San Tomas Expressway

Santa Clara, CA 95050 www.nvidia.com

Notice

ALL NVIDIA DESIGN SPECIFICATIONS, REFERENCE BOARDS, FILES, DRAWINGS, DIAGNOSTICS, LISTS, AND OTHER DOCUMENTS (TOGETHER AND SEPARATELY, “MATERIALS”) ARE BEING PROVIDED “AS IS." NVIDIA MAKES NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.

Information furnished is believed to be accurate and reliable. However, NVIDIA Corporation assumes no responsibility for the consequences of use of such information or for any infringement of patents or other rights of third parties that may result from its use. No license is granted by implication or otherwise under any patent or patent rights of NVIDIA Corporation. Specifications mentioned in this publication are subject to change without notice. This publication supersedes and replaces all information previously supplied. NVIDIA Corporation products are not authorized for use as critical components in life support devices or systems without express written approval of NVIDIA Corporation.

Trademarks

NVIDIA and the NVIDIA logo are registered trademarks of NVIDIA Corporation. Other company and product names may be trademarks of the respective companies with which they are associated.

Copyright

© 2004 NVIDIA Corporation. All rights reserved


Recommended