Graphics Pipeline

summary

现在我们要进行图形管线并且看清楚它的每个工作步骤。着色器和特效系统都会进行解释。

本例的代码和上一例是完全一样的。但是会强调不同的知识面。

 

The Graphics Pipeline

在上一节中,我们建立了顶点缓冲,然后绑定了一个顶点布局和一个technique对象。现在,我们将解释这个technique对象和组成它的着色器。为了完整的理解分开的着色器,我们要回头去看看整个图形管线。

图形管线包含了很多在数据渲染前对它进行处理的步骤。表示为着色器的步骤可以包含用户代码,并在数据通过时对它进行操作。下图就展示了管线的流程图,并且每个步骤都有解释。

在例2中,当我们用technique调用Apply()的时候,我们实际上把我们的着色器绑定到了管线上的一个过程。然后,当我们调用Draw(),就开始处理传入管线的顶点数据。

 

Input Assembler Stage:这个步骤用来向管线输送数据(三角形,线,点)

VertexShader Stage:顶点着色器阶段使用一个顶点着色器来处理顶点,比如矩阵转换、蒙皮、照明等。一个顶点着色器通常输入一个顶点,并输出一个顶点。

Geometry Shader Stage:几何体着色器使用一个几何着色器来处理图元。和顶点着色器不同的是,几何体着色器输入一个基本图元(确切的说是三个顶点的三角形,两个顶点的线,或一个顶点)。另外,每个图元都包含了与它邻接的图元的信息。对一个三角形来说这可能包含至多三个额外的顶点信息,对线来说最多两个额外顶点信息,对点来说最多一个。

Stream Output Stage:这一阶段是设计来让流数据在进入光栅处理过程前从渲染管线传到内存中的。数据可以流入或流出到下一阶段,数据流出到内存可以进入缓冲,是为了可以循环的让它作为输入数据进入渲染管线。

Rasterizer Stage:光栅化阶段用来剪切图元,为像素着色器准备图元,并决定如何调用像素着色器。

Pixel Shader Stage:像素着色器阶段是对每个像素处理或每个图元处理的,并产生逐像素的数据,如颜色。像素数据可以理解为静态数据或通过像素间插值。

OutputMerger Stage:输出合并阶段是用来混合各种输出数据(渲染目标,深度,模板信息)来产生最终显示的数据

 

 

Shaders

d3d10中,着色器固定在图形管线的不同阶段。它们其实是简短的程序,由GPU执行,获取确定的输入数据,处理数据,然后输出结果到下一个阶段。d3d10支持3种类型的着色器:顶点着色器,几何体着色器,像素着色器。一个顶点着色器以一个顶点作为输入,它对每个通过顶点缓冲输入GPU的顶点都运行一次。几何体着色器以一个基本图元作为输入,并对每个输入到GPU的基本图元都运算一次。像素着色器以一个像素(有时称为fragment碎片)作为输入,并对我们想要渲染的基本图元的每个像素孝运算一次。它们三个就是最重要的动作发生的地方。当在d3d10中进行渲染时,GPU必须有一个有效的顶点着色器和一个像素着色器。几何体着色器是一个可选的特性,所以暂时不会讨论。

 

 

顶点着色器:

顶点着色器都是一些由GPU在顶点上执行的短程序,可以理解为C语言中的函数,以每个顶点作为输入,经过运算,输出处理过的顶点。在应用程序把顶点缓冲数据传送给GPU的之后,GPU就迭代缓冲中的顶点,并在每个顶点上执行被激活的顶点着色器。顶点着色器可以用来执行很多任务,其中最重要的就是顶点转换,即把顶点从一个坐标系转换到另一个坐标系的过程。比如,一个三角形的三个顶点坐标是(0,0,0)100)(010)。当这个三角形在一个2D材质缓冲中绘制时,GPU必须知道这些顶点要绘制的2D坐标。正是顶点转换帮我们实现这个过程的。转换会在下一节中详细讲解。对本例来说,我们将使用一个简单的顶点缓冲,简单到只是把输入的顶点再作为转出。

d3d10教学中,我们用HLSL来写着色器,应用程序会通过特效系统来使用这些着色器。前面提过我们顶点有3个顶点分量,而本例的顶点着色器不会对它们做任何处理。它简单到像下面这样:

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

这个顶点着色器看起来就像个C函数。HLSL使用类似C语言的语法。这个顶点着色器的名字是VS,输入一个float4类型的参数,并输出一个float4值。在HLSL中,float4表示一个由4float分量组成的向量。冒号定义了它前面的数据的语义。前面提到过,HLSL中的语义描述了数据的性质。我们选择POSITION作为输入参数的语义因为它会包含顶点坐标,而返回值的语义是SV_POSITION,是一个提前定义好的有特殊意义的语义。这个语义告诉图形渲染管线,该语义绑定的数据表示剪切空间坐标(clip-space position)。这个坐标在GPU在屏幕上绘制像素时需要。(下一节会讨论剪切空间)。

 

像素着色器

现在的电脑显示器基本上都是光栅显示器,就是说屏幕实际上是一个由像素点组成的二维网格。每个像素都可以用它自己的颜色照亮,与其他像素无关。当我们在屏幕上渲染一个三角形时,我们并不会把三角形作为一个整体来渲染。实际上,我们渲染被这个三角形覆盖的区域下的像素。

 

 

把由三个顶点定义的三角形转换成被它覆盖的一堆像素的过程就称为光栅化。GPU会首先决定哪些像素是被这个三角形覆盖的。然后,它为其中的每个像素调用当前激活的像素着色器。一个像素着色器的基本上的就是计算每个像素的颜色。为了绘制一个像素,着色器会先输入一些关于该像素的信息,然后计算像素颜色,然后把颜色输出到渲染管线。它的输入实际上来自几何体着色器,如果当前没有激活的几何着色器,就直接来自顶点着色器。

我们创建的顶点着色器输出一个类型为float4,语义为SV_POSITION的值。这就会是像素着色器的输入。由于像素着色器输出颜色值,所以我们的像素着色器的输出值是float4,语义是SV_TARGET,意思是渲染目标格式。像素着色器如下:

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

 

特效系统:

我们的特效文件由上面两个着色器和technique声明构成。technique声明会设置对应的着色器。另外,还有用于编译着色器的语义。注意几何体着色器置为NULL,因为现在不需要它。

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

 

创建特效和特效technique

在本应用程序中,我们要创建特效实例。该实例将代表我们的特效文件,通过D3D10CreateEffectFromFile()来创建。一旦创建完成,我们就可以调用ID3D10Effect::GetTechniqueByName()方法,输入”Render”作为名字,来获得我们要使用的technique。代码如下:

    // 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" );

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值