DirectXの12の3Dゲームの開発と実際の内容章V

レンダリングパイプライン

学習目標:

  1. そのような重要な要因の2D画像の奥行きとして宇宙のシーンの三次元感覚の真の効果を示すことを学びます
  2. Direct3Dので3Dオブジェクトを表現する方法を発見
  3. 仮想カメラを作成する方法を学びます
  4. 2D画像処理を生成する三次元シーン記述の所定の幾何学的形状に従って、レンダリング・パイプラインが理解

5.1 3Dの視覚的な錯覚?

1は、目視観察の観点から、平行線は最終的に(また、消失点として知られている点を、消失)点で交差するので、我々はそれを結論付けることができる:増加深さ(z方向)で、オブジェクトは、より多くの表示されます小さな、(DXは左利きされ、OpenGLは右手座標系です)。

2、我々は物体の重なりが、それは即ち、不透明なオブジェクトが部分的または完全に、シーン内の物体の異なる深さの順序との関係を伝えるオブジェクトの背面側を遮断することができる、重要な概念であることを知っています

図3に示すように、3Dオブジェクトの特徴付け及び三次元立体形状の光と影プレイの処理が重要な役割であり、シェーディングクマ光源とに対するシーン内のオブジェクトの相対位置を意味し、二つの重要なタスク何かのおおよその位置。

モデルの5.2表現

実際には、三角形を近似する三角形メッシュを用いて物理的な3Dオブジェクトは、3Dオブジェクトモデリングの基礎となるものです、我々は実世界の3Dオブジェクトをシミュレートするために、任意の三角形メッシュを使用することができます。もちろん、点や線も不可欠であり、例えば、我々は、曲線近似を描く1ピクセル幅のラインのシリーズを使用することができます。

ゲーム開発の過程で、我々は一般的に、一般的に、最も単純なモデルを除き、当社のモデルのほとんどは、3Dモデリングツール(3Dであるので、疲れて、3Dオブジェクトをシミュレートするために、独自のリストの手の三角形をしないでください)完成。3D Studioのマックス、LightWaveの3D、マヤ、ソフトイマージとブレンダー:ゲーム開発のモデリングソフトウェアで人気。

5.3コンピュータベースカラー

観察者の眼の中へ混合光、網膜の特定領域に照射されたときに各カラー画素は、赤、緑、青の発光するコンピュータディスプレイは、光を混合し、コーンは視神経及び転送を介して神経インパルスの産生を刺激するために対象となります脳にして、知覚される色の送信信号を解釈します。なぜなら混合光の変化に刺激された細胞は、同じではないので、異なっているので、我々は、異なる色の違いを認識することができるであろう

発行可能な各ディスプレイの赤、緑、青の強度は、光強度の説明の便宜のために、それは強度を表すない間隔0-1、0で正規化された値の範囲、通常、量子化WE、制限され、1最高強度の代表的なので、我々は(R、G、B)の色を表現するために3次元ベクトルを使用することができ、これらの3つの成分の強度は、混合光における赤、緑、青の光を表します

5.3.1色の操作

わずかに

5.3.2 128色

実際に、我々は、通常、それは混合技術における意志(0.0は完全に透明であり、1.0は完全に不透明である)色の不透明度のアルファ成分を表すために使用されるアルファ成分(成分アルファ)であると呼ばれる一つの色成分を使用します重要な役割を果たしています。コンポーネントを追加した後、我々は、各色を表現するために、4Dベクトル(R、G、B、A)を使用することができ

色を表現するために128ビットのデータを使用するように、各成分は浮動小数点値でなければなりません。各色は4Dベクトルを示すために使用することができるので、我々は、次にカラーDriectXMathベクトル関数を計算することによって、それらに記載されたコードXMVECTIRタイプを使用することができます。だから我々は、データの処理速度を加速するためにSIMD技術を利用することができます。

5.3.3 32ビットカラー

