天天看點

Tutorial 3: Shaders and Effect System(Directx手冊)Summary(總結)The Graphics Pipeline(圖形管道)Shaders(着色器)Effect System()Putting It Together

Tutorial 3: Shaders and Effect System(Directx手冊)Summary(總結)The Graphics Pipeline(圖形管道)Shaders(着色器)Effect System()Putting It Together

Summary(總結)

In the previous tutorial, we setup a vertex buffer and passed one triangle to the GPU. Now, we will actually step through the graphics pipeline and look at how each stage works. The concept of shaders and the effect system will be explained.

Note that this tutorial shares the same source code as the previous one, but will emphasize a different section.

在先前的教程中, 我們建立了頂點緩存并把一個三角形傳給GPU.現在我們将會真正的建立圖形管道和看看各階段的如果工作.着色器和效果系統的觀念将會被解釋.

注意該教程中着色器的代碼和先前的代碼是一樣的.但是會強調不同的部分

Source(源程式)

(SDK root)\Samples\C++\Direct3D10\Tutorials\Tutorial03

Navigation(導航)

  • The Graphics Pipeline
  • Shaders
  • Effect System
  • Putting It Together

The Graphics Pipeline(圖形管道)

In the previous tutorial, we setup the vertex buffer, and then we associated a vertex layout with a technique object. Now, we will explain the technique object and the shaders that compose it. To fully understand the individual shaders, we will take a step back and look at the whole graphical pipeline.

In Tutorial 2, when we called Apply from the technique, we actually bound our shader to a stage in the pipeline. Then, when we called Draw, we start processing the vertex data passed into the graphics pipeline. The following sections describe in detail what happens after the Draw command.

在前面的教程中,我們建立了頂點緩存,然後我們用technique對象關聯頂點布局.現在我們将解釋technique對象和着色器,為了更好的了解着色器,我們回到整個圖形管道.

在教程2中, 當我們從technique中調用應用時, 我們其實限制我們的着色器在管道中.然後我們調用繪制函數,我們開始通過圖形管道處理頂點資料.接下來的部分描述繪制指令後的細節.

Shaders(着色器)

In Direct3D 10, shaders reside in different stages of the graphics pipeline. They are short programs that, executed by the GPU, take certain input data, process that data, and then output the result to the next stage of the pipeline. Direct3D 10 supports 3 types of shaders: vertex shader, geometry shader, and pixel shader. A vertex shader takes a vertex as input. It is run once for every vertex passed to the GPU via vertex buffers. A geometry shader takes a primitive as input, and is run once for every primitive passed to the GPU. A primitive is a point, a line, or a triangle. A pixel shader takes a pixel (or sometimes called a fragment) as input, and is run once for each pixel of a primitive that we wish to render. Together, vertex, geometry, and pixel shaders are where the meat of the action occurs. When rendering with Direct3D 10, the GPU must have a valid vertex shader and pixel shader. Geometry shader is an advanced feature in Direct3D 10 and is optional, so we will not discuss geometry shaders in this tutorial.

在Directx3D 10 中,着色器處于圖形管道的不同階段.他們是短小的程式,被GPU解釋,帶進某些輸入資料, 處理這些資料,并且輸出結果到下一階段的管道,Directx3D 10 支援3種着色器:頂點着色器,幾何着色器,像素着色器.頂點着色器把頂點作為輸入,它為每個經過GPU頂點緩存中的頂點執行一次, 幾何着色器把元件作為輸入,他為每個經過GPU的元件執行一次.一個元件是一個點,一條線,或者是一個三角形,像素着色器把像素(有時叫做片段)作為輸入,他為每個經過GPU的像素執行一次.當渲染Direct3D 10時,GPU必須有一個有效的頂點着色器和像素着色器.在Direct3D中幾何着色器是進階特性并且是可選的,是以在這章中我們不讨論幾何着色器.

Vertex Shaders(頂點着色器)

Vertex shaders are short programs that are executed by the GPU on vertices. Think of vertex shaders as C the active vertex shader once for each vertex, passing the vertex's datafunctions that take each vertex as input, process the input, and then output the modified vertex. After the application passes vertex data to the GPU in the form of a vertex buffer, the GPU iterates through the vertices in the vertex buffer, and executes  to the vertex shader as input parameters.

While a vertex shader can be used to carry out many tasks, the most important job of a vertex shader is transformation. Transformation is the process of converting vectors from one coordinate system to another. For example, a triangle in a 3D scene may have its vertices at the positions (0, 0, 0) (1, 0, 0) (0, 1, 0). When the triangle is drawn on a 2D texture buffer, the GPU has to know the 2D coordinates of the points on the buffer that the vertices should be drawn at. It is transformation that helps us accomplish this. Transformation will be discussed in detail in the next tutorial. For this tutorial, we will be using a simple vertex shader that does nothing except passing the input data through as output.

In the Direct3D 10 tutorials, we will write our shaders in High-Level Shading Language (HLSL), and the applications will use these shaders with the effect system. Recall that our vertex data has a 3D position element, and the vertex shader will do no processing on the input at all. The resulting vertex shader looks like the following:

頂點着色器是短小的程式,被GPU解釋.把頂點着色器想成C,通過頂點的函數把每個頂點當成輸入,處理輸入,然後輸出修改後的頂點.在應用程式從頂點緩存中傳遞頂點資料給GPU後,GPU重複通過把頂點緩存中的頂點當作頂點着色器的輸入參數.

