- Introduction
- 3D coordinate system
- Object space Objects coordinate system
- World Space Coordinate system
- View Space View coordinate system

- Coordinate system transformations
- World Transformation Transformation
- View Transformation View Transform
- Projection Transformation Projection Transformation

- Using transformations
- Modifying the vertex cache
- Modifying a vertex shader
- Set the Matrix
- Updating the constant cache

Introduction

In this section, we will delve into 3D locations and transformations. The goal of this section is to draw a 3D object onto the screen.

3D coordinate system

In order to place an object somewhere in the world, we need to use the coordinate system and then define three position-related coordinates. In computer graphics, the 3D coordinate system is the most common in cartesian product coordinates. In this coordinate system, there are X, Y, z axes, which are perpendicular to each other. The left-hand system:x-> right,y-> on the,z-> front, right hand is:x-> right,y-> on,z->.

In 3D, the coordinate system can be determined by an origin, and X, Y, Z axes. In computer graphics, there are several common coordinate systems:**object Space**, world **space**, **view space**, **projection space** **, and Screen space**.

Object Space (Objects coordinate system)

The object coordinate system, also called the Model coordinate system (used by artists to design 3D models). The center of the object is the origin point.

World Space (Global coordinate system)

The coordinate system shared by each object in the scene is the world coordinate system. It is often used to define the coordinate system relationship between the set of objects that we want to render. In order to make the world coordinate system more image, we can imagine that we stand in a rectangular room in the southwest corner, facing north. The position of our foot station is defined as (0,0,0). X-Axis->right,y-up, z-axis front (and our direction of alignment). This allows a point in the room to be described with the XYZ axis. So, the world coordinate system is to tell us the relative position of objects in the world.

View Space (visual coordinate system)

Sometimes called the camera coordinate system, and the world coordinate system is a little similar to the whole scene is also used. However, the central point in the visual coordinate system is the observer or camera. The observed direction is defined as the z-axis forward, and the "Up" defined by the application is the y-axis forward.

Coordinate system transformations

Conversion is usually the representation of a vertex from one coordinate system representation to another. In 3D computer graphics, there are several typical transformations in the graphics pipeline: World**Transformation**, **view Transformation**, and **projection transformations (projection Transformation)**.

World transformation (Global transformation)

The world transformation, as the name implies, is to convert the object coordinate system into a world coordinate system (coordinate transformation). including zooming, rotating, moving, each object in the scene has its world transformation matrix, because each object has its size, direction, position.

View transformation (View transform)

After the vertices are turned into a world coordinate system, the viewport transforms the vertices from the world coordinate system into the view coordinate system. In the visual coordinate system, the observer stands at the origin, and is looking toward the distance along the z-axis.

The view transformation matrix is applied to the vertex, not the observer, therefore, the view transformation matrix should give the observer or the camera the opposite transformation. For example, we will move the camera in the negative direction of the z axis for a distance, we need to calculate a visual matrix to move the vertices along the z-axis forward the corresponding distance. The **XMMATRIXLOOKATLH () **api in XNA math is commonly used to calculate a visual matrix. We simply tell it where the observer is, where it is headed, and the observer is in the upward direction, and the corresponding view matrix can be obtained.

Projection Transformation (Projection transformation)

A projection transformation transforms vertices in a coordinate system, such as a visual coordinate system and a world coordinate system, into a projected coordinate system. In a projected coordinate system, the XY axis of a vertex can be obtained from the x/z, y/z ratios of vertices in the 3D coordinate system.

In 3D space, things appear in perspective, and the nearer things look larger. Therefore, the points on the 2D screen are directly related to the x/z and y/z ratios.

FOV, viewable area, truncated cone.

The GPU filters out objects outside the FOV and does not have to be rendered without display, a process called **clipping clipping**. The cropping process is quite complex because the GPU compares each vertex (compared to a plane).