オクテット256を占める各色成分がない強度を表すない異なる色強度(0に分けて説明することができるように32ビットのデータとの色を表現するために、各コンポーネントは、バイトを行うために256の担当者に割り当てることができそう4色成分の合計が、第4の色255を生成することができる最強の強度)は、32ビットカラーDirectXMathライブラリに格納されているXMCOLOR構造が設けられています。

それであれば、ベクターの32ビットの色成分値の各AS / 255は、対応する色ベクトル128を得ることができ、128色と32ビットの色と交換することができます。XMCOLORは、典型的には、4つの8ビットの色成分は、このように32ビットおよび128ビットの色の間で変換する32ビット整数値(unsigned int型の等値)にパッケージ化するので、通常、いくつかの追加操作の色でありますこの点で、DirectXMathライブラリは、タイプXMVECTORのXMCOLORの値を取得する機能を提供し、型の対応するインスタンスを返します。

XMVECTOR XM_CALLONV PackedVector::XMLoadColor(const XMCOLOR* pSource);

また、DirectXMathライブラリはまた、タイプ値はXMVECTOR XMCOLORタイプの値に変換することができる提供します。

void XM_CALLCONV PackedVector::XMStoreColor(XMCOLOR pDestination, FXMVECTOR V);

一般に、ピクセルシェーダに配置各種演算などの高精度なカラー操作で使用128色。しかし、色が最終的バックバッファに記憶されているが、通常、32ビットカラーです。

レンダリングパイプラインの5.4の概要

一連のステップを説明3Dシーンジオメトリの2D画像を与え、このカメラは、視野角のために生成されたレンダリングパイプライン、そこに仮想カメラの決定された位置および向きに配置した場合:レンダリングパイプライン

マップ上のファースト:

携帯電話は写真を撮るために、希望は私を許して(出典:DirectXの12の3Dゲーム開発の戦闘)

レンダリングパイプラインのすべてのステージの左側上の図は、右は位相がリソースを読み取ることができ、リソースは、レンダリングパイプラインから入力されてもよいことを示すメモリリソース、レンダリングパイプラインステージを指し、ターゲットメモリプール矢印からリソースで表します矢印は、メモリ・プールはステージがGPUリソ​​ースにデータを書き込むことができることを示しているリソースを指します。次は、詳細は、レンダリングパイプラインの各ステージになります。私たちが見てきたように、ステージのほとんどを動作させることができるリソースを読んで、彼らはGPUリソ​​ースに書き込むことができるだけで数段の前に。(データパイプラインを各ステージの出力をレンダリングすることは、多くの場合、次のステージの入力です)

  1. 入力アセンブラ相(メモリリソースを読み取り、幾何プリミティブに組み立てから、リソース)
  2. 頂点シェーダステージ(プロセスプリミティブ組み立てられた頂点データ)
  3. 船体シェーダステージ(省略)
  4. テッセレーションステージ(三角形メッシュの数を増加させる、任意の位相段階)
  5. ドメインシェーダステージ(省略)
  6. ジオメトリシェーダステージ(その後の再導入し、この段階は任意の位相です)
  7. ストリーム出力段(わずかに)
  8. ラスタ化段階(算出された画素の色の三角形に相当)
  9. (色を追加する画素毎に(即ち、頂点の補間計算結果ラスタライズステージ属性))ピクセルシェーダステージ
  10. 結合された出力段(ピクセルフラグメントをスクリーニングし、次いでバックピクセルフラグメントバッファに書き込ま)

5.5入力組立段階

入力アセンブラは、メモリからジオメトリデータ(頂点及びインデックス(頂点及びインデックス))を読み出し、その後、幾何学的プリミティブにそれらを組み立てます。これらの概念は、我々は後述していきます

5.5.1頂点

数学的には、三角形の頂点が2つの辺の交点であり、頂点線は、頂点自体は単一の点のために、その2つのエンドポイントであります

在Direct3D中,顶点不仅可以用来表示位置信息,还可以包含其他的信息。例如:我们将在第八章为顶点添加法向量依次来实现光照效果,在第九章中我们会为顶点添加纹理坐标从而实现纹理贴图。Direct3D为用户自定义顶点格式提供了很高的灵活性,在第六章我们会讲解一些和顶点有关的代码