一個頂點着色器能被執行很多任務,最重要的工作是轉換.就是頂點在坐标系統中轉變為另一個的過程,一個三角形在3D場景中可能在(0, 0, 0) (1, 0, 0) (0, 1, 0)上有頂點.當三角形被繪制在2D紋理緩存中時,GPU必須知道該點所畫的2D坐标.這樣才能幫助我們完成轉變,轉換将會在下章詳細讨論.這章中,我們使用簡單的頂點着色器,該着色器除了輸出輸入的資料外不做任何事.

在Direct3D 10 教程中, 我們将會寫我們自己的着色器使用進階着色器語言(HLSL),然後這些應用程式将會使用這些帶着效果系統的着色器.回憶我們頂點資料包含了3D元素,并且頂點着色器不會處理輸入.最後的頂點着色器像下面這樣.

float4 VS( float4 Pos : POSITION ) : SV_POSITION
    {
        return Pos;
    }
      

This vertex shader looks a lot like a C function. HLSL uses C-like syntax to make learning easier for C/C++ programmers. We can see that this vertex shader, named VS, takes a parameter of float4 type and returns a float4 value. In HLSL, a float4 is a 4-component vector where each component is a floating-point number. The colons define the semantics of the parameter as well as the return value. As mentioned above, the semantics in HLSL describe the nature of the data. In our shader above, we choose POSITION as the semantics of the Pos input parameter because this parameter will contain the vertex position. The return value's semantics, SV_POSITION, is a pre-defined semantics with special meaning. This semantics tells the graphics pipeline that the data associated with the semantics defines the clip-space position. This position is needed by the GPU in order to drawn pixels on the screen. (We will discuss clip-space in the next tutorial.) In our shader, we take the input position data and output the exact same data back to the pipeline.

這個着色器像C函數一樣,HLSL使用C風格的文法來更容易的學習C/C++程式.我們看到這個頂點着色器,名為VS,使用float4類型的參數,傳回float4類型的值.在HLSL中,一個float4是一個4部分組成的頂點,每一部分是一個float頂點數..............

Pixel Shaders(像素着色器)

Modern computer monitors are commonly raster display, which means the screen is actually a two-dimensional grid of small dots called pixels. Each pixel contains a color independent of other pixels. When we render a triangle on the screen, we don't really render a triangle as one entity. Rather, we light up the group of pixels that are covered by the triangle's area. Figure 2 shows an illustration of this.

Tutorial 3: Shaders and Effect System(Directx手冊)Summary(總結)The Graphics Pipeline(圖形管道)Shaders(着色器)Effect System()Putting It Together

Figure 2. Left: What we would like to draw. Right: What is actually on the screen.

The process of converting a triangle defined by three vertices to a bunch of pixels covered by the triangle is called rasterization. The GPU first determines what pixels are covered by the triangle being rendered. Then it invokes the active pixel shader for each of these pixels. A pixel shader's primary purpose is to compute the color that each pixel should have. The shader takes certain input about the pixel being colored, computes the pixel's color, then outputs that color back to the pipeline. The input that it takes comes from the active geometry shader, or, if a geometry shader is not present, such as the case in this tutorial, the input comes directly from the vertex shader.(像素着色器的輸入來自頂點着色器)

The vertex shader we created above outputs a float4 with the semantics SV_POSITION. This will be the input of our pixel shader. Since pixel shaders output color values, the output of our pixel shader will be a float4. We give the output the semantics SV_TARGET to signify outputting to the render target format. The pixel shader looks like the following:

float4 PS( float4 Pos : SV_POSITION ) : SV_Target
    {
        return float4( 1.0f, 1.0f, 0.0f, 1.0f );    // Yellow, with Alpha = 1
    }
      

Effect System()

Our effect file consists of the two shaders, vertex shader and pixel shader, and the technique definition. The technique definition will set the corresponding shaders to each section. In addition, there is also the semantic to compile the shader. Note that the geometry shader is left NULL because it's not required and will be covered later.

// Technique Definition
    technique10 Render
    {
        pass P0
        {
            SetVertexShader( CompileShader( vs_4_0, VS() ) );
            SetGeometryShader( NULL );
            SetPixelShader( CompileShader( ps_4_0, PS() ) );
        }
    }
      

Creating the Effect and Effect Technique

In the application code, we will need to create an effect object. This effect object represents our effect file, and is created by calling D3D10CreateEffectFromFile(). Once we have created the effect object, we can call the ID3D10Effect::GetTechniqueByName() method, passing in "Render" as the name, to obtain the technique object that we will be using to do the actual rendering. The code is demonstrated below:

// Create the effect
    if( FAILED( D3DX10CreateEffectFromFile( L"Tutorial03.fx", NULL, NULL, D3D10_SHADER_ENABLE_STRICTNESS, 0, g_pd3dDevice, NULL, NULL, &g_pEffect, NULL ) ) )
        return FALSE;

    // Obtain the technique
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
      

Putting It Together

After walking through the graphics pipeline, we can start to understand the process of rendering the triangle we created at the beginning of Tutorial 2. Creating Direct3D applications requires two distinct steps. The first would be creating the source data in vertex data, as we've done in Tutorial 2; the second stage would be to create the shaders which would transform that data for rendering, which we showed in this Tutorial.

繼續閱讀