In Direct3D 11, the simplest way to get a projection matrix is to call the **Xmmatrixperspectivefovlh ()** method. We only need to provide four parameters: Fovy, Aspect, Zn, Zf,fovy is the display field in the Y direction, Aspect is the aspect ratio of the view coordinate system, Zn and Zf are near Z values and distant Z values respectively.

Using transformations

In the previous section we simply drew a simple triangle on the screen, and when we created the vertex cache, we used the vertex position of the projected coordinate system directly, so we didn't have to do any conversion, now we have a basic understanding of the 3D coordinate system and the transformation, we define the vertex cache in the object coordinate system, We then modify the vertex shader to convert the object coordinate system into a projected coordinate system.

Modifying the vertex cache

`Simplevertex vertices[] = {{XMFLOAT3 (-1.0f,1.0f, -1.0f), XMFLOAT4 (0.0f,0.0f,1.0f,1.0f)}, {XMFLOAT3 (1.0f,1.0f, -1.0f), XMFLOAT4 (0.0f,1.0f,0.0f,1.0f)}, {XMFLOAT3 (1.0f,1.0f,1.0f), XMFLOAT4 (0.0f,1.0f,1.0f,1.0f)}, {XMFLOAT3 (-1.0f,1.0f,1.0f), XMFLOAT4 (1.0f,0.0f,0.0f,1.0f)}, {XMFLOAT3 (-1.0f, -1.0f, -1.0f), XMFLOAT4 (1.0f,0.0f,1.0f,1.0f)}, {XMFLOAT3 (1.0f, -1.0f, -1.0f), XMFLOAT4 (1.0f,1.0f,0.0f,1.0f)}, {XMFLOAT3 (1.0f, -1.0f,1.0f), XMFLOAT4 (1.0f,1.0f,1.0f,1.0f)}, {XMFLOAT3 (-1.0f, -1.0f,1.0f), XMFLOAT4 (0.0f,0.0f,0.0f,1.0f) }, };`

If we are careful to find out that what we are doing is to clarify eight points on the cube, but in fact we do not have a description of the triangle, if we pass this as is, the output will not be what we expect, we need to clear the eight points to form a cube of the triangle.

A cube, many triangles will share the same vertex, again and again to define the same vertex is a waste of space, so Direct3D can clearly choose which points to make the triangle. This is done through the index cache, which contains our list of vertices with the following code:

`//CreateIndex buffer WORD indices[] = {3,1,0,2,1,3,0,5,4,1,5,0,3,4,7,0,4,3,1,6,5,2,6,1,2,7,6,3,7,2,6,4,5,7,4,6, };`

As you can see, the first triangle consists of the index point 3,1,0, i.e. ( -1.0f, 1.0f, 1.0f), (1.0f, 1.0f, -1.0f), and ( -1.0f, 1.0f, -1.0f), the cube has six faces, each polygon is composed of two triangles, so there is a total 12 triangles are defined.

The creation of the

Index buffer is similar to the creation of a vertex buffer, where we define the size and type of the parameter, and then call the method ** Createbuffer **. The type is ** D3d11_bind_index_buffer **, because we declare that the type of the array is word, and we will use sizeof (WORD) with the following code:

`D3D11_BUFFER_DESC BD; ZeroMemory (&BD, sizeof (BD)); Bd = D3d11_usage_default; Bd = sizeof (WORD) * 36 ; //vertices needed for the triangles in a triangle list bd. Bindflags = D3d11_bind_index_buffer; Bd = 0 ; Bd = 0 ; Initdata.psysmem = indices; if (FAILED (G_pd3ddevice->createbuffer (&BD, &initdata, &g_pindexbuffer)) return false ; `

Once we have created this cache, we need to set it up so that Direct3D knows to refer to the index cache when forming a triangular collection. We explicitly cache pointers, formats, offsets.

`Set index buffer g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );`

Modifying a vertex shader