5.5.2 图元拓扑

在Direct3D中,我们要通过一种名为顶点缓冲区的特殊数据结构来将顶点和渲染流水安绑定在一起,顶点缓冲区利用连续的内存来存储一系列顶点,但是仅凭顶点缓冲区是无法说明这些顶点将如何组成几何图元,因此我们需要指定图元拓扑(primitive topology)来告知Direct3D要以何种方式来表示几何图元。

void ID3D12GraphicsCommandList::IASetPrimitiveTopology{
D3D_PRIMITIVE_TOPOLOGY PrimitiveTopology
};

typedef enum D3D_PRIMITIVE_TOPOLOGY {
    D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0,
    D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1,
    D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2,
    D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3,
    D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 4,
    D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5,
    D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10,
    D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11,
    D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 12,
    D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 13,
    .
    .
    .
    D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64,
}D3D_PRIMITIVE_TOPOLOGY;

在用户通过命令列表修改图元拓扑之前,所有的绘制调用都会沿用当前设置的图元拓扑,下面将举一个通过命令列表对图元拓扑进行修改的代码示例:

//通过三角形列表的方式来绘制对象
mCommandList->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

5.2.2.1 点列表

通过枚举项D3D_PRIMITIVE_TOPOLOGY_POINTLIST来指定点列表,当使用该图元拓扑时,所有的顶点都将在绘制过程中绘制成一个单独的点

5.2.2.2 线条带

通过枚举项D3D_PRIMITIVE_TOPOLOGY_LINESTRIP来指定线条带,当使用该图元拓扑时,顶点将会在绘制调用的过程中被绘制成一系列连续的线段,所以在这种模式下,n + 1个顶点就会生成n条线段

5.2.2.3 线列表

通过枚举项D3D_PRIMITIVE_TOPOLOGY_LINELIST来指定线列表,当使用该图元拓扑时,顶点在绘制调用时会被绘制成一系列单独的线段,所以在这种模式下,2n个顶点就会生成n条线段

5.2.2.4 三角形带

通过枚举项D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP来指定三角形带,当使用该图元拓扑时,顶点在绘制调用时会被绘制成一系列连续的三角形,所以在这种模式下,n个顶点可以生成n - 2个三角形(三角形带的绕序为为顺时针方向)

5.2.2.5 三角形列表

通过枚举项D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST来指定三角形列表,当使用该图元拓扑时,顶点在绘制调用时会被绘制成一系列独立的三角形,所以在这种模式下,3n个顶点就会生成n个三角形

5.2.2.6 具有邻接数据的图元拓扑

5.2.2.7 控制点面片列表

D3D_PRIMITIVE_TOPOLOGY_N_CONTROL_POINT_PATCHLIST拓扑类型表示:将顶点数据解释为具有N个控制点(control point)的面片列表,(此图元常用与渲染流水线的曲面细分阶段,此阶段为可选阶段),这种图元拓扑类型我们将会在第十四章再次进行讨论

5.5.3 索引

在前面我们提到过,三角形是3D实体对象的基本组成部分,所以为三角形指定顶点顺序是十分重要的工作,我们把这个顺序称之为绕序。

构成3D物体的不同三角形之间会共用许多顶点,比如一个四边形,从数学上来看它只有四个顶点,但是在Direct3D中,绘制一个四边形必须要使用两个三角形,即有六个顶点,如果不重复利用顶点数据,那么我们需要创建六个顶点(其中有两个顶点数据是重复的)来绘制一个四边形,这明显不是我们希望看到的结果,所以我们一般都会借助三角形带或者是索引来解决这个问题

三角形带:借助三角形带可以改善顶点数据的重复创建问题,因为三角形带图元拓扑可以使顶点在绘制调用的过程中绘制成一系列连续的三角形。但如果想使用三角形带改善这个问题,前提是这些几何体必须是能够组织成带状的

