This page uses frames, but your browser doesn't support them.
DirectX Graphics This section provides information about using the Microsoft®
DirectX® Graphics application programming interfaces (APIs). As with other
components of DirectX, DirectX Graphics can be used with C, C++, and Microsoft
Visual Basic®. For an overview of the organization of the DirectX Graphics
Help, see Error! Bookmark not defined.. Roadmap Information on Microsoft®
DirectX® Graphics is presented in the following sections. What's New in DirectX
Graphics. New features and functionality of this component in DirectX 8.0. If
you've used Microsoft Direct3D® or Microsoft DirectDraw® before, read this
section first, because much has changed since DirectX 7.0. Introduction to
DirectX Graphics. An overview of what DirectX Graphics is and what it can do
for your application, together with a look at some key principles and necessary
background information. Understanding DirectX Graphics. A deeper look at the
underlying structure. This section won't teach you how to implement vertex
lighting or texture mapping in your application, but it will help you
understand the mechanics of the API when you get into the details. Using
DirectX Graphics. A guide to using the API. You'll probably want to familiarize
yourself with the table of contents for this section and then refer to parts of
it as you need specific information. Use it in conjunction with the reference
section. Advanced Topics in DirectX Graphics. Information of interest for
creating applications that take full advantage of the power of DirectX
Graphics. Programming Tips and Tools. Miscellaneous information about
compiling, debugging, and optimizing DirectX Graphics applications. In
addition, this section contains information on issues that may be encountered
when using pre-DirectX 8.0 drivers. [C++] DirectX Graphics C/C++ Tutorials.
Step-by-step implementation of basic functionality. If you learn best by doing,
this is a good place to start. DirectX Graphics C/C++ Samples. A guide to the
sample applications in the SDK to point you to the sample code you need.
Direct3D C/C++ Reference. Detailed information for all the API elements
declared in the Microsoft Direct3D® header files. Direct3DX C/C++ Reference.
Detailed information for all the API elements declared in the Direct3DX utility
library header files. Direct3DX Shader Assemblers Reference. Detailed reference
information on the Direct3DX vertex and pixel shader assemblers. Effect File
Format. Information on the format of effect files, which consist of a set of
parameter declarations, followed by descriptions of various techniques X File
C/C++ Reference. Detailed information for all the API elements declared in
Dxfile.h. X File Format Reference. Detailed information on the DirectX (.x)
file format. [Visual Basic] DirectX Graphics Visual Basic Tutorials.
Step-by-step implementation of basic functionality. If you learn best by doing,
this is a good place to start. DirectX Graphics Visual Basic Samples. A guide
to the sample applications in the SDK to point you to the sample code you need.
Direct3D Visual Basic Reference. Detailed information on the Direct3D® API
elements in the DirectX for Visual Basic type library. Direct3DX Visual Basic
Reference. Detailed information on the Direct3DX API elements in the DirectX
for Visual Basic type library. Direct3DX Shader Assemblers Reference. Detailed
reference information on the Direct3DX vertex and pixel shader assemblers.
Effect File Format. Information on the format of effect files, which consist of
a set of parameter declarations, followed by descriptions of various techniques
X File Visual Basic Reference. Detailed information on the DirectX (.x) API
elements in the DirectX for Visual Basic type library. X File Format Reference.
Detailed information on the .x file format. What's New in DirectX Graphics
Microsoft® DirectX® 8.0 maintains backward compatibility by exposing and
supporting objects and interfaces offered by previous releases of DirectX.
However, many new features and performance enhancements have been added as part
of the DirectX 8.0 new Microsoft Direct3D® API interfaces. Complete integration
of DirectDraw and Direct3D Simplifies application initialization and improves
data allocation and management performance, which reduces the memory footprint.
Also, the integration of the graphics APIs enable parallel vertex input streams
for more flexible rendering. Programmable vertex processing language Enables
you to write custom shaders for morphing and tweening animation, matrix palette
skinning, user-defined lighting models, general environment mapping, procedural
geometry, or any other developer-defined algorithm. Programmable pixel
processing language Enables you to write custom hardware shaders for general
texture combining expressions, per-pixel lighting (bump mapping), per-pixel
environment mapping for photoreal specular effects, or any other
developer-defined algorithm. Multisampling rendering support Enables full-scene
anti-aliasing and multisampling effects, such as motion blur and
depth-of-field. Point sprites Enables high-performance rendering of particle
systems for sparks, explosions, rain, snow, and so on. 3-D volumetric textures
Enables range-attenuation in per-pixel lighting and volumetric atmospheric
effects, and can be applied to more intricate geometry. Higher-order primitive
support Enhances the appearance of 3-D content and facilitates the mapping of
content from major 3-D authoring tools. Higher-level technologies Includes 3-D
content creation tool plug-ins for export to Direct3D of skinned meshes using a
variety of Direct3D techniques, multiresolution level-of-detail (LOD) geometry,
and higher-order surface data. Indexed vertex blending Extends geometry
blending support to allow the matrices used for vertex blending to be referred
to using a matrix index. Expansion of the Direct3DX Utility Library Contains a
wealth of new functionality. The Direct3DX utility library is a helper layer
that sits on top of Direct3D to simplify common tasks encountered by 3-D
graphics developers. Includes a skinning library, support for working with
meshes, and functions to assemble vertex and pixel shaders. Note that the
functionality supplied by D3D_OVERLOADS, first introduced with Microsoft
DirectX? 5.0, has been moved to the Direct3DX utility library. Introduction to
DirectX Graphics This section introduces the Microsoft® DirectX® Graphics APIs,
providing a high- level overview of technology and services. * The Power of
DirectX Graphics * Getting Started with DirectX Graphics The Power of DirectX
Graphics Microsoft® Direct3D® is designed to enable world-class game and
interactive three- dimensional (3-D) graphics on a computer running Microsoft
Windows®. It is a drawing interface that provides device-dependent access to
3-D video-display hardware in a device-independent manner. Direct3D is a
low-level 3-D API that is ideal for developers who need to port games and other
high-performance multimedia applications to the Windows operating system.
Direct3D provides a device-independent way for applications to communicate with
accelerator hardware at a low level. Direct3D is a software interface that
provides direct access to display devices while maintaining compatibility with
the Windows graphics device interface (GDI), providing a device-independent way
for games and Windows subsystem software, such as three-dimensional (3-D)
graphics packages, to gain access to the features of specific display devices.
Direct3D provides excellent game graphics on computers running Windows 95 or
later, or Windows 2000. Some of the advanced features of Direct3D are: *
Switchable depth buffering (using z-buffers or w-buffers). * Flat and Gouraud
shading. * Multiple light sources and types. * Full material and texture
support, including mipmapping. * Robust software emulation drivers. *
Transformation and clipping. * Hardware independence. * Full support on Windows
95, Windows 98, Windows ME, and Windows 2000. * Support for the Intel MMX
architecture, Intel Streaming Single-Instruction, Multiple-Data (SIMD)
Extensions (SSE)®, and AMD's® 3DNow® architecture. * Support for a Hardware
Abstraction Layer (HAL). This provides a consistent interface through which to
work directly with the display hardware, getting maximum performance. * Support
for page flipping with multiple back buffers in full-screen applications. For
more information, see Page Flipping and Back Buffering. * Support for clipping
in windowed or full-screen applications. * Support for 3-D z-buffers. * Access
to image-stretching hardware. * Simultaneous access to standard and enhanced
display-device memory areas. * Other features, including exclusive hardware
access and resolution switching. These features combine to enable you to write
applications that easily outperform standard Windows GDI-based applications and
even MS-DOS applications. The world management of Direct3D is based on
vertices, polygons, and commands that control them. It enables immediate access
to the transformation, lighting, and rasterization 3-D graphics pipeline. If
hardware isn't present to accelerate rendering, Direct3D offers robust software
emulation. Direct3D provides simple and straightforward methods to set up and
render a 3-D scene. The key set of rendering methods is referred to as
DrawPrimitive methods. They enable applications to render one or more objects
in a scene with a single method call. For more information about these methods,
see Rendering Primitives. Direct3D enables a low-overhead connection to 3-D
hardware. This comes at a price, however. You must provide explicit calls for
transformations and lighting, you must provide all the necessary matrices, and
you must determine what kind of hardware is present and its capabilities.
Getting Started with DirectX Graphics This section provides an overview of
graphics programming with Microsoft® Direct3D®. Each concept discussed here
begins with a nontechnical overview, followed by specific information about how
Direct3D supports it. You don't need to be a graphics guru to benefit from this
overview. In fact, if you are one, you might want to skip this section entirely
and move on to the more detailed information in the Using DirectX Graphics
section. When you finish reading these topics, you will have a solid
understanding of basic Direct3D graphics programming concepts. The following
topics are discussed. * 3-D Coordinate Systems and Geometry * Shading
Techniques * Matrices and Transformations * Vectors, Vertices, and Quaternions
* Copying Surfaces * Page Flipping and Back Buffering * Rectangles 3-D
Coordinate Systems and Geometry Programming Microsoft® Direct3D® applications
requires a working familiarity with 3-D geometric principles. This section
introduces the most important geometric concepts for creating 3-D scenes. The
following topics are covered. * 3-D Coordinate Systems * 3-D Primitives *
Triangle Rasterization Rules These topics provide you with a high-level
understanding of the basic concepts employed by a Direct3D application. For
more information about these topics, see Further Information. 3-D Coordinate
Systems Typically 3-D graphics applications use two types of Cartesian
coordinate systems: left-handed and right-handed. In both coordinate systems,
the positive x-axis points to the right, and the positive y-axis points up. You
can remember which direction the positive z-axis points by pointing the fingers
of either your left or right hand in the positive x-direction and curling them
into the positive y-direction. The direction your thumb points, either toward
or away from you, is the direction that the positive z-axis points for that
coordinate system. The following illustration shows these two coordinate
systems. [C++] Microsoft® Direct3D® uses a left-handed coordinate system. If
you are porting an application that is based on a right-handed coordinate
system, you must make two changes to the data passed to Direct3D. * Flip the
order of triangle vertices so that the system traverses them clockwise from the
front. In other words, if the vertices are v0, v1, v2, pass them to Direct3D as
v0, v2, v1. * Use the view matrix to scale world space by –1 in the
z-direction. To do this, flip the sign of the _31, _32, _33, and _34 member of
the D3DMATRIX structure that you use for your view matrix. To obtain what
amounts to a right-handed world, use the D3DXMatrixPerspectiveRH and
D3DXMatrixOrthoRH functions to define the projection transform. However, be
careful to use the corresponding D3DXMatrixLookAtRH function, reverse the
backface-culling order, and lay out the cube maps accordingly. [Visual Basic]
Microsoft® Direct3D® uses a left-handed coordinate system. If you are porting
an application that is based on a right-handed coordinate system, you must make
two changes to the data passed to Direct3D. * Flip the order of triangle
vertices so that the system traverses them clockwise from the front. In other
words, if the vertices are v0, v1, v2, pass them to Direct3D as v0, v2, v1. *
Use the view matrix to scale world space by –1 in the z-direction. To do this,
flip the sign of the _31, _32, _33, and _34 member of the D3DMATRIX type that
you use for your view matrix. To obtain what amounts to a right-handed world,
use the D3DXMatrixPerspectiveRH and D3DXMatrixOrthoRH functions to define the
projection transform. However, be careful to use the corresponding
D3DXMatrixLookAtRH function, reverse the backface-culling order, and lay out
the cube maps accordingly. Although left-handed and right-handed coordinates
are the most common systems, there is a variety of other coordinate systems
used in 3-D software. For example, it is not unusual for 3-D modeling
applications to use a coordinate system in which the y- axis points toward or
away from the viewer, and the z-axis points up. In this case, right-handedness
is defined as any positive axis (x, y, or z) pointing toward the viewer.
Left-handedness is defined as any positive axis (x, y, or z) pointing away from
the viewer. If you are porting a left-handed modeling application where the z-
axis points up, you must do a rotation on all the vertex data in addition to
the previous steps. The essential operations performed on objects defined in a
3-D coordinate system are translation, rotation, and scaling. You can combine
these basic transformations to create a transform matrix. For details, see 3-D
Transformations. When you combine these operations, the results are not
commutative—the order in which you multiply matrices is important. 3-D
Primitives A 3-D primitive is a collection of vertices that form a single 3-D
entity. The simplest primitive is a collection of points in a 3-D coordinate
system, which is called a point list. Often, 3-D primitives are polygons. A
polygon is a closed 3-D figure delineated by at least three vertices. The
simplest polygon is a triangle. Microsoft® Direct3D® uses triangles to compose
most of its polygons because all three vertices in a triangle are guaranteed to
be coplanar. Rendering nonplanar vertices is inefficient. You can combine
triangles to form large, complex polygons and meshes. The following
illustration shows a cube. Two triangles form each face of the cube. The entire
set of triangles forms one cubic primitive. You can apply textures and
materials to the surfaces of primitives to make them appear to be a single
solid form. For details, see Materials and Textures. You can also use triangles
to create primitives whose surfaces appear to be smooth curves. The following
illustration shows how a sphere can be simulated with triangles. After a
material is applied, the sphere looks curved when it is rendered. This is
especially true if you use Gouraud shading. For details, see Gouraud Shading.
Triangle Rasterization Rules Often, the points specified for vertices do not
precisely match the pixels on the screen. When this happens, Microsoft®
Direct3D® applies triangle rasterization rules to decide which pixels apply to
a given triangle. Direct3D uses a top-left filling convention for filling
geometry. This is the same convention that is used for rectangles in GDI and
OpenGL. In Direct3D, the center of the pixel is the decisive point. If the
center is inside a triangle, the pixel is part of the triangle. Pixel centers
are at integer coordinates. This description of triangle-rasterization rules
used by Direct3D does not necessarily apply to all available hardware. Your
testing may uncover minor variations in the implementation of these rules. The
following illustration shows a rectangle whose upper-left corner is at (0, 0)
and whose lower-right corner is at (5, 5). This rectangle fills 25 pixels, just
as you would expect. The width of the rectangle is defined as right minus left.
The height is defined as bottom minus top. In the top-left filling convention,
top refers to the vertical location of horizontal spans, and left refers to the
horizontal location of pixels within a span. An edge cannot be a top edge
unless it is horizontal—in general, most triangles have only left and right
edges. The top-left filling convention determines the action taken by Direct3D
when a triangle passes through the center of a pixel. The following
illustration shows two triangles, one at (0, 0), (5, 0), and (5, 5), and the
other at (0, 5), (0, 0), and (5, 5). The first triangle in this case gets 15
pixels (shown in black), whereas the second gets only 10 pixels (shown in gray)
because the shared edge is the left edge of the first triangle. If you define a
rectangle with its upper-left corner at (0.5, 0.5) and its lower-right corner
at (2.5, 4.5), the center point of this rectangle is at (1.5, 2.5). When the
Direct3D rasterizer tessellates this rectangle, the center of each pixel is
unambiguously inside each of the four triangles, and the top-left filling
convention is not needed. The following illustration shows this. The pixels in
the rectangle are labeled according to the triangle in which Direct3D includes
them. If you move the rectangle in the previous example so that its upper-left
corner is at (1.0, 1.0), its lower-right corner at (3.0, 5.0), and its center
point at (2.0, 3.0), Direct3D applies the top-left filling convention. Most
pixels in this rectangle straddle the border between two or more triangles, as
the next illustration shows. For both rectangles, the same pixels are affected.
Shading Techniques This section describes techniques used in Microsoft®
Direct3D® to control the shading of 3-D polygons. * Shading Modes * Comparing
Shading Modes * Setting the Shading Mode * Face and Vertex Normal Vectors *
Triangle Interpolants Shading Modes The shading mode used to render a polygon
has a profound effect on its appearance. Shading modes determine the intensity
of color and lighting at any point on a polygon face. Microsoft® Direct3D®
supports two shading modes: * Flat Shading * Gouraud Shading Flat Shading In
the flat shading mode, the Direct3D rendering pipeline renders a polygon, using
the color of the polygon material at its first vertex as the color for the
entire polygon. 3-D objects that are rendered with flat shading have visibly
sharp edges between polygons if they are not coplanar. The following figure
shows a teapot rendered with flat shading. The outline of each polygon is
clearly visible. Flat shading is computationally the least expensive form of
shading. Gouraud Shading When Microsoft® Direct3D® renders a polygon using
Gouraud shading, it computes a color for each vertex by using the vertex normal
and lighting parameters. Then, it interpolates the color across the face of the
polygons The interpolation is done linearly. For example, if the red component
of the color of vertex 1 is 0.8 and the red component of vertex 2 is 0.4, using
the Gouraud shading mode and the RGB color model, the Direct3D lighting module
assigns a red component of 0.6 to the pixel at the midpoint of the line between
these vertices. The following figure demonstrates Gouraud shading. This teapot
is composed of many flat, triangular polygons. However, Gouraud shading makes
the surface of the object appear curved and smooth. Gouraud shading can also be
used to display objects with sharp edges. For more information, see Face and
Vertex Normal Vectors. Comparing Shading Modes In flat shading mode, the
pyramid below is displayed with a sharp edge between adjoining faces. In
Gouraud shading mode, however, shading values are interpolated across the edge,
and the final appearance is of a curved surface. Gouraud shading lights flat
surfaces more realistically than flat shading. A face in the flat shading mode
is a uniform color, but Gouraud shading enables light to fall across a face
more correctly. This effect is particularly obvious if there is a nearby point
source. Gouraud shading smoothes the sharp edges between polygons that are
visible with flat shading. However, it can result in Mach bands, which are
bands of color or light that are not smoothly blended across adjacent polygons.
Your application can reduce the appearance of Mach bands by increasing the
number of polygons in an object, increasing screen resolution, or increasing
the color depth of the application. Gouraud shading can miss some details. One
example is the case shown by the following illustration, in which a spotlight
is completely contained within a polygon face. In this case, Gouraud shading,
which interpolates between vertices, would miss the spotlight altogether; the
face would be rendered as though the spotlight did not exist. Setting the
Shading Mode [C++] Microsoft® Direct3D® enables one shading mode to be selected
at a time. By default, Gouraud shading is selected. In C++, you can change the
shading mode by calling the IDirect3DDevice8::SetRenderState method. Set the
State parameter to D3DRS_SHADEMODE. The State parameter must be set to a member
of the D3DSHADEMODE enumeration. The following sample code examples illustrate
how the current shading mode of a Direct3D application can be set to flat or
Gouraud shading mode. // Set to flat shading. // This code example assumes that
pDev is a valid pointer to // an IDirect3DDevice8 interface. hr =
pDev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); if(FAILED(hr)) { // Code
to handle the error goes here. } // Set to Gouraud shading. This is the default
for Direct3D. hr = pDev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
if(FAILED(hr)) { // Code to handle the error goes here. } [Visual Basic]
Microsoft® Direct3D® enables one shading mode to be selected at a time. By
default, Gouraud shading is selected. In Microsoft Visual Basic®, you can
change the shading mode by calling the Direct3DDevice8.SetRenderState method.
Set the State parameter to D3DRS_SHADEMODE. The State parameter must be set to
a member of the CONST_D3DSHADEMODE enumeration. The following code example
illustrates how the current shading mode of a Direct3D application can be set
to flat or Gouraud shading mode. ' Set to flat shading. ' This code example
assumes that d3dDev is a valid reference to ' a Direct3DDevice8 object. On
Local Error Resume Next Call d3dDev.SetRenderState(D3DRS_SHADEMODE, _
D3DSHADE_FLAT) ' Check for an error. If Err.Number <> D3D_OK Then ' Handle the
error. End If ' Set to Gouraud shading. this is the default for Direct3D. Call
d3dDev.SetRenderState(D3DRS_SHADEMODE, _ D3DSHADE_GOURAUD) If Err.Number <>
D3D_OK Then ' Handle the error. End If Face and Vertex Normal Vectors Each face
in a mesh has a perpendicular normal vector. The vector's direction is
determined by the order in which the vertices are defined and by whether the
coordinate system is right- or left-handed. The face normal points away from
the front side of the face. In Microsoft® Direct3D®, only the front of a face
is visible. A front face is one in which vertices are defined in clockwise
order. Any face that is not a front face is a back face. Direct3D does not
always render back faces; therefore, back faces are said to be culled. You can
change the culling mode to render back faces if you want. See Culling State for
more information. Direct3D applications do not need to specify face normals;
the system calculates them automatically when they are needed. The system uses
face normals in the flat shading mode. In the Gouraud shading mode, Direct3D
uses the vertex normal. It also uses the vertex normal for controlling lighting
and texturing effects. When applying Gouraud shading to a polygon, Direct3D
uses the vertex normals to calculate the angle between the light source and the
surface. It calculates the color and intensity values for the vertices and
interpolates them for every point across all the primitive's surfaces. Direct3D
calculates the light intensity value by using the angle. The greater the angle,
the less light is shining on the surface. If you are creating an object that is
flat, set the vertex normals to point perpendicular to the surface, as shown in
the following illustration. A flat surface composed of two triangles is
defined. It is more likely, however, that your object is made up of triangle
strips and the triangles are not coplanar. One simple way to achieve smooth
shading across all the triangles in the strip is to first calculate the surface
normal vector for each polygonal face with which the vertex is associated. The
vertex normal can be set to make an equal angle with each surface normal.
However, this method might not be efficient enough for complex primitives. This
method is illustrated by the following figure, which shows two surfaces, S1 and
S2 seen edge-on from above. The normal vectors for S1 and S2 are shown in blue.
The vertex normal vector is shown in red. The angle that the vertex normal
vector makes with the surface normal of S1 is the same as the angle between the
vertex normal and the surface normal of S2. When these two surfaces are lit and
shaded with Gouraud shading, the result is a smoothly shaded, smoothly rounded
edge between them. If the vertex normal leans toward one of the faces with
which it is associated, it causes the light intensity to increase or decrease
for points on that surface, depending on the angle it makes with the light
source. An example is shown in the following figure. Again, these surfaces are
seen edge-on. The vertex normal leans toward S1, causing it to have a smaller
angle with the light source than if the vertex normal had equal angles with the
surface normals. You can use Gouraud shading to display some objects in a 3-D
scene with sharp edges. To do so, duplicate the vertex normal vectors at any
intersection of faces where a sharp edge is required, as shown in the following
illustration. If you use the DrawPrimitive methods to render your scene, define
the object with sharp edges as a triangle list, rather than a triangle strip.
When you define an object as a triangle strip, Direct3D treats it as a single
polygon composed of multiple triangular faces. Gouraud shading is applied both
across each face of the polygon and between adjacent faces. The result is an
object that is smoothly shaded from face to face. Because a triangle list is a
polygon composed of a series of disjoint triangular faces, Direct3D applies
Gouraud shading across each face of the polygon. However, it is not applied
from face to face. If two or more triangles of a triangle list are adjacent,
they appear to have a sharp edge between them. Another alternative is to change
to flat shading when rendering objects with sharp edges. This is
computationally the most efficient method, but it may result in objects in the
scene that are not rendered as realistically as the objects that are Gouraud-
shaded. Triangle Interpolants The system interpolates the characteristics of a
triangle's vertices across the triangle when it renders a face. These are the
triangle interpolants: * Color * Specular * Alpha All the triangle interpolants
are modified by the current shading mode, as shown in the following table.
Shading mode Description Flat No interpolation is done. Instead, the color of
the first vertex in the triangle is applied across the entire face. Gouraud
Linear interpolation is performed between all three vertices. The color and
specular interpolants are treated differently, depending on the color model. In
the RGB color model, the system uses the red, green, and blue color components
in the interpolation. In the monochromatic or ramp model, the system uses only
the blue component of the vertex color. The alpha component of a color is
treated as a separate interpolant because device drivers can implement
transparency in two different ways: by using texture blending or by using
stippling. [C++] Use the ShadeCaps member of the D3DCAPS8 structure to
determine what forms of interpolation the current device driver supports.
[Visual Basic] Use the ShadeCaps member of the D3DCAPS8 type to determine what
forms of interpolation the current device driver supports. Matrices and
Transformations Use matrices in Microsoft® Direct3D® to define world, view, and
projection transformations. If you haven't programmed for 3-D graphics before,
this section will help you familiarize yourself with the key concepts you need
to understand in order to get started. If you have prior experience in 3-D
programming, skip this section, or skim the following topics. * Matrices * 3-D
Transformations Matrices [C++] Matrices in Microsoft® Direct3D® are represented
by a 4´4 homogeneous matrix, defined by the D3DMATRIX structure. [Visual Basic]
Matrices in Microsoft® Direct3D® are represented by a 4?4 homogeneous matrix,
defined by the D3DMATRIX type. [C++] The Direct3DX utility library
implementation of the D3DMATRIX structure (D3DXMATRIX) implements a parentheses
("()") operator. This operator offers convenient access to values in the matrix
for C++ programmers. Instead of having to refer to the structure members by
name, you can refer to them by row and column number and index the numbers as
needed. These indices are zero-based, so, for example, the element in the third
row, second column would be M(2, 1). You need a basic knowledge of matrices to
work with Direct3D. For more information, see 3-D Transformations. 3-D
Transformations Microsoft® Direct3D® uses matrices to perform 3-D
transformations. This section explains how matrices create 3-D transformations,
describes some common uses for transformations, and details how you can combine
matrices to produce a single matrix that encompasses multiple transformations.
Information is divided into the following topics. * About 3-D Transformations *
Translation * Rotation * Scaling * Matrix Concatenation For more information
about transformations in Direct3D, see the Direct3D Rendering Pipeline. About
3-D Transformations In applications that work with 3-D graphics, you can use
geometrical transformations to do the following: * Express the location of an
object relative to another object. * Rotate and size objects. * Change viewing
positions, directions, and perspectives. You can transform any point into
another point by using a 4?4 matrix. In the following example, a matrix is
reinterprets the point (x, y, z), producing the new point (x', y', z'). Perform
the following operations on (x, y, z) and the matrix to produce the point (x',
y', z'). The most common transformations are translation, rotation, and
scaling. You can combine the matrices that produce these effects into a single
matrix to calculate several transformations at once. For example, you can build
a single matrix to translate and rotate a series of points. For more
information, see Matrix Concatenation. Matrices are written in row-column
order. A matrix that evenly scales vertices along each axis, known as uniform
scaling, is represented by the following matrix using mathematical notation.
[C++] In C++, Microsoft® Direct3D® declares matrices as a two-dimensional
array, using the D3DMATRIX structure. The following example shows how to
initialize a D3DMATRIX structure to act as a uniform scaling matrix. // In this
example, s is a variable of type float. D3DMATRIX scale = { s, 0.0f, 0.0f,
0.0f, 0.0f, s, 0.0f, 0.0f, 0.0f, 0.0f, s, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f };
[Visual Basic] In Microsoft® Visual Basic®, Microsoft Direct3D® uses matrices
declared as a two- dimensional array, using the D3DMATRIX type. The following
example shows how to initialize a variable of type D3DMATRIX to act as a
uniform scaling matrix. ' In this example, s is a variable of type Single. Dim
ScaleMatrix As D3DMATRIX With ScaleMatrix .m11 = s .m22 = s .m33 = s .m44 = 1
End With Translation The following transformation translates the point (x, y,
z) to a new point (x', y', z'). [C++] You can create a translation matrix by
hand in C++. The following example shows the source code for a function that
creates a matrix to translate vertices. D3DXMATRIX Translate(const float dx,
const float dy, const float dz) { D3DXMATRIX ret; D3DXMatrixIdentity(&ret); //
Implemented by Direct3DX ret(3, 0) = dx; ret(3, 1) = dy; ret(3, 2) = dz; return
ret; } // End of Translate For convenience, the Direct3DX utility library
supplies the D3DXMatrixTranslation function. [Visual Basic] You can create a
translation matrix by hand in Microsoft® Visual Basic®. The following example
shows the source code for a function that creates a matrix to translate
vertices. Sub TranslateMatrix(m As D3DMATRIX, v As D3DVECTOR)
D3DXMatrixIdentity m ' Implemented by Direct3DX. m.m41 = v.x m.m42 = v.y m.m43
= v.z End Sub For convenience, the Direct3DX utility library supplies the
D3DXMatrixTranslation function. Rotation The transformations described here are
for left-handed coordinate systems, and so may be different from transformation
matrices that you have seen elsewhere. For more information, see 3-D Coordinate
Systems. The following transformation rotates the point (x, y, z) around the
x-axis, producing a new point (x', y', z'). The following transformation
rotates the point around the y-axis. The following transformation rotates the
point around the z-axis. In these example matrices, the Greek letter theta (?)
stands for the angle of rotation, in radians. Angles are measured clockwise
when looking along the rotation axis toward the origin. [C++] In a C++
application, use the D3DXMatrixRotationX, D3DXMatrixRotationY, and
D3DXMatrixRotationZ functions supplied by the Direct3DX utility library to
create rotation matrices. The following is the code for the D3DXMatrixRotationX
function. D3DXMATRIX* WINAPI D3DXMatrixRotationX ( D3DXMATRIX *pOut, float
angle ) { #if DBG if(!pOut) return NULL; #endif float sin, cos; sincosf(angle,
&sin, &cos); // Determine sin and cos of angle. pOut->_11 = 1.0f; pOut->_12 =
0.0f; pOut->_13 = 0.0f; pOut->_14 = 0.0f; pOut->_21 = 0.0f; pOut->_22 = cos;
pOut->_23 = sin; pOut->_24 = 0.0f; pOut->_31 = 0.0f; pOut->_32 = -sin;
pOut->_33 = cos; pOut->_34 = 0.0f; pOut->_41 = 0.0f; pOut->_42 = 0.0f;
pOut->_43 = 0.0f; pOut->_44 = 1.0f; return pOut; } [Visual Basic] In a
Microsoft® Visual Basic® application, use the D3DXMatrixRotationX,
D3DXMatrixRotationY, and D3DXMatrixRotationZ functions supplied by the
Direct3DX utility library to create rotation matrices. If you manually create a
matrix for rotation about an axis—in this case, the x-axis— the source code
looks something like the following: Sub CreateXRotation(ret As D3DMATRIX, rads
As Single) Dim cosine As Single Dim sine As Single cosine = Cos(rads) sine =
Sin(rads) D3DXMatrixIdentity ret ' Implemented by Direct3DX. ret.m22 = cosine
ret.m23 = sine ret.m32 = -sine ret.m33 = cosine End Sub Scaling The following
transformation scales the point (x, y, z) by arbitrary values in the x-, y- ,
and z-directions to a new point (x', y', z'). Matrix Concatenation One
advantage of using matrices is that you can combine the effects of two or more
matrices by multiplying them. This means that, to rotate a model and then
translate it to some location, you don't need to apply two matrices. Instead,
you multiply the rotation and translation matrices to produce a composite
matrix that contains all their effects. This process, called matrix
concatenation, can be written with the following formula. In this formula, C is
the composite matrix being created, and M1 through Mn are the individual
transformations that matrix C contains. In most cases, only two or three
matrices are concatenated, but there is no limit. [C++] Use the
D3DXMatrixMultiply function to perform matrix multiplication. [Visual Basic]
Use the D3DXMatrixMultiply function to perform matrix multiplication. The order
in which the matrix multiplication is performed is crucial. The preceding
formula reflects the left-to-right rule of matrix concatenation. That is, the
visible effects of the matrices that you use to create a composite matrix occur
in left-to-right order. A typical world transformation matrix is shown the
following example. Imagine that you are creating the world transformation
matrix for a stereotypical flying saucer. You would probably want to spin the
flying saucer around its center— the y-axis of model space—and translate it to
some other location in your scene. To accomplish this effect, you first create
a rotation matrix, and then multiply it by a translation matrix, as shown in
the following formula. In this formula, Ry is a matrix for rotation about the
y-axis, and Tw is a translation to some position in world coordinates. The
order in which you multiply the matrices is important because, unlike
multiplying two scalar values, matrix multiplication is not commutative.
Multiplying the matrices in the opposite order has the visual effect of
translating the flying saucer to its world space position, and then rotating it
around the world origin. No matter what type of matrix you are creating,
remember the left-to-right rule to ensure that you achieve the expected
effects. Vectors, Vertices, and Quaternions Throughout Microsoft® Direct3D®,
vertices describe position and orientation. Each vertex in a primitive is
described by a vector that gives its position, color, texture coordinates, and
a normal vector that gives its orientation. Quaternions add a fourth element to
the [x, y, z] values that define a three- component-vector. Quaternions are an
alternative to the matrix methods that are typically used for 3-D rotations. A
quaternion represents an axis in 3-D space and a rotation around that axis. For
example, a quaternion might represent a (1,1,2) axis and a rotation of 1
radian. Quaternions carry valuable information, but their true power comes from
the two operations that you can perform on them: composition and interpolation.
Performing composition on quaternions is similar to combining them. The
composition of two quaternions is notated as follows: The composition of two
quaternions applied to a geometry means "rotate the geometry around axis2 by
rotation2, then rotate it around axis1 by rotation1." In this case, Q
represents a rotation around a single axis that is the result of applying q2,
then q1 to the geometry. Using quaternion interpolation, an application can
calculate a smooth and reasonable path from one axis and orientation to
another. Therefore, interpolation between q1 and q2 provides a simple way to
animate from one orientation to another. When you use composition and
interpolation together, they provide you with a simple way to manipulate a
geometry in a manner that appears complex. For example, imagine that you have a
geometry that you want to rotate to a given orientation. You know that you want
to rotate it r2 degrees around axis2, then rotate it r1 degrees around axis1,
but you don't know the final quaternion. By using composition, you could
combine the two rotations on the geometry to get a single quaternion that is
the result. Then, you could interpolate from the original to the composed
quaternion to achieve a smooth transition from one to the other. [C++] The
Direct3DX utility library includes functions that help you work with
quaternions. For example, the D3DXQuaternionRotationAxis function adds a
rotation value to a vector that defines an axis of rotation, and returns the
result in a quaternion defined by a D3DXQUATERNION structure. Additionally, the
D3DXQuaternionMultiply function composes quaternions and the
D3DXQuaternionSlerp performs spherical linear interpolation between two
quaternions. Direct3D applications can use the following functions to simplify
the task of working with quaternions. * D3DXQuaternionBaryCentric *
D3DXQuaternionConjugate * D3DXQuaternionDot * D3DXQuaternionExp *
D3DXQuaternionIdentity * D3DXQuaternionInverse * D3DXQuaternionIsIdentity *
D3DXQuaternionLength * D3DXQuaternionLengthSq * D3DXQuaternionLn *
D3DXQuaternionMultiply * D3DXQuaternionNormalize * D3DXQuaternionRotationAxis *
D3DXQuaternionRotationMatrix * D3DXQuaternionRotationYawPitchRoll *
D3DXQuaternionSlerp * D3DXQuaternionSquad * D3DXQuaternionToAxisAngle Direct3D
applications can use the following functions to simplify the task of working
with three-component-vectors. * D3DXVec3Add * D3DXVec3BaryCentric *
D3DXVec3CatmullRom * D3DXVec3Cross * D3DXVec3Dot * D3DXVec3Hermite *
D3DXVec3Length * D3DXVec3LengthSq * D3DXVec3Lerp * D3DXVec3Maximize *
D3DXVec3Minimize * D3DXVec3Normalize * D3DXVec3Project * D3DXVec3Scale *
D3DXVec3Subtract * D3DXVec3Transform * D3DXVec3TransformCoord *
D3DXVec3TransformNormal * D3DXVec3Unproject Many additional functions that
simplify tasks using two- and four-component-vectors are included among the
math functions supplied by the Direct3DX utility library. [Visual Basic] The
Direct3DX utility library includes functions that help you work with
quaternions. For example, the D3DXQuaternionRotationAxis function adds a
rotation value to a vector that defines an axis of rotation, and returns the
result in a quaternion defined by a D3DQUATERNION type. Additionally, the
D3DXQuaternionMultiply function composes quaternions and the
D3DXQuaternionSlerp performs spherical linear interpolation between two
quaternions. Direct3D applications can use the following functions to simplify
the task of working with quaternions. * D3DXQuaternionBaryCentric *
D3DXQuaternionConjugate * D3DXQuaternionExp * D3DXQuaternionIdentity *
D3DXQuaternionInverse * D3DXQuaternionIsIdentity * D3DXQuaternionLength *
D3DXQuaternionLengthSq * D3DXQuaternionLn * D3DXQuaternionMultiply *
D3DXQuaternionNormalize * D3DXQuaternionRotationAxis *
D3DXQuaternionRotationMatrix * D3DXQuaternionRotationYawPitchRoll *
D3DXQuaternionSlerp * D3DXQuaternionSquad * D3DXQuaternionToAxisAngle Direct3D
applications can use the following functions to simplify the task of working
with three-component-vectors. * D3DXVec3Add * D3DXVec3BaryCentric *
D3DXVec3CatmullRom * D3DXVec3Cross * D3DXVec3Dot * D3DXVec3Hermite *
D3DXVec3Length * D3DXVec3LengthSq * D3DXVec3Lerp * D3DXVec3Maximize *
D3DXVec3Minimize * D3DXVec3Normalize * D3DXVec3Project * D3DXVec3Scale *
D3DXVec3Subtract * D3DXVec3Transform * D3DXVec3TransformCoord *
D3DXVec3TransformNormal * D3DXVec3Unproject Many additional functions that
simplify tasks using two- and four-component-vectors are included with the math
functions supplied by the Direct3DX utility library. Copying Surfaces [C++] The
term blit is shorthand for "bit block transfer," which is the process of
transferring blocks of data from one place in memory to another. The blitting
device driver interface (DDI) continues to be used in Microsoft® DirectX® 8.0
as the primary mechanism for moving large rectangles of pixels on a per-frame
basis, the mechanism behind the copy-oriented IDirect3DDevice8::Present method.
The transportation of artwork in the blit operation is performed by the
IDirect3DDevice8::UpdateTexture method. Artwork can also be copied in DirectX
8.0 by using the IDirect3DDevice8::CopyRects method, which copies a rectangular
subset of pixels. Note DirectX 8.0 provides D3DX functions that enable you to
load artwork from files, apply color conversion, and resize artwork. For more
information on the available functions see Texturing Functions. [Visual Basic]
The term blit is shorthand for "bit block transfer," which is the process of
transferring blocks of data from one place in memory to another. The blitting
device driver interface (DDI) continues to be used in Microsoft® DirectX® 8.0
as the primary mechanism for moving large rectangles of pixels on a per-frame
basis, the mechanism behind the copy-oriented Direct3DDevice8.Present method.
The transportation of artwork in the blit operation is performed by the
Direct3DDevice8.UpdateTexture method. Artwork can also be copied in DirectX 8.0
by using the Direct3DDevice8.CopyRects method, which copies a rectangular
subset of pixels. Note DirectX 8.0 provides D3DX functions that enable you to
load artwork from files, apply color conversion, and resize artwork. For more
information on the available functions see the D3DX8.class and look under
methods for textures. Page Flipping and Back Buffering Page flipping is key in
multimedia, animation, and game software. Software page flipping is analogous
to the way you can do animation with a pad of paper. On each page the artist
changes the figure slightly, so that when you flip rapidly between sheets, the
drawing appears animated. Page flipping in software is very similar to this
process. Microsoft® Direct3D® implements page flipping functionality through a
swap chain which is a property of the device. Initially, you set up a series of
Direct3D buffers that are designed to flip to the screen the way the artist's
paper flips to the next page. The first buffer is referred to as the color
front buffer and the buffers behind it are called back buffers. Your
application writes to a back buffer, and then flips the color front buffer so
that the back buffer appears on screen. While the system displays the image,
your software is again writing to a back buffer. The process continues as long
as you are animating, enabling you to animate images quickly and efficiently.
Direct3D makes it easy to set up page flipping schemes, from a relatively
simple double-buffered scheme—a color front buffer with one back buffer—to more
sophisticated schemes that add additional back buffers. Rectangles Throughout
Microsoft® Direct3D® and Microsoft Windows® programming, objects on the screen
are referred to in terms of bounding rectangles. The sides of a bounding
rectangle are always parallel to the sides of the screen, so the rectangle can
be described by two points, the top-left corner and bottom-right corner. Most
applications use the RECT structure to carry information about a bounding
rectangle to use when blitting to the screen or performing hit detection. [C++]
In C++, the RECT structure has the following definition. typedef struct tagRECT
{ LONG left; // This is the top-left corner x-coordinate. LONG top; // The
top-left corner y-coordinate. LONG right; // The bottom-right corner
x-coordinate. LONG bottom; // The bottom-right corner y-coordinate. } RECT,
*PRECT, NEAR *NPRECT, FAR *LPRECT; [Visual Basic] In Microsoft Visual Basic®,
the RECT type has the following definition. Type RECT Left As Long ' This is
the top-left corner x-coordinate. Top As Long ' The top-left corner
y-coordinate. Right As Long ' The bottom-right corner x-coordinate. Bottom As
Long ' The bottom-right corner y-coordinate. End Type In the preceding example,
the left and top members are the x- and y-coordinates of a bounding rectangle's
top-left corner. Similarly, the right and bottom members make up the
coordinates of the bottom-right corner. The following diagram illustrates how
you can visualize these values. In the interest of efficiency, consistency, and
ease of use, all Direct3D presentation functions work with rectangles.
Understanding DirectX Graphics This section describes the underlying workings
of Microsoft® DirectX® Graphics. * Direct3D Architecture * Direct3D Rendering
Pipeline Direct3D Architecture This section contains general information about
the relationship between the Microsoft® Direct3D® component and the rest of
Microsoft DirectX®, the operating system, and the system hardware. The
following topics are discussed. * Architectural Overview for Direct3D *
Hardware Abstraction Layer * System Integration Architectural Overview for
Direct3D There are two programmable sections of the Microsoft® Direct3D®
architecture: vertex shaders and pixel shaders. Vertex shaders are invoked
prior to vertex assembly and operate on vectors. Pixel shaders are invoked
after any DrawPrimitive calls and operate on pixels. The following simplified
diagram illustrates the Direct3D architecture. It is a subset of the
architecture, as Direct3D supports eight sets of textures and texture
coordinates. As shown in this diagram, vertex buffers stream vertex data into
the vertex shader. The vertex shader performs geometry operations using the
instructions defined by the Direct3DX vertex shader assembler. The data
streamed to the vertex shader does not have to be contained in vertex buffers,
but this is the ideal case. After vertex assembly, the assembled vertex data is
drawn using DrawPrimitive methods. At this point, each pixel of the drawn
primitive is routed to the pixel shader, including its position, color,
texture, and texture coordinate. The pixel shader performs pixel operations
using the instructions defined by the Direct3DX pixel shader assembler. The
inputs to the pixel processing pixel shader stage include texture surfaces and
the associated texture coordinates controlling the sampling of surfaces. The
output pixel is routed to the frame buffer. For more information on the
architecture of the programmable sections of the Direct3D, see Vertex Shader
Architecture and Pixel Shader Architecture. For more information on how vertex
and pixel shaders fit into the rendering pipeline, see the Direct3D Rendering
Pipeline. Vertex Shader Architecture The following diagram illustrates the
vertex shader architecture. The incoming data to the vertex data is taken from
vertex data streams, and the constant data is loaded by the vertex shader
declarator. For details, see the Vertex Shader Assembler Reference. Pixel
Shader Architecture The following diagram illustrates the pixel shader
architecture. The incoming data to the pixel shader is the clip space vertex
(homogeneous coordinates). The diffuse and specular color comes from the values
in the color registers (v0 and v1). The texture coordinates and set textures
come from the values in the texture registers (t0, t1, t2, and t3) from the
texture setup stage and vertex data. For details, see the Pixel Shader
Assembler Reference. Hardware Abstraction Layer Microsoft® Direct3D® provides
device independence through the hardware abstraction layer (HAL). The HAL is a
device-specific interface, provided by the device manufacturer, that Direct3D
uses to work directly with the display hardware. Applications never interact
with the HAL. Rather, with the infrastructure that the HAL provides, Direct3D
exposes a consistent set of interfaces and methods that an application uses to
display graphics. The device manufacturer implements the HAL in a combination
of 16-bit and 32-bit code under Microsoft Windows®. Under Windows NT® and
Windows 2000, the HAL is always implemented in 32-bit code. The HAL can be part
of the display driver or a separate dynamic-link library (DLL) that
communicates with the display driver through a private interface that driver's
creator defines. The Direct3D HAL is implemented by the chip manufacturer,
board producer, or original equipment manufacturer (OEM). The HAL implements
only device- dependent code and performs no emulation. If a function is not
performed by the hardware, the HAL does not report it as a hardware capability.
Additionally, the HAL does not validate parameters; Direct3D does this before
the HAL is invoked. In DirectX 8.0, the HAL can have three different vertex
processing modes: software vertex processing, hardware vertex processing, and
mixed vertex processing on the same device. The pure device mode is a variant
of the HAL device. The pure device type supports hardware vertex processing
only, and allows only a small subset of the device state to be queried by the
application. Additionally, the pure device is available only on adapters that
have a minimum level of capabilities. System Integration The following diagram
shows the relationships between Microsoft® Direct3D®, the graphics device
interface (GDI), the hardware abstraction layer (HAL), and the hardware. As the
preceding diagram shows, Direct3D applications exist alongside GDI applications
and both have access to the graphics hardware through the device driver for the
graphics card. Unlike GDI, Direct3D can take advantage of hardware features
when a HAL device is selected. HAL devices provide hardware acceleration based
on the feature set supported by the graphics card. You are provided with a
Direct3D method to determine at run time if a device is capable of the task.
The software device, although not supporting the entire DirectX 8.0 feature
set, is intended to ensure that applications can always find a working device
on any system. However, in many cases an application running on a software
device must be prepared to run with a downgraded set of functionality. The
capabilities of the software device can be determined in the same fashion as
the capabilities of a hardware device. For more information on devices
supported by Direct3D, see Device Types. Direct3D Rendering Pipeline The
Microsoft® Direct3D® rendering pipeline is a series of processing stages that
specify the behavior of the vertex transform and lighting pipeline, and the
pixel and texture blending pipeline. When you design a 3-D application, you can
define the world in any units you find convenient, from microns to parsecs.
Your application passes a description of that world to Direct3D. This
description includes the sizes and relative positions of all the objects in
your world and the position and orientation of the viewer. Direct3D transforms
these descriptions (vertices) into a series of pixels on the screen. The first
step of this process—the transformation of the geometry that you supply into a
two- dimensional image—is the geometry pipeline, sometimes called the
transformation pipeline. After vertex processing, pixel data is used to perform
multitexturing and fog blending. Then alpha, stencil, and depth tests are
performed. Finally, frame-buffer blending is done by the rasterizer. The
following topics provide a Direct3D-centered approach to the complete rendering
pipeline. The topics introduce key concepts and make parallels from those
concepts to their counterparts in the Direct3D API. The fixed-function
processing section discusses techniques familiar to developers who have used
earlier versions of Microsoft DirectX®, whereas the section on programmable
(procedural) processing explains the new procedural model used for vertex and
pixel processing in Microsoft DirectX 8.0. * Fixed Function Vertex and Pixel
Processing * Programmable Vertex and Pixel Processing * Presenting Vertex Data
to the Vertex Processor Fixed Function Vertex and Pixel Processing The part of
Microsoft® Direct3D® that pushes geometry through the fixed function geometry
pipeline is the transformation engine. It locates the model and viewer in the
world, projects vertices for display on the screen, and clips vertices to the
viewport. The transformation engine also performs lighting computations to
determine diffuse and specular components at each vertex. The geometry pipeline
takes vertices as input. The transformation engine applies three
transformations—the world, view, and projection transformations—to the
vertices, clips the result, and passes everything to the rasterizer. The
following image illustrates the sequence of steps. At the head of the pipeline,
no transformations have been applied, so all of a model's vertices are declared
relative to a local coordinate system—this is a local origin and an
orientation. This orientation of coordinates is often referred to as model
space, and individual coordinates are called model coordinates. The first stage
of the geometry pipeline transforms a model's vertices from their local
coordinate system to a coordinate system that is used by all the objects in a
scene. The process of reorienting the vertices is called the world
transformation. This new orientation is commonly referred to as world space,
and each vertex in world space is declared using world coordinates. In the next
stage, the vertices that describe your 3-D world are oriented with respect to a
camera. That is, your application chooses a point-of-view for the scene, and
world space coordinates are relocated and rotated around the camera's view,
turning world space into camera space. This is the view transformation. The
next stage is the projection transformation. In this part of the pipeline,
objects are usually scaled with relation to their distance from the viewer in
order to give the illusion of depth to a scene; close objects are made to
appear larger than distant objects, and so on. For simplicity, this
documentation refers to the space in which vertices exist after the projection
transformation as projection space. Some graphics books might refer to
projection space as post-perspective homogeneous space. Not all projection
transformations scale the size of objects in a scene. A projection such as this
is sometimes called an affine or orthogonal projection. In the final part of
the pipeline, any vertices that will not be visible on the screen are removed,
so that the rasterizer doesn't take the time to calculate the colors and
shading for something that will never be seen. This process is called clipping.
After clipping, the remaining vertices are scaled according to the viewport
parameters and converted into screen coordinates. The resulting vertices—seen
on the screen when the scene is rasterized—exist in screen space. Information
on the fixed vertex and pixel processing pipeline is organized into the
following topics. * Transformation and Lighting Engine * Viewports and Clipping
* Rasterization Transformation and Lighting Engine The following topics explain
the mechanics behind each component of the fixed function transformation and
lighting engine in detail. * The World Transformation * The View Transformation
* The Projection Transformation * The Lighting Engine * Mathematics of Direct3D
Lighting The World Transformation The discussion of the world transformation
introduces basic concepts and provides details on how to set up a world
transformation matrix in a Microsoft® Direct3D® application. This information
is organized into the following topics. * What Is the World Transformation? *
Setting Up a World Matrix What Is the World Transformation? The world
transformation changes coordinates from model space, where vertices are defined
relative to a model's local origin, to world space, where vertices are defined
relative to an origin common to all the objects in a scene. In essence, the
world transformation places a model into the world; hence its name. The
following diagram illustrates the relationship between the world coordinate
system and a model's local coordinate system. The world transformation can
include any combination of translations, rotations, and scalings. For a
discussion of the mathematics of transformations, see 3-D Transformations.
Setting Up a World Matrix As with any other transformation, you create the
world transformation by concatenating a series of transformation matrices into
a single matrix that contains the sum total of their effects. In the simplest
case, when a model is at the world origin and its local coordinate axes are
oriented the same as world space, the world matrix is the identity matrix. More
commonly, the world matrix is a combination of a translation into world space
and possibly one or more rotations to turn the model as needed. [C++] The
following example, from a fictitious 3-D model class written in C++, uses the
helper functions included in the Direct3DX utility library to create a world
matrix that includes three rotations to orient a model and a translation to
relocate it relative to its position in world space. /* * For the purposes of
this example, the following variables * are assumed to be valid and
initialized. * * The m_xPos, m_yPos, m_zPos variables contain the model's *
location in world coordinates. * * The m_fPitch, m_fYaw, and m_fRoll variables
are floats that * contain the model's orientation in terms of pitch, yaw, and
roll * angles, in radians. */ void C3DModel::MakeWorldMatrix( D3DXMATRIX*
pMatWorld ) { D3DXMATRIX MatTemp; // Temp matrix for rotations. D3DXMATRIX
MatRot; // Final rotation matrix, applied to // pMatWorld. // Using the
left-to-right order of matrix concatenation, // apply the translation to the
object's world position // before applying the rotations.
D3DXMatrixTranslation(pMatWorld, m_xPos, m_yPos, m_zPos);
D3DXMatrixIdentity(&MatRot); // Now, apply the orientation variables to the
world matrix if(m_fPitch || m_fYaw || m_fRoll) { // Produce and combine the
rotation matrices. D3DXMatrixRotationX(&MatTemp, m_fPitch); // Pitch
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp); D3DXMatrixRotationY(&MatTemp,
m_fYaw); // Yaw D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
D3DXMatrixRotationZ(&MatTemp, m_fRoll); // Roll D3DXMatrixMultiply(&MatRot,
&MatRot, &MatTemp); // Apply the rotation matrices to complete the world
matrix. D3DXMatrixMultiply(pMatWorld, &MatRot, pMatWorld); } } After you
prepare the world transformation matrix, call the
IDirect3DDevice8::SetTransform method to set it, specifying the D3DTS_WORLD
macro for the first parameter. For more information, see Setting
Transformations. [Visual Basic] The following example, from a fictitious 3-D
model class written in Microsoft ® Visual Basic® uses the helper functions
included in the Direct3DX utility library to create a world matrix that
includes three rotations to orient a model and a translation to relocate it
relative to its position in world space. ' ' For the purposes of this example,
the following variables ' are assumed to be valid and initialized. ' ' The
m_xPos, m_yPos, m_zPos variables contain the model's ' location in world
coordinates. ' ' The m_sPitch, m_sYaw, and m_sRoll variables are Singles that '
contain the model's orientation in terms of pitch, yaw, and roll ' angles, in
radians. ' Public Function MakeWorldMatrix() As D3DMATRIX Dim matWorld As
D3DMATRIX ' World matrix to return. Dim matTemp As D3DMATRIX ' Temp matrix to
hold rotations. Dim matRot As D3DMATRIX ' Temp rotation matrix. ' Modify
matWorld to create a translation matrix. D3DXMatrixIdentity matWorld
matWorld.m41 = m_xPos matWorld.m42 = m_yPos matWorld.m43 = m_zPos
D3DXMatrixIdentity matRot ' Sets up the rotation matrix. ' ' Using the
left-to-right order of matrix concatenation, ' apply the translation to the
object's world position ' before applying the rotations. ' ' Produce and
combine the rotation matrices. If (m_sPitch <> 0) Or (m_sYaw <> 0) Or (m_sRoll
<> 0) Then ' First, pitch. D3DXMatrixRotationX matTemp, m_sPitch
D3DXMatrixMultiply matRot, matRot, matTemp ' Then, yaw. D3DXMatrixRotationY
matTemp, m_sYaw D3DXMatrixMultiply matRot, matRot, matTemp ' Finally, roll.
D3DXMatrixRotationZ matTemp, m_sRoll D3DXMatrixMultiply matRot, matRot, matTemp
' Apply the rotation matrices to the translation already in ' matWorld to
complete the world matrix. D3DXMatrixMultiply matWorld, matRot, matWorld End If
MakeWorldMatrix = matWorld End Function After you prepare the world
transformation matrix, call the Direct3DDevice8.SetTransform method to set it,
specifying the D3DTS_WORLD flag in the first parameter. For more information,
see Setting Transformations. Note Microsoft® Direct3D® uses the world and view
matrices that you set to configure several internal data structures. Each time
you set a new world or view matrix, the system recalculates the associated
internal structures. Setting these matrices frequently—for example, thousands
of times per frame—is computationally expensive. You can minimize the number of
required calculations by concatenating your world and view matrices into a
world-view matrix that you set as the world matrix, and then setting the view
matrix to the identity. Keep cached copies of individual world and view
matrices so that you can modify, concatenate, and reset the world matrix as
needed. For clarity, in this documentation Direct3D samples rarely employ this
optimization. The View Transformation This section introduces the basic
concepts of the view transformation and provides details on how to set up a
view transformation matrix in a Microsoft® Direct3D® application. This
information is organized into the following topics. * What Is the View
Transformation? * Setting Up a View Matrix What Is the View Transformation? The
view transformation locates the viewer in world space, transforming vertices
into camera space. In camera space, the camera, or viewer, is at the origin,
looking in the positive z-direction. Recall that Microsoft® Direct3D® uses a
left-handed coordinate system, so z is positive into a scene. The view matrix
relocates the objects in the world around a camera's position—the origin of
camera space—and orientation. There are many ways to create a view matrix. In
all cases, the camera has some logical position and orientation in world space
that is used as a starting point to create a view matrix that will be applied
to the models in a scene. The view matrix translates and rotates objects to
place them in camera space, where the camera is at the origin. One way to
create a view matrix is to combine a translation matrix with rotation matrices
for each axis. In this approach, the following general matrix formula applies.
In this formula, V is the view matrix being created, T is a translation matrix
that repositions objects in the world, and Rx through Rz are rotation matrices
that rotate objects along the x-, y-, and z-axis. The translation and rotation
matrices are based on the camera's logical position and orientation in world
space. So, if the camera's logical position in the world is <10,20,100>, the
aim of the translation matrix is to move objects -10 units along the x-axis,
-20 units along the y-axis, and -100 units along the z-axis. The rotation
matrices in the formula are based on the camera's orientation, in terms of how
the much the axes of camera space are rotated out of alignment with world
space. For example, if the camera mentioned earlier is pointing straight down,
its z-axis is 90 degrees (pi/2 radians) out of alignment with the z-axis of
world space, as shown in the following illustration. The rotation matrices
apply rotations of equal, but opposite, magnitude to the models in the scene.
The view matrix for this camera includes a rotation of -90 degrees around the
x-axis. The rotation matrix is combined with the translation matrix to create a
view matrix that adjusts the position and orientation of the objects in the
scene so that their top is facing the camera, giving the appearance that the
camera is above the model. [C++] Another approach involves creating the
composite view matrix directly. The D3DXMatrixLookAtLH and D3DXMatrixLookAtRH
helper functions use this technique. This approach uses the camera's world
space position and a look-at point in the scene to derive vectors that describe
the orientation of the camera space coordinate axes. The camera position is
subtracted from the look-at point to produce a vector for the camera's
direction vector (vector n). Then the cross product of the vector n and the
y-axis of world space is taken and normalized to produce a right vector (vector
u). Next, the cross product of the vectors u and n is taken to determine an up
vector (vector v). The right (u), up (v), and view-direction (n) vectors
describe the orientation of the coordinate axes for camera space in terms of
world space. The x, y, and z translation factors are computed by taking the
negative of the dot product between the camera position and the u, v, and n
vectors. [Visual Basic] Another approach involves creating the composite view
matrix directly. The D3DXMatrixLookAtRH and D3DXMatrixLookAtRH methods use this
technique. This approach uses the camera's world space position and a look-at
point in the scene to derive vectors that describe the orientation of the
camera space coordinate axes. The camera position is subtracted from the
look-at point to produce a vector for the camera's direction vector (vector n).
Then the cross product of the vector n and the y- axis of world space is taken
and normalized to produce a right vector (vector u). Next, the cross product of
the vectors u and n is taken to determine an up vector (vector v). The right
(u), up (v), and view-direction (n) vectors describe the orientation of the
coordinate axes for camera space in terms of world space. The x, y, and z
translation factors are computed by taking the negative of the dot product
between the camera position and the u, v, and n vectors. These values are put
into the following matrix to produce the view matrix. In this matrix, u, v, and
n are the up, right, and view-direction vectors, and c is the camera's world
space position. This matrix contains all the elements needed to translate and
rotate vertices from world space to camera space. After creating this matrix,
you can also apply a matrix for rotation around the z-axis to allow the camera
to roll. For information on implementing this technique, see Setting Up a View
Matrix. Setting Up a View Matrix [C++] The D3DXMatrixLookAtLH and
D3DXMatrixLookAtRH helper functions create a view matrix based on the camera
location and a look-at point. They use the D3DXVec3Cross, D3DXVec3Dot,
D3DXVec3Normalize, and D3DXVec3Subtract helper functions. The following code
example, illustrates the D3DXMatrixLookAtLH function. D3DXMATRIX* WINAPI
D3DXMatrixLookAtLH ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const
D3DXVECTOR3 *pAt, const D3DXVECTOR3 *pUp ) { #if DBG if(!pOut || !pEye || !pAt
|| !pUp) return NULL; #endif D3DXVECTOR3 XAxis, YAxis, ZAxis; // Get the z
basis vector, which points straight ahead; the // difference from the eye point
to the look-at point. This is the // direction of the gaze (+z).
D3DXVec3Subtract(&ZAxis, pAt, pEye); // Normalize the z basis vector.
D3DXVec3Normalize(&ZAxis, &ZAxis); // Compute the orthogonal axes from the
cross product of the gaze // and the pUp vector. D3DXVec3Cross(&XAxis, pUp,
&ZAxis); D3DXVec3Normalize(&XAxis, &XAxis); D3DXVec3Cross(&YAxis, &ZAxis,
&XAxis); // Start building the matrix. The first three rows contain the //
basis vectors used to rotate the view to point at the look-at // point. The
fourth row contains the translation values. // Rotations are still about the
eyepoint. pOut->_11 = XAxis.x; pOut->_21 = XAxis.y; pOut->_31 = XAxis.z;
pOut->_41 = -D3DXVec3Dot(&XAxis, pEye); pOut->_12 = YAxis.x; pOut->_22 =
YAxis.y; pOut->_32 = YAxis.z; pOut->_42 = -D3DXVec3Dot(&YAxis, pEye); pOut->_13
= ZAxis.x; pOut->_23 = ZAxis.y; pOut->_33 = ZAxis.z; pOut->_43 =
-D3DXVec3Dot(&ZAxis, pEye); pOut->_14 = 0.0f; pOut->_24 = 0.0f; pOut->_34 =
0.0f; pOut->_44 = 1.0f; return pOut; } As with the world transformation, you
call the IDirect3DDevice8::SetTransform method to set the view transformation,
specifying the D3DTS_VIEW flag in the first parameter. For more information,
see Setting Transformations. [Visual Basic] Microsoft® Visual Basic®
applications use the D3DXMatrixLookAtLH and D3DXMatrixLookAtRH helper functions
to create a view matrix based on the camera location, a look-at point, and an
up vector (usually 0,1,0). The following example code, written in Visual Basic,
shows how you can use the D3DXMatrixLookAtLH function. ' This example assumes
that g_D3DDevice is a valid reference ' to a Direct3DDevice8 object. Dim
matView As D3DMATRIX ' Set the eyepoint five units back along the z-axis ' and
up three units. D3DXMatrixLookAtLH matView, vec3(0#, 3#, -5#), _ vec3(0#, 0#,
0#), _ vec3(0#, 1#, 0#) g_D3DDevice.SetTransform D3DTS_VIEW, matView As with
the world transformation, you call the Direct3DDevice8.SetTransform method to
set the view transformation, specifying the D3DTS_VIEW flag in the first
parameter. See Setting Transformations, for more information. Performance
Optimization Note Microsoft® Direct3D® uses the world and view matrices that
you set to configure several internal data structures. Each time you set a new
world or view matrix, the system recalculates the associated internal
structures. Setting these matrices frequently—for example, 20,000 times per
frame—is computationally expensive. You can minimize the number of required
calculations by concatenating your world and view matrices into a world-view
matrix that you set as the world matrix, and then setting the view matrix to
the identity. Keep cached copies of individual world and view matrices that you
can modify, concatenate, and reset the world matrix as needed. For clarity,
Direct3D samples rarely employ this optimization. The Projection Transformation
You can think of the projection transformation as controlling the camera's
internals; it is analogous to choosing a lens for the camera. This is the most
complicated of the three transformation types. This discussion of the
projection transformation is organized into the following topics. * The Viewing
Frustum * What Is the Projection Transformation? * Setting Up a Projection
Matrix * A W-Friendly Projection Matrix The Viewing Frustum A viewing frustum
is 3-D volume in a scene positioned relative to the viewport's camera. The
shape of the volume affects how models are projected from camera space onto the
screen. The most common type of projection, a perspective projection, is
responsible for making objects near the camera appear bigger than objects in
the distance. For perspective viewing, the viewing frustum can be visualized as
a pyramid, with the camera positioned at the tip. This pyramid is intersected
by a front and back clipping plane. The volume within the pyramid between the
front and back clipping planes is the viewing frustum. Objects are visible only
when they are in this volume. If you imagine that you are standing in a dark
room and looking through a square window, you are visualizing a viewing
frustum. In this analogy, the near clipping plane is the window, and the back
clipping plane is whatever finally interrupts your view—the skyscraper across
the street, the mountains in the distance, or nothing at all. You can see
everything inside the truncated pyramid that starts at the window and ends with
whatever interrupts your view, and you can see nothing else. The viewing
frustum is defined by fov (field of view) and by the distances of the front and
back clipping planes, specified in z-coordinates. In this illustration, the
variable D is the distance from the camera to the origin of the space that was
defined in the last part of the geometry pipeline—the viewing transformation.
This is the space around which you arrange the limits of your viewing frustum.
For information about how this D variable is used to build the projection
matrix, see What Is the Projection Transformation? What Is the Projection
Transformation? The projection matrix is typically a scale and perspective
projection. The projection transformation converts the viewing frustum into a
cuboid shape. Because the near end of the viewing frustum is smaller than the
far end, this has the effect of expanding objects that are near to the camera;
this is how perspective is applied to the scene. In The Viewing Frustum, the
distance between the camera required by the projection transformation and the
origin of the space defined by the viewing transformation is defined as D. A
beginning for a matrix defining the perspective projection might use this D
variable like this: The viewing matrix puts the camera at the origin of the
scene. Because the projection matrix needs to have the camera at (0, 0, -D), it
translates the vector by -D in the z- direction, by using the following matrix.
Multiplying these two matrices gives the following composite matrix. The
following illustration shows how the perspective transformation converts a
viewing frustum into a new coordinate space. Notice that the frustum becomes
cuboid and also that the origin moves from the upper-right corner of the scene
to the center. In the perspective transformation, the limits of the x- and
y-directions are -1 and 1. The limits of the z-direction are 0 for the front
plane and 1 for the back plane. This matrix translates and scales objects based
on a specified distance from the camera to the near clipping plane, but it
doesn't consider the field of view (fov), and the z-values that it produces for
objects in the distance can be nearly identical, making depth comparisons
difficult. The following matrix addresses these issues, and it adjusts vertices
to account for the aspect ratio of the viewport, making it a good choice for
the perspective projection. In this matrix, Zn is the z-value of the near
clipping plane. The variables w, h, and Q have the following meanings. Note
that fovw and fovh represent the viewport's horizontal and vertical fields of
view, in radians. For your application, using field-of-view angles to define
the x and y scaling coefficients might not be as convenient as using the
viewport's horizontal and vertical dimensions (in camera space). As the math
works out, the following two formulas for w and h use the viewport's
dimensions, and are equivalent to the preceding formulas. In these formulas, Zn
represents the position of the near clipping plane, and the Vw and Vh variables
represent the width and height of the viewport, in camera space. [C++] For a
C++ application, these two dimensions correspond directly to the Width and
Height members of the D3DVIEWPORT8 structure. Whatever formula you decide to
use, it's important that you set Zn to as large a value as possible, as
z-values extremely close to the camera don't vary by much. This makes depth
comparisons using 16-bit z-buffers somewhat complicated. As with the world and
view transformations, you call the IDirect3DDevice8::SetTransform method to set
the projection transformation; for more information, see Setting
Transformations. [Visual Basic] For a Microsoft® Visual Basic® application,
these two dimensions correspond directly to the Width and Height members of the
D3DVIEWPORT8 type. Whatever formula you decide to use, it's important that you
set Zn to as large a value as possible, as z-values extremely close to the
camera don't vary by much, making depth comparisons using 16-bit z-buffers
tricky. As with the world and view transformations, you call the
Direct3DDevice8.SetTransform method to set the projection transformation; for
more information, see Setting Transformations. Setting Up a Projection Matrix
[C++] The following ProjectionMatrix sample function—written in C++—takes four
input parameters that set the front and back clipping planes, as well as the
horizontal and vertical field of view angles. This code parallels the approach
discussed in the What Is the Projection Transformation? topic. The fields of
view should be less than pi radians. D3DMATRIX ProjectionMatrix(const float
near_plane, // Distance to near clipping // plane const float far_plane, //
Distance to far clipping // plane const float fov_horiz, // Horizontal field of
view // angle, in radians const float fov_vert) // Vertical field of view //
angle, in radians { float h, w, Q; w = (float)1/tan(fov_horiz*0.5); // 1/tan(x)
== cot(x) h = (float)1/tan(fov_vert*0.5); // 1/tan(x) == cot(x) Q =
far_plane/(far_plane - near_plane); D3DMATRIX ret; ZeroMemory(&ret,
sizeof(ret)); ret(0, 0) = w; ret(1, 1) = h; ret(2, 2) = Q; ret(3, 2) =
-Q*near_plane; ret(2, 3) = 1; return ret; } // End of ProjectionMatrix After
you create the matrix, you must set it in a call to the
IDirect3DDevice8::SetTransform method, specifying D3DTRANSFORMSTATE_PROJECTION
in the first parameter. For details, see Setting Transformations. The Direct3DX
utility library provides the following functions to help you set up your
projections matrix. * D3DXMatrixPerspectiveLH * D3DXMatrixPerspectiveRH *
D3DXMatrixPerspectiveFovLH * D3DXMatrixPerspectiveFovRH *
D3DXMatrixPerspectiveOffCenterLH * D3DXMatrixPerspectiveOffCenterRH [Visual
Basic] Applications written in Microsoft® Visual Basic® can create a projection
matrix as described in the What Is the Projection Transformation? topic.
However, the Direct3DX utility library provides the following functions to help
you set up your projections matrix. * D3DXMatrixPerspectiveLH *
D3DXMatrixPerspectiveRH * D3DXMatrixPerspectiveFovLH *
D3DXMatrixPerspectiveFovRH * D3DXMatrixPerspectiveOffCenterLH *
D3DXMatrixPerspectiveOffCenterRH The following Visual Basic code example shows
how D3DXMatrixPerspectiveLH is commonly used. ' This example assumes that
g_D3DDevice is a valid reference ' to a Direct3DDevice8 object. ' For the
projection matrix, set up a perspective transform, which ' transforms geometry
from 3-D view space to 2-D viewport space, ' with a perspective divide that
makes objects smaller in the ' distance. To build a perspective transform, you
need the field ' of view (1/4 pi is common), the aspect ratio, and the near and
' far clipping planes, which define the distances at which ' geometry should be
no longer be rendered. Dim matProj As D3DMATRIX D3DXMatrixPerspectiveFovLH
matProj, g_pi / 4, 1, 1, 1000 g_D3DDevice.SetTransform D3DTS_PROJECTION,
matProj After you create the matrix, you must set it in a call to the
Direct3DDevice8.SetTransform method, specifying D3DTRANSFORMSTATE_PROJECTION in
the first parameter. For details, see Setting Transformations. A W-Friendly
Projection Matrix Microsoft® Direct3D® can use the W component of a vertex that
has been transformed by the world, view, and projection matrices to perform
depth-based calculations in depth-buffer or fog effects. Computations such as
these require that your projection matrix normalize W to be equivalent to
world-space Z. In short, if your projection matrix includes a (3,4) coefficient
that is not 1, you must scale all the coefficients by the inverse of the (3,4)
coefficient to make a proper matrix. If you don't provide a compliant matrix,
fog effects and depth buffering are not applied correctly. The projection
matrix recommended in What Is the Projection Transformation? is compliant with
w-based calculations. The following illustration shows a non-compliant
projection matrix, and the same matrix scaled so that eye-relative fog will be
enabled. In the preceding matrices, all variables are assumed to be nonzero.
For more information about eye-relative fog, see Eye-Relative vs. Z-based
Depth. For information about w-based depth buffering, see What Are Depth
Buffers? Note Direct3D uses the currently set projection matrix in its w-based
depth calculations. As a result, applications must set a compliant projection
matrix to receive the desired w-based features, even if they do not use the
Direct3D transformation pipeline. The Lighting Engine This section introduces
the general concepts behind the Microsoft® Direct3D® lighting engine. The
following topics are discussed. * Enabling and Disabling the Lighting Engine *
Light Color Types and Sources * Fog Effects For detailed information on the
inner working of the lighting engine, see Mathematics of Direct3D Lighting.
Enabling and Disabling the Lighting Engine [C++] By default, Microsoft®
Direct3D® performs lighting calculations on all vertices, even those without
vertex normals. This is different from the behavior in previous releases of
Microsoft DirectX®, where lighting was performed only on vertices that
contained a vertex normal. However, you can disable lighting through the
D3DRS_LIGHTING render state. Call the IDirect3DDevice8::SetRenderState method,
passing D3DRS_LIGHTING as the first parameter, and TRUE or FALSE as the second
parameter. Setting the state to TRUE enables lighting (the default), and
setting it to FALSE disables lighting operations. [Visual Basic] By default,
Microsoft® Direct3D® performs lighting calculations on all vertices, even those
without vertex normals. However, you can disable lighting through the
D3DRS_LIGHTING render state. Call the Direct3DDevice8.SetRenderState method,
passing D3DRS_LIGHTING as the first parameter, and True or False as the second
parameter. Setting the state to True enables lighting (the default), and
setting it to False disables lighting operations. Light Color Types and Sources
Light sources in Microsoft® Direct3D® emit diffuse, ambient, and specular
colors as distinct light components that factor into lighting computations
independently of each other. Similarly, the vertices that the system renders
can use discrete diffuse, ambient, specular, and emissive colors, as defined by
their vertex format. [C++] For a C++ application, these vertex colors are used
by the system only when you set the D3DRS_COLORVERTEX render state to TRUE.
Vertex color sources are selectable; that is, you can configure the system to
select the source for the vertex- color portions of lighting formulas at run
time. The D3DRS_AMBIENTMATERIALSOURCE, D3DRS_DIFFUSEMATERIALSOURCE, and
D3DRS_SPECULARMATERIALSOURCE render states control the source from which the
system draws the associated colors during lighting calculations. You can set
each render state to a member of the D3DMATERIALCOLORSOURCE enumerated type,
which defines values that cause the system to use the current material, or a
color from the vertex, as the color source. [Visual Basic] From Microsoft®
Visual Basic®, vertex colors are used by the system only when you set the
D3DRS_COLORVERTEX render state to True. Vertex color sources are selectable;
that is, you can configure the system to select the source for the vertex-
color portions of lighting formulas at run time. The
D3DRS_AMBIENTMATERIALSOURCE, D3DRS_DIFFUSEMATERIALSOURCE, and
D3DRS_SPECULARMATERIALSOURCE render states control the source from which the
system draws the associated colors during lighting calculations. You can set
each render state to a member of the CONST_D3DMATERIALCOLORSOURCE enumeration,
which defines values that cause the system to use the current material, or a
color from the vertex, as the color source. Fog Effects The Microsoft®
Direct3D® transformation and lighting engine can create fog effects during
lighting. This type of fog is usually referred to as vertex fog because fog
information is placed in the alpha component of the vertex to be rasterized.
For more information see Fog and Vertex Fog. Mathematics of Direct3D Lighting
This section describes the mechanics and implementation details behind the
Microsoft® Direct3D® lighting engine. Direct3D models illumination by
estimating how light behaves in nature. The Direct3D light model keeps track of
light color, the direction and distance that light travels, the position of the
viewer, and the characteristics of the current material to compute two color
components for each vertex in a face. Direct3D uses these color components to
compute the color it draws while rasterizing the pixels of a face. Note All
computations are made in model space by transforming the light source's
position and direction, along with the camera position to model space using the
inverse of the world matrix, then they are back transformed. As a result, if
the world or view matrices introduce nonuniform scaling, the resultant lighting
might be inaccurate. This section presents a technical look at the formulas
that Direct3D uses to come up with diffuse and specular components. By
understanding the approach of Direct3D, you will be better equipped to decide
if the Direct3D light model suits your needs. The Direct3D light model was
designed to be accurate, efficient, and easy to use. However, if the formulas
used by Direct3D don't suit your needs, you can implement your own light model,
bypassing the Direct3D lighting module altogether. The following topics are
discussed. * Lighting Notation * Camera Space Transformation * Basic Lighting
Formula * Diffuse Formula * Specular Formula * Light Attenuation Over Distance
* Reflectance Model * Spotlight Falloff Model The parameters used for these
formulas are listed in the tables below. Each table has its corresponding
default value, type, and a range of accepted values. The following table lists
the position parameters. Parameter Default value Type Description Pe (0,0,0)
D3DVECTOR Camera position in camera space. Po N/A D3DVECTOR Position of current
model origin (0,0,0,1) in the camera space. This is the fourth row of the Mw*Mv
matrix. Mw N/A D3DMATRIX World matrix, set by D3DTRANSFORMSTATE_VIEW. Mv N/A
D3DMATRIX View matrix, set by D3DTRANSFORMSTATE_VIEW. Mwv N/A D3DMATRIX Mw*Mv.
Halfway N/A D3DVECTOR Normalized vector, used to compute specular reflection.
La (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE Ambient color in the light state. Set by
D3DRENDERSTATE_AMBIENT. V N/A D3DVECTOR Vertex position in camera space. N N/A
D3DVECTOR Normalized vertex normal in camera space. Vcd N/A D3DCOLORVALUE
Vertex diffuse color. Vcs N/A D3DCOLORVALUE Vertex specular color. The
following table lists the material parameters. Parameter Default value Type
Description Ma (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE Ambient color. Md (255, 255,
255, 255) D3DCOLORVALUE Diffuse color. Ms (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE
Specular color. Me (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE Emissive color. Mp 0.0
D3DVALUE Specular exponent. Range: (-?,+?) The following table lists the light
source i parameters. Parameter Default value Type Description LpI (0.0, 0.0,
0.0) D3DVECTOR Position in camera space. LdI (0.0, 0.0, 1.0) D3DVECTOR
Direction to the light in the camera space. LrI 0.0 D3DVALUE Distance range.
Range: [0.0, D3DLIGHT_RANGE_MAX] LcaI (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE
Ambient color. LcsI (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE Specular color. LcI
(1.0, 1.0, 1.0, 0.0) D3DCOLORVALUE Diffuse color. att0I 0.0 D3DVALUE Constant
attenuation factor. Range: (0, +?) att1I 0.0 D3DVALUE Linear attenuation
factor. Range: (0, +?) att2I 0.0 D3DVALUE Quadratic attenuation factor. Range:
(0, +?) falloffI 0.0 D3DVALUE Falloff factor. Range: (-?, +?) thetaI 0.0
D3DVALUE Umbra angle of spotlight in radians. Range: [0, ?) phiI 0.0 D3DVALUE
Penumbra angle of spotlight in radians. Range: [thetaI, ?) Lighting Notation
[C++] The following notations are used in the lighting formulas. The range of a
D3DCOLORVALUE component is (-?, +?). • - dot product is defined as d1 • d2 =
max{d1•d2, 0} norm(P) - normalized vector V1V2 - vector from point V1 to point
V2 M-1- inverse matrix MT- transposed matrix V1 / V2 , where V1 and V2 are of
D3DVECTOR type, equals to the vector: (V1.x / V2.x, V1.y / V2.y , V1.z / V2.z).
V1 * V2 , where V1 and V2 are of D3DVECTOR type, equals to the vector: (V1.x *
V2.x, V1.y * V2.y , V1.z * V2.z). [Visual Basic] The following notations are
used in the lighting formulas. The range of a D3DCOLORVALUE component is (-?,
+?). • - dot product is defined as d1 • d2 = max{d1•d2, 0} norm(P) - normalized
vector V1V2 - vector from point V1 to point V2 M-1- inverse matrix MT-
transposed matrix V1 / V2 , where V1 and V2 are of D3DVECTOR type, equals to
the vector: (V1.x / V2.x, V1.y / V2.y , V1.z / V2.z). V1 * V2 , where V1 and V2
are of D3DVECTOR type, equals to the vector: (V1.x * V2.x, V1.y * V2.y , V1.z *
V2.z). Camera Space Transformation Vertices in the camera space are computed by
multiplying the object vertices by Mwv matrix. v = Vobject * Mwv Normals in the
camera space are computed by multiplying the object normals by inverse
transposed Mwv matrix and normalizing the result. N = Nobject * (Mwv-1)T If
D3DRENDERSTATE_NORMALIZENORMALS is set to TRUE, normals are normalized after
transformation to the camera space: N = norm(N) Light position in the camera
space (Lpi) is computed by multiplying the light source position by Mv. Lpi =
Lporiginal * Mv Direction to light in the camera space for D3DLIGHT_DIRECTIONAL
lights is computed by multiplying the light source position by Mv matrix,
normalizing and negating the result. Ldi = -norm(Ldi original * Mv) For the
D3DLIGHT_POINT and D3DLIGHT_SPOT the direction to light is computed as: Ldi =
norm(VLpi) Basic Lighting Formula The output of the lighting stage is diffuse
(D) and specular (S) colors in RGBA format. Lighting may be in one of two
states: 1. Lighting Off (D3DRENDERSTATE_LIGHTING is set to FALSE). In this
state the vertex color is computed as follows: D3DRENDERSTATE_COLORVETEX is
ignored. If the diffuse vertex color is present, the output diffuse color is
equal to the vertex diffuse color. Otherwise, the diffuse color is equal to the
default diffuse color (255,255,255,255). Output diffuse color is scaled and
clamped to the range [0, 255]. If the specular vertex color is present, the
output specular color is equal to the vertex specular color. Otherwise, the
specular color is equal to the default specular (0,0,0,0). Output specular
color is scaled and clamped to the range [0, 255]. 2. Lighting On
(D3DRENDERSTATE_LIGHTING is set to TRUE). In this state, Direct3D computes
vertex colors according to the formulas below. If normals are not present in
the vertices, the part of the lighting equations that depends on dot product is
set to zero. Lighting is still computed. Lighting is done in the camera space.
alpha component is not used in the following lighting equations. Diffuse
Formula The following explains the formula for diffuse lighting. The specular
component is set to (0, 0, 0, 0) if D3DRENDERSTATE_SPECULARENABLE is set to
FALSE, otherwise it is computed as follows: where Specular Formula The
following explains the formula for specular lighting. hi are half way vectors
between the normal and the direction to light. hi = norm(norm(Vpe) + Ldi)), if
D3DRENDERSTATE_LOCALVIEWER = TRUE hi = norm((0,0,-1) + Ldi)), if
D3DRENDERSTATE_LOCALVIEWER = FALSE rhoi = norm(Ldi) ? norm(VLpi) di is a
distance from a vertex to the light i and is computed as follows: Diffuse and
specular components are clamped to be from 0 to 255, after all lights are
processed and interpolated separately. Light Attenuation Over Distance [C++]
Microsoft® Direct3D® determines the distance between a light source and a
vertex being lit by taking the magnitude of the vector that exists between the
light's position and the vertex. This is represented by the following formula.
In the preceding formula, D is the distance being calculated, V is the position
of the vertex being lit, and L is the light source's position. If D is greater
than the light's range, that is, the Range member of a D3DLIGHT8 structure,
Direct3D makes no further attenuation calculations and applies no effects from
the light to the vertex. If the distance is within the light's range, Direct3D
then applies the following formula to calculate light attenuation over distance
for point lights and spotlights; directional lights don't attenuate. In this
attenuation formula, A is the calculated total attenuation and D is the
distance from the light source to the vertex. The dvAttenuation0,
dvAttenuation1, and dvAttenuation2 values are the light's attenuation constants
as specified by the members of a light object's D3DLIGHT8 structure. The
corresponding structure members are Attenuation0, Attenuation1, and
Attenuation2. The attenuation constants act as coefficients in the formula—you
can produce a variety of attenuation curves by making simple adjustments to
them. You can set Attenuation0 to 1.0 to create a light that doesn't attenuate
but is still limited by range, or you can experiment with different values to
achieve various attenuation effects. The attenuation at the maximum range of
the light is not 0.0. To prevent lights from suddenly appearing when they are
at the light range, an application can increase the light range. Or, the
application can set up attenuation constants so that the attenuation factor is
close to 0.0 at the light range. The attenuation value is multiplied by the
red, green, and blue components of the light's color to scale the light's
intensity as a factor of the distance light travels to a vertex. After
computing the light attenuation, Direct3D also considers spotlight effects if
applicable, the angle that the light reflects from a surface, and the
reflectance of the current material to calculate the diffuse and specular
components for that vertex. For more information, see Spotlight Falloff Model
and Reflectance Model. [Visual Basic] Microsoft® Direct3D® determines the
distance between a light source and a vertex being lit by taking the magnitude
of the vector that exists between the light's position and the vertex. This is
represented by the following formula. In the preceding formula, D is the
distance being calculated, V is the position of the vertex being lit, and L is
the light source's position. If D is greater than the light's range—the Range
member of a D3DLIGHT8 type—Direct3D makes no further attenuation calculations
and applies no effects from the light to the vertex. If the distance is within
the light's range, Direct3D then applies the following formula to calculate
light attenuation over distance for point lights and spotlights; directional
lights don't attenuate. In this attenuation formula, A is the calculated total
attenuation and D is the distance from the light source to the vertex. The
attenuation0, attenuation1, and attenuation2 values are the light's attenuation
constants as specified by the members of a light object's D3DLIGHT8 type. The
corresponding structure members are Attenuation0, Attenuation1, and
Attenuation2. The attenuation constants act as coefficients in the formula—you
can produce a variety of attenuation curves by making simple adjustments to
them. You can set Attenuation0 to 1.0 to create a light that doesn't attenuate
but is still limited by range, or you can experiment with different values to
achieve various attenuation effects. The attenuation at the maximum range of
the light is not 0.0. To prevent lights from suddenly appearing when they are
at the light range, an application can increase the light range. Or, the
application can set up attenuation constants so that the attenuation factor is
close to 0.0 at the light range. The attenuation value is multiplied by the
red, green, and blue components of the light's color to scale the light's
intensity as a factor of the distance light travels to a vertex. After
computing the light attenuation, Direct3D also considers spotlight effects if
applicable, the angle that the light reflects from a surface, and the
reflectance of the current material to calculate the diffuse and specular
components for that vertex. For more information, see Spotlight Falloff Model
and Reflectance Model. Reflectance Model After adjusting the light intensity
for any attenuation effects, Microsoft® Direct3D® computes how much of the
remaining light reflects from a vertex given the angle of the vertex normal and
the direction of the incident light. Direct3D skips to this step for
directional lights because they don't attenuate over distance. The system
considers two reflection types, diffuse and specular, and uses a different
formula to determine how much light is reflected for each. After calculating
the amounts of light reflected, Direct3D applies these new values to the
diffuse and specular reflectance properties of the current material. The
resulting color values are the diffuse and specular components that the
rasterizer uses to produce Gouraud shading and specular highlighting. Diffuse
Reflection Model [C++] Microsoft Direct3D uses the following formula to compute
diffuse reflection factors. In this formula, Rd is the diffuse reflectance
factor, D is the direction that the light travels to the vertex, and N is the
vertex normal. Vector D is normalized; vector N is normalized only if the
D3DRS_NORMALIZENORMALS render state is enabled. The light's direction vector is
reversed by multiplying it by -1 to create the proper association between the
direction vector and the vertex normal. This formula produces values that range
from -1.0 to 1.0, which are clamped to the range of 0.0 to 1.0 and used to
scale the intensity of the light reflecting from the vertex. After the diffuse
reflection formula is applied, the scaled light is then applied to the diffuse
reflectance formula to determine the diffuse component at that vertex. The
formula that combines ambient and diffuse reflection to create the diffuse
component for the vertex looks like this: In the preceding formula, Dv is the
diffuse component being calculated for the vertex, Ia is the ambient light
level in the scene, and A is the light intensity for a light source that has
been attenuated for distance and spotlight effects (attenuation from Light
Attenuation Over Distance multiplied by Spotlight Falloff Model). The L
variables represent the light's properties, and the V entries represent the
vertex color, where the subscripts a, d, and e applied to each denote the type
of color—ambient, diffuse, or emissive. As the formula notation states, the
system computes IaVa + Ve once, adding A(RdVdLd ? VaLa) for every active light.
If the D3DRS_COLORVERTEX render state is enabled, the system selects colors for
V based on the values set for the D3DRS_AMBIENTMATERIALSOURCE and
D3DRS_DIFFUSEMATERIALSOURCE render states. Set these render states to a member
of the D3DMATERIALCOLORSOURCE enumerated type to cause the system to use the
current material, or a color from the vertex, as the color source. For more
information, see Specular Reflection Model. [Visual Basic] Microsoft Direct3D
uses the following formula to compute diffuse reflection factors. In this
formula, Rd is the diffuse reflectance factor, D is the direction that the
light travels to the vertex, and N is the vertex normal. Vector D is
normalized; vector N is normalized only if the D3DRS_NORMALIZENORMALS render
state is enabled. The light's direction vector is reversed by multiplying it by
-1 to create the proper association between the direction vector and the vertex
normal. This formula produces values that range from -1.0 to 1.0, which are
clamped to the range of 0.0 to 1.0 and used to scale the intensity of the light
reflecting from the vertex. After the diffuse reflection formula is applied,
the scaled light is then applied to the diffuse reflectance formula to
determine the diffuse component at that vertex. The formula that combines
ambient and diffuse reflection to create the diffuse component for the vertex
looks like this: In the preceding formula, Dv is the diffuse component being
calculated for the vertex, Ia is the ambient light level in the scene, and A is
the light intensity for a light source that has been attenuated for distance
and spotlight effects—attenuation from Light Attenuation Over Distance
multiplied by Spotlight Falloff Model. The L variables represent the light's
properties, and the V entries represent the vertex color, where the subscripts
a, d, and e applied to each denote the type of color—ambient, diffuse, or
emissive. As the formula notation states, the system computes IaVa + Ve once,
adding A(RdVdLd ? VaLa) for every active light. If the D3DRS_COLORVERTEX render
state is enabled, the system selects colors for V based on the values set for
the D3DRS_AMBIENTMATERIALSOURCE and D3DRS_DIFFUSEMATERIALSOURCE render states.
Set these render states to a member of the CONST_D3DMATERIALCOLORSOURCE
enumeration to cause the system to use the current material, or a color from
the vertex, as the color source. For more information, see Specular Reflection
Model. Specular Reflection Model [C++] Modeling specular reflection requires
that the system not only know the direction that light is traveling, but also
the direction to the viewer's eye. The system uses a simplified version of the
Phong specular-reflection model, which employs a halfway vector to approximate
the intensity of specular reflection. This halfway vector exists midway between
the vector to the light source and the vector to the eye. Microsoft Direct3D
provides applications with two ways to compute the halfway vector, which is
controlled by the D3DRS_LOCALVIEWER render state. If D3DRS_LOCALVIEWER is set
to TRUE, the system calculates the halfway vector using the position of the
camera and the position of the vertex, along with the light's direction vector.
The following formula illustrates this. In the preceding formula, norm is an
operator that normalizes an input vector, VC is the vector that exists from the
position of the vertex to the position of the viewpoint or eye, and Ld is the
light's direction vector. Determining the halfway vector in this manner can be
computationally expensive. As an alternative, you can set D3DRS_LOCALVIEWER to
FALSE. This instructs the system to act as though the viewpoint is infinitely
distant on the z-axis. This setting is less computationally expensive, but much
less accurate, so it is best used by applications that use orthogonal
projection. When D3DRS_LOCALVIEWER is set to FALSE, Direct3D determines the
halfway vector by the following formula. This formula is similar to the first
formula, but substitutes the vector I (0, 0, -1)— which points at a viewpoint
infinitely distant on the z-axis—instead of computing the vector VC. After
determining the halfway vector, H, the system uses the following formula to
compute specular reflection. In the preceding formula, Rs is the specular
reflectance, N in the vertex normal, H is the halfway vector, and p is the
specular reflection power of the current material, as specified by the Power
member of the material's D3DMATERIAL8 structure. Vector H is normalized, and
vector N is normalized only if the D3DRS_NORMALIZENORMALS render state is
enabled. As with the diffuse reflectance formula, this formula produces values
that range from -1.0 to 1.0, which are clamped to the range of 0.0 to 1.0 and
used to scale the light reflecting from the vertex. Also similar to the diffuse
reflection model, the remaining light is applied to a formula that derives the
specular component at that vertex: In this formula, Sv is the specular color
being computed. A is the light from a single light source that has been
attenuated for distance and spotlight effects; for more information, see Light
Attenuation Over Distance and Spotlight Falloff Model. The Rs variable is the
previously calculated specular reflectance, Vs is the specular component for
the vertex, and Ls is the specular light color output by the light. If the
D3DRS_COLORVERTEX render state is enabled, the system selects the color source
for V based on the value of the D3DRS_SPECULARMATERIALSOURCE render state. This
render state can be set to a member of the D3DMATERIALCOLORSOURCE enumerated
type to cause the system to use the current material or one of the color
components for the vertex as the color source. For more information, see
Diffuse Reflection Model. [Visual Basic] Modeling specular reflection requires
that the system not only know the direction that light is traveling, but also
the direction to the viewer's eye. The system uses a simplified version of the
Phong specular-reflection model, which employs a halfway vector to approximate
the intensity of specular reflection. This halfway vector exists midway between
the vector to the light source and the vector to the eye. Microsoft® Direct3D®
provides applications with two ways to compute the halfway vector, which is
controlled by the D3DRS_LOCALVIEWER render state. If D3DRS_LOCALVIEWER is set
to True, the system calculates the halfway vector using the position of the
camera and the position of the vertex, along with the light's direction vector.
The following formula illustrates this. In the preceding formula, norm is an
operator that normalizes an input vector, VC is the vector that exists from the
position of the vertex to the position of the viewpoint or eye, and Ld is the
light's direction vector. Determining the halfway vector in this manner can be
computationally intensive. As an alternative, you can set D3DRS_LOCALVIEWER to
FALSE. This instructs the system to act as though the viewpoint is infinitely
distant on the z-axis. This setting is less computationally expensive, but much
less accurate, so it is best used by applications that use orthogonal
projection. When D3DS_LOCALVIEWER is set to False, Direct3D determines the
halfway vector by the following formula. This formula is similar to the first
formula, but substitutes the vector I (0, 0, -1)— which points at a viewpoint
infinitely distant on the z-axis—instead of computing the vector VC. After
determining the halfway vector, H, the system uses the following formula to
compute specular reflection. In the preceding formula, Rs is the specular
reflectance, N in the vertex normal, H is the halfway vector, and p is the
specular reflection power of the current material as specified by the power
member of the material's D3DMATERIAL8 type. Vector H is normalized, and vector
N is normalized only if the D3DRS_NORMALIZENORMALS render state is enabled. As
with the diffuse reflectance formula, this formula produces values that range
from -1.0 to 1.0, which are clamped to the range of 0.0 to 1.0 and used to
scale the light reflecting from the vertex. Also similar to the diffuse
reflection model, the remaining light is applied to a formula that derives the
specular component at that vertex: In the preceding formula, Sv is the specular
color being computed. A is the light from a single light source that has been
attenuated for distance and spotlight effects; for more information, see Light
Attenuation Over Distance and Spotlight Falloff Model. The Rs variable is the
previously calculated specular reflectance, Vs is the selected specular
component for the vertex, and Ls is the specular light color output by the
light. If the D3DRS_COLORVERTEX render state is enabled, the system selects the
color source for V based on the value of the D3DRS_SPECULARMATERIALSOURCE
render state. This render state can be set to a member of the
CONST_D3DMATERIALCOLORSOURCE enumerated type to cause the system to use the
current material or one of the color components for the vertex as the color
source. For more information, see Diffuse Reflection Model. Spotlight Falloff
Model [C++] Spotlights emit a cone of light that has two parts: a bright inner
cone and an outer cone. Light is brightest in the inner cone and isn't present
outside the outer cone, with light intensity attenuating between the two areas.
This type of attenuation is commonly referred to as falloff. How much light a
vertex receives is based on the vertex's location in the inner or outer cones.
Microsoft® Direct3D® computes the dot product of the spotlight's direction
vector (L) and the vector from the vertex to the light (D). This value is equal
to the cosine of the angle between the two vectors, and serves as an indicator
of the vertex's position that can be compared to the light's cone angles to
determine where the vertex might lie in the inner or outer cones. The following
illustration provides a graphical representation of the association between
these two vectors. Next, the system compares this value to the cosine of the
spotlight's inner and outer cone angles. In the light's D3DLIGHT8 structure,
the Theta and Phi members represent the total cone angles for the inner and
outer cones. Because the attenuation occurs as the vertex becomes more distant
from the center of illumination, rather than across the total cone angle,
Direct3D halves these cone angles before calculating their cosines. If the dot
product of vectors L and D is less than or equal to the cosine of the outer
cone angle, the vertex lies beyond the outer cone and receives no light. If the
dot product of L and D is greater than the cosine of the inner cone angle, then
the vertex is within the inner cone and receives the maximum amount of light,
still considering attenuation over distance. If the vertex is somewhere between
the two regions, Direct3D calculates falloff for the vertex by using the
following formula. In the formula, If is light intensity, after falloff, for
the vertex being lit, ? is the angle between vectors L and D, ? is half of the
outer cone angle, ? is half of the inner cone angle, and p is the spotlight's
falloff property—Falloff in the D3DLIGHT8 structure. This formula generates a
value between 0.0 and 1.0 that scales the light's intensity at the vertex to
account for falloff. Attenuation as a factor of the vertex's distance from the
light is also applied. The p value corresponds to the Falloff member of the
D3DLIGHT8 structure and controls the shape of the falloff curve. The following
illustration shows how different Falloff values can affect the falloff curve.
The effect of various Falloff values on the actual lighting is subtle, and a
small performance penalty is incurred by shaping the falloff curve with Falloff
values other than 1.0. For these reasons, this value is typically set to 1.0.
For more information, see Light Attenuation Over Distance. [Visual Basic]
Spotlights emit a cone of light that has two parts: a bright inner cone and an
outer cone. Light is brightest in the inner cone and isn't present outside the
outer cone, with light intensity attenuating between the two areas. This type
of attenuation is commonly referred to as falloff. How much light a vertex
receives is based on the vertex's location in the inner or outer cones.
Microsoft® Direct3D® computes the dot product of the spotlight's direction
vector (L) and the vector from the vertex to the light (D). This value is equal
to the cosine of the angle between the two vectors, and serves as an indicator
of the vertex's position that can be compared to the light's cone angles to
determine where the vertex might lie in the inner or outer cones. The following
illustration provides a graphical representation of the association between
these two vectors. Next, the system compares this value to the cosine of the
spotlight's inner and outer cone angles. In the light's D3DLIGHT8 type, the
Theta and Phi members represent the total cone angles for the inner and outer
cones. Because the attenuation occurs as the vertex becomes more distant from
the center of illumination, rather than across the total cone angle, Direct3D
halves these cone angles before calculating their cosines. If the dot product
of vectors L and D is less than or equal to the cosine of the outer cone angle,
the vertex lies beyond the outer cone and receives no light. If the dot product
of L and D is greater than the cosine of the inner cone angle, then the vertex
is within the inner cone and receives the maximum amount of light, still
considering attenuation over distance. If the vertex is somewhere between the
two regions, Direct3D calculates falloff for the vertex by using the following
formula. In the formula, If is light intensity, after falloff, for the vertex
being lit, ? is the angle between vectors L and D, ? is half of the outer cone
angle, ? is half of the inner cone angle, and p is the spotlight's falloff
property—Falloff in the D3DLIGHT8 type. This formula generates a value between
0.0 and 1.0 that scales the light's intensity at the vertex to account for
falloff. Attenuation as a factor of the vertex's distance from the light is
also applied. The p value corresponds to the Falloff member of the D3DLIGHT8
type and controls the shape of the falloff curve. The following illustration
shows how different Falloff values can affect the falloff curve. The effect of
various Falloff values on the actual lighting is subtle, and a small
performance penalty is incurred by shaping the falloff curve with values other
than 1.0. For these reasons, this value is typically set to 1.0. For more
information, see Light Attenuation Over Distance. Viewports and Clipping This
section discusses clipping, the last stage of the geometry pipeline. The
discussion is organized into the following topics. * What Is a Viewport? *
Viewport Rectangle * Clipping Volumes * Viewport Scaling * Using Viewports
Microsoft® Direct3D® implements clipping by way of a set of viewport parameters
set in the device. What Is a Viewport? Conceptually, a viewport is a 2-D
rectangle into which a three-dimensional scene is projected. In Microsoft®
Direct3D®, the rectangle exists as coordinates within a Direct3D surface that
the system uses as a rendering target. The projection transformation converts
vertices into the coordinate system used for the viewport. You use a viewport
in Direct3D to specify the following features in your application. * The
screen-space viewport to which the rendering will be confined. * The range of
depth values on a render-target surface into which a scene will be rendered
(usually 0.0 to 1.0). Viewport Rectangle [C++] You define the viewport
rectangle in C++ by using the D3DVIEWPORT8 structure. The D3DVIEWPORT8
structure is used with the following viewport manipulation methods exposed by
the IDirect3DDevice8 interface. * IDirect3DDevice8::GetViewport *
IDirect3DDevice8::SetViewport The D3DVIEWPORT8 structure contains four
members—X, Y, Width, and Height—that define the area of the render-target
surface into which a scene will be rendered. These values correspond to the
destination rectangle, or viewport rectangle, as shown in the following
illustration. The values you specify for the X, Y, Width, and Height members of
the D3DVIEWPORT8 structure are screen coordinates relative to the upper-left
corner of the render-target surface. The structure defines two additional
members (MinZ and MaxZ) that indicate the depth-ranges into which the scene
will be rendered. Microsoft® Direct3D® assumes that the viewport clipping
volume ranges from -1.0 to 1.0 in X, and from 1.0 to -1.0 in Y. These were the
settings used most often by applications in the past. During the projection
transformation, you can adjust for viewport aspect ratio before clipping. This
task is covered by topics in The Projection Transformation section. Note The
D3DVIEWPORT8 structure members MinZ and MaxZ indicate the depth- ranges into
which the scene will be rendered and are not used for clipping. Most
applications will set these members to 0.0 and 1.0 to enable the system to
render to the entire range of depth values in the depth buffer. In some cases,
you can achieve special effects by using other depth ranges. For instance, to
render a heads-up display in a game, you can set both values to 0.0 to force
the system to render objects in a scene in the foreground, or you might set
them both to 1.0 to render an object that should always be in the background.
[Visual Basic] You define the viewport rectangle in a Microsoft® Visual Basic®
application by using the D3DVIEWPORT8 type. The D3DVIEWPORT8 type is used with
the following viewport manipulation methods offered by the Direct3DDevice8
class. * Direct3DDevice8.GetViewport * Direct3DDevice8.SetViewport The
D3DVIEWPORT8 type contains four members—x, y, Width, and Height— that define
the area of the render-target surface into which a scene will be rendered,
called the viewport rectangle. These values correspond to the destination
rectangle, or viewport rectangle, a