The vertex shader for the previous section, we enter the vertex position and then output the vertex position without any modification. The reason we can do this is because the vertex position is already defined in the projected coordinate system. Now, because our input vertices are defined in the object coordinate system, it must be converted before the vertex shader outputs the result. It takes three steps: Object coordinate system, world coordinate system, visual coordinate system, and projected coordinate system. 1. Declare three cache variables, cache variables are used to store the data to be passed to the shader, before rendering, the application will usually write important data to the cache, the data can be read to the shader during rendering, in the FX file, the constant cache is declared as a global variable in the C + + structure. These three variables are the world, the view, the projection transformation matrix.

Once we have the desired matrix, we can use the vertex shader to enter the vertex position through the matrix transformation. The code is as follows:

`Cbuffer Constantbuffer:register (b0) {matrix World;Matrix View;Matrix Projection;}////Vertex Shader//Vs_output VS (float4 pos:position, Float4 color:color) {vs_output out put = (vs_output)0;Output. Pos=Mul(Pos, World);Output. Pos=Mul(Output. Pos, View);Output. Pos=Mul(Output. Pos, Projection);Output. Color= Color;Return output;}`

Set the Matrix

We've let the vertex shader go through the matrix, but we also need to define three matrices in our program. These three matrices will save the transformations used when we render. Before rendering, we copy these three matrices to the shader constant cache, and then, when we call **Draw ()** to initialize the render, the vertex shader can read the stored matrix on the constant cache. In addition to matrices, we also need **id3d11buffer** objects to represent constant caches, so the code is as follows:

`ID3D11Buffer* g_pConstantBuffer = NULL; XMMATRIX g_World; XMMATRIX g_View; XMMATRIX g_Projection;`

In order to create the **Id3d11buffer** object, we use **id3d11device::createbuffer ()**:

`D3D11_BUFFER_DESC BD; ZeroMemory (&BD, sizeof (BD)); Bd = D3d11_usage_default; Bd = sizeof (Constantbuffer); Bd = D3d11_bind_constant_buffer; Bd = 0 ; if (FAILED (G_pd3ddevice->createbuffer (&BD, null , &g_pconstantbuffer))) return hr; `

The next thing we need to do is propose an array that will be used to do the conversion. We want the triangle to be located at the origin and parallel to the XY plane, which in fact is how it is stored in the vertex cache in the object's coordinate system. So the world transforms nothing to do, we initialize the world array to an array of units. We want to set the camera at [0 1-5] position, looking at [0 1 0]. We can call the method **Xmmatrixlookatlh ()** very handy to calculate a visual matrix by using the upward vector [0 1 0], because we want the y direction to remain consistent upward. Finally, in order to produce a projection transformation array, we call **Xmmatrixperspectivefovlh ()**, with a degree vertical field of view (PI/2), 640/480 screen aspect ratio, The z-axis values are 0.1 and 110, which means that any object that is closer than 0.1 to 110 is not displayed on the screen. This is the three array stored in the global G_world, G_view, G_projection.

Updating the constant cache

With matrices, it is necessary to write them to a constant data buffer when rendering, so that the GPU can read them. In order to update the cache, we can call **id3d11devicecontext::updatesubresource () **api and pass the location of the matrix store to the function in the same order as the shader constant buffer. To do this, we will create a structure that has the same layout as the constant buffers in the shader. Also, because the matrices are arranged differently in memory in C + + and HLSL, we have to transpose them before updating them.

We have the matrices, and now We must write them to the constant buffer when rendering so, the GPU C An read them. To update the buffer, we can use the Id3d11devicecontext::updatesubresource () API and pass it a pointer to the matrices St ORed in the same order as the shader ' s constant buffer. To help does this, we'll create a structure that have the same layout as the constant buffer in the shader. Also, because matrices is arranged differently in memory in C + + and HLSL, we must transpose the matrices before updating them.

`// // Update variables // ConstantBuffer cb; cb.= XMMatrixTranspose( g_World ); cb.= XMMatrixTranspose( g_View ); cb.= XMMatrixTranspose( g_Projection ); g_pImmediateContext->0NULL&00 );`

Direct3D 11 Fourth Section 3D Spaces