索引:这是我们推荐的解决方法,整个工作流程是这样的:

  1. 先创建一个顶点列表和索引列表
  2. 在顶点列表中收录一份所有独立的顶点,并在索引列表中存储顶点列表的索引值
  3. 这些索引定义了顶点列表中的顶点是如何组合在一起的,从而构成三角形

通过以上的操作,我们就把“复用的顶点数据”转换为索引列表了,这样便可以对一个顶点数据进行多次调用。

5.6 顶点着色器阶段

待图元被装配完毕之后,其顶点会被送到顶点着色器阶段(vertex shader state),我们可以把顶点着色器看成一种输入数据和输出数据都是单个顶点的函数,每一个要被绘制的顶点都必须要经过顶点着色器的处理之后才可以送往后续阶段。事实上,我们可以认为在硬件中执行的是下列处理操作

for (UINT i = 0; i < numVertices; ++i)
{
    outputVertex[i] = VertexShader(intputVertex[i]);
}

其中的顶点着色器函数(VertexShader)就是我们要实现的部分,由于这个阶段的操作是由GPU完成的,所以一般速度都会很快

在后续的章节中,我们会看到各种不同的顶点着色器示例,所以在学习完本书之后,我们应该要对顶点着色器可以时间的具体功能有一个深刻的认识。接下来,我们将介绍几种常用的空间变换

5.6.1 局部空间和世界空间

设想:如果我们正在拍一部电影,我们所在的团队需要为一些特效镜头打造一个和火车有关的微缩场景,其中我们的具体任务是制作一架袖珍小桥,当然,我们不会把小桥直接搭建在场景之中,否则我们便需要在一个极其复杂的环境中小心翼翼的工作,以防止破坏场景中的其他物体,一旦失手便会功亏一篑,相对来讲,我们更加愿意在远离场景的工作室内制作这个袖珍小桥,等制作完成之后在将它以恰当的角度放在场景中合适的位置

3D美工在工作的时候也和上述设想一样,他们不会直接在世界坐标系(世界空间)中直接构建物体的几何形状,而是选择在相对于局部坐标系(局部空间)来创建物体。只要在局部空间定义了3D模型的各顶点,我们就能将它变换到世界空间中,为了做到这一点,我们必须要定义局部空间和世界空间两者之间的联系。具体的做法是:根据物体的位置和朝向,指定其局部空间坐标系的原点和每个坐标轴相对于世界坐标系的坐标,再运用坐标变换即可将物体从局部空间转换到世界空间了。将局部坐标系内的坐标转换到世界坐标系中的过程称为世界变换,所使用的矩阵称为世界矩阵,由于场景中,每一个物体的朝向和位置都可以各不相同,因此它们都会有属于自己特定的世界矩阵。

在每一个3D模型各自的局部坐标系中的优点如下:
1、易于使用,在局部坐标系中定义物体可以很轻松的确定各个顶点的坐标

2、物体应该要可以跨越多个场景重复使用,如果将物体坐标相对于某一个特定场景进行硬编码则会多出很多麻烦

3、我们有时候需要在同一场景中绘制多个同一物体,但是它们的位置、方向和大小不一样,将物体绘制在局部空间可以解决这个问题。(我们通常将存储一份几何体相对于其局部空间的副本,接着按需求次数来绘制该物体,并使用不同的世界矩阵来指定物体在世界空间中的位置、大小和方向,这种方法称为实例化)

一般来说,为了构建一个世界矩阵,我们必须要弄清局部空间中原点和各坐标轴相对于世界空间的坐标关系,但实际上,获取这个关系并不容易而且也不直观,所以我们一般采用一种更直观的方式:定义一系列的变换组合W,即W = SRT;

S:缩放矩阵,将物体缩放到世界空间

R:旋转矩阵,用来定义物体在局部空间相对于世界空间的朝向

T:平移矩阵,定义的是物体在局部空间相对于世界空间的位置

通过定义一系列的变换组合W,便可以在不指明局部空间的原点以及各坐标轴相对于世界空间的齐次坐标的情况下,直接通过复合一系列简单的变换来建立世界矩阵

