Introduction to 3D Game Programming with DirectX.9.0 - F. D. Luna
.pdfPicking 265
Figure 15.5 shows a screen shot of the sample application for this chapter. The teapot moves around the screen, and you can try to click on it with the mouse. If you click on the bounding sphere of the teapot, a message box will pop up indicating that you hit it. We handle the mouse click event by testing for a WM_LBUTTONDOWN message:
case WM_LBUTTONDOWN:
//compute the ray in view space given the clicked screen point d3d::Ray ray = CalcPickingRay(LOWORD(lParam), HIWORD(lParam));
//transform the ray to world space
D3DXMATRIX view;
Device->GetTransform(D3DTS_VIEW, &view);
D3DXMATRIX viewInverse;
D3DXMatrixInverse(&viewInverse, 0, &view);
TransformRay(&ray, &viewInverse);
// test for a hit
if( RaySphereIntTest(&ray, &BSphere) ) ::MessageBox(0, "Hit!", "HIT", 0);
break;
15.6 Summary
Picking is the technique used to determine the 3D object that cor- |
|
|
responds to the 2D projected object displayed on the screen that |
I |
|
the user clicked on with the mouse. |
II |
|
art |
||
The picking ray is found by shooting a ray, originating at the origin |
||
of the view space, through the point on the projection window that |
P |
|
|
||
corresponds to the clicked screen point. |
|
|
|
||
We can transform a ray r(t) = p0 + tu by transforming its origin p0 |
|
|
and direction u by a transformation matrix. Note that the origin is |
|
|
transformed as a point (w = 1) and the direction is treated as a vec- |
|
|
tor (w = 0). |
|
|
To test if the ray has intersected an object, we can test if the ray |
|
|
intersected a triangle that composes the object or test if the ray |
|
|
intersects a bounding volume of the object, such as a bounding |
|
|
sphere. |
|
This page intentionally left blank.
Part IV
Shaders and Effects
Thus far, we have achieved a desired effect by altering the configuration of device states such as transforms, lights, textures, and render states. Although the various supported configurations provide us with some flexibility, we are still limited to predefined fixed operations (hence the name “fixed function pipeline”).
The primary theme of this part is vertex and pixel shaders, which replace sections of the fixed function pipeline with a custom program that we implement, called a shader. Shaders are completely programmable and allow us to implement techniques that are not defined in the fixed function pipeline. Consequently, the number of techniques that we have available at our disposal has greatly increased. The programmable sections of the rendering pipeline are commonly referred to as the programmable pipeline. A brief description of the chapters in this part follows.
Chapter 16, “Introduction to the High-Level Shading Language”— In this chapter we explore the High-Level Shading Language (HLSL), which is the language we use to write vertex and pixel shader programs in this book.
Chapter 17, “Introduction to Vertex Shaders”—This chapter explains what vertex shaders are and how to create and use them in Direct3D. The chapter illustrates vertex shaders by explaining the implementation of a cartoon styled shading technique.
Chapter 18, “Introduction to Pixel Shaders”—This chapter explains what pixel shaders are and how to create and use them in Direct3D. The chapter concludes by showing how to implement multitexturing using a pixel shader.
Chapter 19, “The Effects Framework”—In this chapter, we discuss the Direct3D effects framework. The chapter describes the purpose of the effects framework, the structure and syntax of effect files, how to create effect files, and how to use effect files in Direct3D applications.
267
This page intentionally left blank.
Chapter 16
Introduction to the High-Level Shading Language
In this chapter we describe the High-Level Shading Language (HLSL), which we use to program vertex and pixel shaders over the next three chapters. Briefly, vertex and pixel shaders are small custom programs we write, executed on the graphics card’s GPU (graphics processing unit), that replace a portion of the fixed function pipeline. By replacing a section of the fixed function pipeline with our own custom shader program, we obtain a huge amount of flexibility in the graphical effects that we can achieve. We are no longer limited to predefined “fixed” operations.
In order to write shader programs, we need a language to write them in. In DirectX 8.x, shaders were written in a low-level shader assembly language. Fortunately, we no longer have to write shaders in assembly language, as DirectX 9 has supplied a High-Level Shading Language that we can use to write shaders. Using HLSL over assembly language to write shader programs has the same advantages as using a high-level language, like C++, over assembly language to write applications, namely:
Increased productivity—Writing programs in a high-level language is faster and easier than writing them in a low-level language. We can spend more time focusing on algorithms rather than coding.
Improved readability—Programs in a high-level language are easier to read, which implies programs written in a high-level language are easier to debug and maintain.
The compilers, more often than not, generate more efficient assembly code than hand-written assembly code.
269
270Chapter 16
Using the HLSL compiler, we can compile our code to any available shader version. Using the assembly language, we would have to port the code for each desired version.
HLSL is also very similar to C and C++ syntax, thus there is a very short learning curve.
Finally, you will need to switch to the REF device for the shader samples if your graphics card does not support vertex and pixel shaders. Using the REF device means the shader samples run very slowly, but they still display the correct results, allowing us to verify that our code is correct.
Note: Vertex shaders can be emulated in software with software vertex processing — D3DCREATE_SOFTWARE_VERTEXPROCESSING.
Objectives
To learn how to write and compile an HLSL shader program
To learn how to communicate data from the application to the shader program
To become familiar with the syntax, types, and built-in functions of HLSL
16.1Writing an HLSL Shader
We can write the code to our HLSL shaders directly into our application source files as a long character string. However, it is more convenient and modular to separate the shader code from the application code. For this reason, we write our shaders in Notepad and save them as regular ASCII text files. Then we use the D3DXCompileShaderFromFile function (section 16.2.2) to compile our shaders.
As an introduction, the following is a simple vertex shader written in HLSL that was saved to a text file generated in Notepad called Transform.txt. The complete project can be found in the companion files under the title Transform. This vertex shader transforms the vertices by a combined view and projection matrix and sets the diffuse color component of the vertex to blue.
Note: This sample uses a vertex shader as an example, but do not worry about what a vertex shader is supposed to do yet, as they are covered in the next chapter. For now, the objective is to familiarize yourself with the syntax and format of an HLSL program.