5.6.2 观察空间

为了构建场景的2D图像,我们必须在场景中架设一台虚拟摄像机,该摄像机确定了观察者可以见到的视野,也就是生成2D图像所需要的场景空间范围,所以我们要为该摄像机赋予一个局部坐标系,该坐标系称为观察坐标系,也称为观察空间。虚拟摄像机会位于观察坐标系的原点,并且朝z轴的正方向进行观察,y轴位于摄像机的上方,x轴位于摄像机的右侧(dx使用左手坐标系,OpenGL使用右手坐标系)。观察空间用于在渲染流水线后续阶段描述这些顶点相对于观察坐标系的位置,由世界空间到观察空间的坐标变换称之为观察变换(视图变换),所使用的矩阵称为观察矩阵

假设矩阵w为物体从观察空间转换到世界空间的变换矩阵,则从观察空间转换到世界空间的变换矩阵V = W的逆矩阵。

接下来我们将介绍一种构建观察矩阵的直观方法:

假设Q为摄像机的位置,T为被观察的目标点的坐标,j表示世界空间y轴方向的单位向量,则

观察坐标系的z轴方向的单位向量w为:(T - Q) / ||T - Q||

观察坐标系的x轴方向的单位向量u为:(j x w) / ||j x w||

观察坐标系的y轴方向的单位向量v为:w x v

综上所述,只有给定摄像机的位置,观察目标点以及世界空间中y轴方向的向量,就可以构建出该世界空间对应的观察空间的观察矩阵,DirectXMath库针对上述计算观察矩阵的方法提过了一个函数:

//输出对应的观察矩阵
XMMATRIX XM_CALLCONV XMMatrixLookAtLH(
    FXMVECTOR EyePosition,              //输入虚拟摄像机的位置
    FXMVECTOR ForcusPosition,           //输入观察目标点的位置
    FXMVECTOR UpDriecttion              //输入世界空间向上方向的向量
)

5.6.3 投影和齐次裁剪空间

前一节我们介绍了摄像机在世界空间的位置和朝向,除此之外,虚拟摄像机还有一个重要的组成要素,那就是摄像机可以观测到的空间体积(volume of space),此范围可以用一个由四棱锥截取的平截头体(四棱台)表示。所以我们的下一个任务便是将平截头体内的3D几何体投影到2D投影窗口中,根据前文的透视投影的原理可知,投影必定会随着众平行线汇聚于消失点,其投影的尺寸也将会随着物体3D深度的增加而变小。

图片为手机拍摄,望见谅(图片来源:DirectX 12 3D 游戏开发实战)

5.6.3.1定义平截头体

在观察空间中,我们可以通过近平面n(near plane)、元平面f(far plane)、垂直视场角a(vertical field of view Angle)以及投影窗口的纵横比r这四个参数来定义一个以原点为中心,并且沿z轴正方向进行观察的平截头体。接下来我们将介绍这四个参数的意义:

图片为手机拍摄,望见谅(图片来源:DirectX 12 3D 游戏开发实战)

1、近平面n:如图

2、远平面f:如图

3、垂直视场角a:如图

4、投影窗口的纵横比r:投影窗口实际是就是观察空间中场景的2D图像,由于该图像最终将会被映射到后台缓冲区中,因此,我们希望投影窗口和后台缓冲区两者的纵横比保持一致,所以我们通常把投影窗口的纵横比指定为后台缓冲区的纵横比。假如后台缓冲区的大小为800 x 600,则投影窗口的纵横比为800 / 600。

下面还有很多内容:略

5.6.3.2 投影顶点

5.6.3.3 规格化设备坐标

5.6.3.4用矩阵来表示投影公式

5.6.3.5 归一化深度值

XMMatrixPerspectiveFovLH函数

我们可以利用DirectXMath库里的XMMatrixPerSpectiveFovLH函数构建对应的投影矩阵

//构建投影矩阵
XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovLH(
    float FovAngleY,            //用弧度制表示的垂直视场角
    float Aspect,               //投影窗口的纵横比(一般都与后台缓冲区的纵横比相等)
    float NearZ,                //虚拟摄像机的位置(观察点)到近平面的距离
    float FarZ                  //虚拟摄像机的位置(观察点)到远平面的距离
);

下面的代码片段为XMMatrixPerspectiveFovLH函数构建一个对应垂直视场角为45度,近平面位于z = 1.0f,远平面位于z = 1000.0f的平截头体的投影矩阵的用法:

XMMATRIX p = XMMatrixPerspectiveFovLH(0.25*XM_PI, AspectRatio(), 1.0f, 1000.0f);

纵横比采用的是我们窗口的宽高比:

float D3DApp::AspectRatio()const
{
    return static_cast<float>(mClientWidth / mClientHeight);
}

5.7 曲面细分阶段

曲面细分阶段(tessellation stage)是利用镶嵌化处理技术对网格中的三角形进行细分,以此来增加物体表面的三角形数量。然后将这些三角形偏移到合适的位置,就可以使网格展现出更加细腻的细节。使用曲面细分的优点主要有以下几方面:

  1. 借此实现一种细节层次机制。我们可以使距离虚拟摄像机较近的三角形进行镶嵌化处理,距离虚拟摄像机较远的三角形则不进行处理
  2. 我们可以在内存中仅维护低模(低精度模型)网格,再根据需求为它动态添加三角形,以此节省内存资源
  3. 我们在处理动画和物理模拟的时候可以使用简单的低模网格,而仅在渲染的过程中使用经镶嵌化处理的高模网格

曲面细分是一个可选的渲染阶段,我们将在第十四章对此阶段进行详细的讲解。

5.8几何着色器阶段

几何着色器阶段是一个可选的渲染阶段,由于我们在第十二章才会用到它,所以我们这里只对它进行简单的介绍。

  1. 几何着色器接受的输入必须是完整的图元,假设我们正在绘制三角形列表,那么向几何着色器输入的一定是定义三角形的三个顶点(这三个顶点已经被顶点着色器处理过的)
  2. 几何着色器的主要优点是可以销毁和创建几何体,比如说,我们可以利用几何着色器将输入的图元扩展称为一个或多个图元,或者是根据一些条件而选择不输出任何图元
  3. 顶点着色器与几何着色器相比,顶点着色器不能创建顶点,它只能接受单个顶点的输入,然后将处理后的单个顶点输出。几何着色器的拿手好戏是将一个点或者一条线扩展成一个四边形

5.9 裁剪

完全位于视椎体(用户在3D空间内的可视范围,形状类似于平截头体,视椎体也被称为视平截头体)之外的几何体需要被完全抛弃,而处于视平截头体交界的几何体也要接受此裁剪的操作。因此,只有在视平截头体之内的物体对象才会被完全保留下来。

由于裁剪操作是由硬件负责完成的,我们在这里并不会进行过多的讲解,如果对裁剪过程有兴趣的话,可以了解一下苏泽兰-霍启曼裁剪算法,这个算法的整体思路是找到平面和多边形的所有交点,然后将这些顶点按顺序组织成新的裁剪多边形。

5.10 光栅化阶段

光栅化阶段(rasterization stage)的主要任务是为投影到主屏幕上的3D三角形计算出相应的像素颜色

5.10.1 视口变换

当裁剪操作完成之后,硬件会通过透视除法将物体从齐次裁剪空间变换到规格化设备坐标(NDC),一旦物体的顶点位于NDC空间之内,构成2D图像的2D顶点x,y坐标就会被变换到后台缓冲区中称为视口的矩形之中,此变换完成会后,这些x,y坐标都会以像素为单位进行表示。(一般来说,由于z坐标经常在深度缓冲技术里面用作为深度值,所以视口变换一般都不会影响到z坐标)

背面剔除

每一个三角形都有两个面,在Direct3D中会采用以下约定对这两个面进行区分,假设组成三角形顺序的顶点为v1,v2,v3,那么我们会通过以下计算来得到这个三角形的法线:

e1 = v2 - v1;

e2 = v3 - v1;

n = (e1 x e2) / (||e1 x e2||)

法向量由正面射出,则另一面为三角形的背面。在这种约定之下,根据观察者的视角看过去,顶点绕序为顺时针方向的为正面朝向,顶点绕序为逆时针方向的位背面朝向。由于背面朝向的三角形都会被正面朝向的三角形遮挡,所以绘制背面朝向的三角形是没有意义的,背面剔除就是用于将背面朝向的三角形从渲染流水线中剔除的流程,这种操作可以将待处理的三角形数量减少一半。

在默认的情况下,Direct3D将以观察者的视角把顺时针绕序的三角形看作是正面朝向的,把逆时针绕序的三角形视为是背面朝向的,但是,通过对Direct3D渲染状态的设置,我们也可以把这个约定颠倒过来。

5.10.3 顶点属性插值

回顾前文可知,我们要通过顶点来定义三角形,除了位置信息之外,我们还可以给顶点附加颜色、法向量、纹理坐标、深度值等其他属性,经过视口变换之后,我们需要为求取三角形内每一个像素所附的属性进行线性插值运算,为了得到屏幕空间中各个顶点的属性插值,我们一般都会使用一种名为透视校正插值。从本质上来说,插值法即利用三角形的三个顶点属性值计算出其内部像素的属性值

我们无需考虑透视校正插值法处理像素属性的数学细节,因为硬件会自动的完成相应的处理,如果有人对其中的数学细节感兴趣。可以在[Eberly01]中找到相应的数学推导过程

5.11 像素着色器阶段

我们编写的像素着色器(pixel shader)是一种由GPU执行的程序,他会针对每一个像素片段进行处理(即每处理一个像素都要执行一次像素种着色器),并根据顶点的插值属性作为输入来计算出对应的像素颜色。像素着色器既可以返回一种单一的恒定颜色,也可以实现如逐像素光照、反射以及阴影等更为复杂的效果。

5.12 输出合并阶段

通过像素着色器生成的像素片段会被移送至渲染流水线的输出合并阶段,在此阶段,一些像素片段可能会被丢弃(比如未通过深度测试或模板测试的像素片段)。而没有被丢弃的像素片段则会被写入后台缓冲区。

混合操作也是在输出合并阶段完成的,这项技术可以使当前处理的像素片段与后台缓冲区中原有的像素片段进行融合,而不是简单的对后台缓冲区进行覆盖。

小结

  1. 根据人们的生活经验,我们可以总结一些规律用于Direct3D中:平行线会相聚于消失点、物体的尺寸受其深度的影响(近大远小)、离观察者近的物体会遮挡其后距观察者远的物体、光照和阴影的明暗对比可以刻画出3D物体的实体形状和体积感、阴影还暗示了光源的位置以及场景中不同物体之间的相对位置
  2. 我们用三角形网格来近似的表示3D物体对象,并通过指定三角形的3个顶点来定义三角形,在许多网格中都存在着顶点被不同三角形共用的情况,而索引列表则可以用于避免因为重复使用顶点而复制顶点数据所带来的亢余信息
  3. 我们一般通过红绿蓝三色光的强度来描述颜色,利用三色光不同强度的相加混色,可以表示出数以千万计种颜色。一般来说我们还会加入一种名为Alpha分量的颜色分量,这个分量用于表示颜色的不透明度,这在混合技术中是很有用的。综上,我们可以使用4D颜色向量来表示四个颜色分量。
  4. 假设在一个场景中有一台虚拟摄像机,那么渲染流水线就是根据该虚拟摄像机的视角,生成能呈现在显示器中对应的2D图像的一系列完整的步骤
  5. 渲染流水线可以分为8个重要阶段,分别是:输入装配阶段、顶点着色器阶段、曲面细分阶段、几何着色器阶段、裁剪阶段、光栅化阶段、像素着色器阶段、输出合并阶段。

おすすめ

転載: www.cnblogs.com/yaya12138/p/11574202.html