Direct3D

微软DirectX中用于3D渲染的API

Direct3D(简称:D3D)是微软公司在Microsoft Windows作业系统上所开发的一套3D绘图编程介面,是DirectX的一部份,目前广为各家显示卡所支援。与OpenGL同为电脑绘图软体和电脑游戏最常使用的两套绘图编程介面之一。

1995年2月,微软收购了英国的Rendermorphics公司,将RealityLab 2.0技术发展成Direct3D标准,并整合到Microsoft Windows中,Direct3D在DirectX 3.0开始出现。后来在DirectX 8.0发表时与DirectDraw编程介面合并并改名为DirectX Graphics

架构

 
抽象层

Direct3D与Windows GDI是同层级组件。Direct3D装置有二种不同的操作模式:windowed和exclusive。在windowed模式下,必须使用back buffer。在Exclusive模式下,Direct3D直接呼叫显示卡驱动程式,而不通过GDI。

Direct3D的抽象概念包括:devices, swap chains和resources。

有4种device type,D3DDEVTYPE定义了设备类型。

  • HAL(hardware abstraction layer):使硬体加速。
  • reference:应用程序请求一个reference设备。
  • null reference:当系统没有装SDK,但是应用程序请求一个reference设备的时候,它就返回一个null reference。
  • 可插拔的软件(Pluggable software);设备通过RegisterDevice设备方法提供。
 
Device

每一个装置至少要有一个swap chain.一个swap chain可用来产生一个或多个back buffer surfaces。渲染目标(render target)也是back buffer surface。back buffer是属于渲染(render)的部份。所有的back buffer都是合理的render target,但是并非所有render target都是back buffer。surface是一种资源,包含一个矩形集合的像素数据,如color, alpha, depth/stencil。

资源有4个属性:

  • Type:资源的类型,如顶点缓冲区(vexert buffer),或一个渲染目标(render target)。
  • Usage:资源的用途,如纹理(texture)或渲染目标,是一系统的旗标所组成,每个旗标占1 bits。
  • Format:资料的格式,如一个二维表面的像素格式。例如,D3DFMT_R8G8B8的值是一个24 bits的颜色深度(colour depth,8 bits是红色,8 bits绿色以及8 bits是蓝色)。
  • Pool[1]:资源所分配的内部记忆体空间类型。

管道

 
Graphics pipeline process

Direct3D 10 API定义了vertices(顶点), textures(纹理), buffers(缓冲区),以及state群组转换到萤幕上的流程。这样的流程被描述成rendering pipeline(渲染流水线),其中有著许多不同的阶段. Direct3D 10 渲染流水线的各阶段包括:[2] are:[3]

  1. 输入组装(Input Assembler):从程式里读取顶点,并将程式提供的数据装进流水线。
  2. 顶点著色引擎Vertex Shader): 每次处理一个顶点,比如变换、贴图、光照。
  3. 几何著色器Geometry Shader): Shader Model 4.0引进了几何著色器,使用Shader资源来处理点、线、面的几何坐标变换,一次最多处理六个点,快速地将模型类似的顶点结合起来进行运算。此一过程无需CPU参与。
  4. 流输出(Stream Output):将Vertex Shader和Pixel Shader处理完成的数据输出给使用者。
  5. 光栅化(Rasterizer): 把算完的顶点转成像素,再将像素(pixels)输出给pixel shader. 这里亦可执行其他工作,像是切割非视觉性的像素,或者对顶点进行插值以得到像素数据。
  6. 像素著色引擎Pixel Shader):决定最后要往渲染目标(render targe)写入的像素颜色,同时也可以计算一个准备写到深度缓冲区的深度值。
  7. 输出混合(Output Merger):接收来自于pixel shader的slice,进行传统的Stencil测试和Depth测试,整并各种不同的输出资料,用以建立最后之结果。

显示模式

Direct3D有两种display modes:

  • 全萤幕模式(Fullscreen mode):全萤幕是指画面全部被Direct3D所占据,不会再显示其他的视窗画面。目前市面上发展的游戏软体多采用此模式。
  • 视窗模式(Windowed mode):视窗模式是指可以有多个视窗同时出现在萤幕上。

历史

1992年,Servan Keondjian开创RenderMorphics公司,成立了一个Reality Lab实验室,专事3D图形技术及API技术研究。有两种版本的API被释出。1995年2月微软买下RenderMorphics,由Keondjian在Windows 95上开发3D图形引擎,主持Direct3D项目的开发。

Window 95推出之时,微软一口气发表了DirectX 1.0DirectX 2.0DirectX 3.0。DirectX 1.0推出时,只包括DirectDrawDirectPlayDirectInputDirectSound四部分,DirectX 2.0内附了Direct 3D,但功能有限,无法与OpenGL3dfx等API函数相提并论。1996年9月发布的Direct 3.0被认为是DirectX的第一套完整版本。不久,DirectX 3.0更新3.0a、3.0b,版号从4.04.00.0068增加到了“4.04.00.0069”,仅是附加了一个被称为Direct3D的组件,这正是Keondjian的杰作。当时的Direct3D有两种模式,一是Retain模式,另一个是Immediate模式,皆以COM建构而成。1996年Westwood工作室发布以DirectX开发的即时战略游戏《红色警戒》,大卖1200万套。

DirectX 4.0并未推出就有DirectX 5.0。1997年6月推出DirectX 5.0,加入DrawPrimitive API,加入了对MMX的支援,不久微软又推出支援D3D加速卡的DirectX 5.0a版和5.1版、5.2版。

Direct3D 6.0,1998年秋微软推出,引进多重贴图(multitxture)以及stencil buffer

Direct3D 7.0引进硬体座标转换以及光影计算(Hardware Transform and Lighting),并支援.dds档[4]

Direct3D 8.0引进了可编程管道(Programable Function Pipeline)的概念,Direct3D在8.0版以前只能工作在固定管道(Fixed Function Pipe-line)的模式下。2001年微软正式发表的Direct3D 8.0支援处理顶点的Vertex Shader,以及处理像素的Pixel Shader。使Direct3D的技术正式超越劲敌OpenGL。DirectX 8中的著色器是用低阶著色器语言(Low Level Shading Language)编写的。

Direct3D 9.0使用HLSL(全称High Level Shading Language)编写Vertex Shader和Pixel Shader[5],有助于著色器的编写和所产生程式码的效率,并且大幅地缩短设计时间。Windows Vista推出DirectX的两种新类型:Direct3D 9Ex和Direct3D 10。Direct3D 9Ex是DirectX 9的扩充版,除了Direct3D 9外,还增加了Windows Vista driver部分新功能的应用程序而设计。Direct3D 9Ex和Direct3D 10均构建于WDDM之上。只有透过WDDM才能在Vista上使用Direct3D。

Direct3D 10

Direct3D 10相对Direct3D 9大量代码重新编写,Direct3D 10著眼在高阶绘图程式,所有render都要写shader。但本质上功能并没有太大改变,只能算是对旧XP时代的问题重新更正,提供更高的可程式化及资源运用,以适合Vista使用。

Direct3D 10新特色:

  • 全新的graphics pipeline:
    • fixed pipeline皆改成programmable的shader,
    • 增加geometry shader、stream out,
    • culling、cliping、blending等stage合为output merger stage
  • 新的resource type: constant buffer、texture array。Texture array可容许最多512个Texture。
  • resource引进view的概念
  • guaranteed feature set
  • GPU呈现多工(multitasking)

Direct3D 10.1

Direct3D 10.1是Direct3D 10.0的小型的更新,2007年8月微软释出Direct3D 10.1以及Shader Model 4.1的测试版本。Direct3D 10.1规定几个更多图像质量标准为图表供营商,给予开发商对图像质量(image quality)的更多控制[6][7]XAudio 2 将取代DirectSound,成为最新的跨平台音频API。

Direct3D 11

Direct3D 11架构于Direct3D 10的基础之上,但相较于Direct3D 10只支援Vista作业系统, Direct3D 11更可以支援Windows 7Windows Vista。Direct3D 11新增以下的功能:

其他还有物件导向化的Shader Model 5等功能。之前DirectX 10还是单执行绪,档案存取与绘图指令共用同一个执行绪,容易造成画面迟缓的现象,与DirectX 10相比,Direct3D 11有了更好的解决方案。

DirectX 11的pipeline新增Hull Shader、Tessellator、Domain Shader来实现tessellation, 可以快速让成像3D的小三角型快速增加。至于Computer Shader则是GPGPU的实现,以GPU的平行处理能力与浮点运算能力来实现CPU的运算,能够同时支援ATI以及Nvidia的显示卡,不受绘图流程的限制。DirectX11还支持Intel的支持Ray Tracing(光线跟踪)与Rasterization(光栅化)技术,使3D效果更真实,更加逼真。

以Direct3D开发3D图形程序,可以采用COM inteface,也可以采用.NET Framework的方式,WPF会使用Direct3D 9与GPU。Direct3D 11技术是DX10.1的超集,支援DX11.0、DX10.1/10.0、DX9.3/9.2/9.1等。

Windows 7 Desktop Windows Manager将会支持Direct3D 10.1 API。可将显卡带宽的占用率降低大约50%。DirectX 11可向下相容于DirectX 10的显示卡,同时也能够在Windows 7与Vista上执行。

Direct3D 12

Direct3D 与 Windows Vista

Vista 引入了 DirectX 的两种新类型:Direct3D 9Ex 和 Direct3D 10。DirectX 10仅适用于Windows Vista,针对 Windows Vista 进行了全新构建,构建于Vista 显示器驱动程序模型 (WDDM) 之上,并引入新的硬体模式、绘图管线和渲染特性,让开发人员更接近硬体。一些由于游戏需要SM 2.0,Vista 将使用SM 2.0来渲染桌面。

范例

用Direct3D 9画三角形:

 // A 3-vertex polygon definition
 D3DLVERTEX v[3];
 // Vertex established
 v[0]=D3DLVERTEX( D3DVECTOR(0.f, 5.f, 10.f), 0x00FF0000, 0, 0, 0 );
 // Vertex established
 v[1]=D3DLVERTEX( D3DVECTOR(0.f, 5.f, 10.f), 0x0000FF00, 0, 0, 0 );
 // Vertex established
 v[2]=D3DLVERTEX( D3DVECTOR(0.f, 5.f, 10.f), 0x000000FF, 0, 0, 0 );
 // Function call to draw the triangle
 pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, v, 3, 0 );

用Direct3D 11画三角形:

 struct Vertex { float x, y, z; D3DCOLOR color; };
 Vertex triangle[] = {
  { 0.f, 5.f, 10.f, 0x00FF0000 },
  { 0.f, 5.f, 10.f, 0x0000FF00 },
  { 0.f, 5.f, 10.f, 0x000000FF }
 };
 // set Flexible Vertex Format
 pDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE);
 // Draw - UP stands for 'user pointer', that is data
 // that is provided through a pointer and not through buffers
 pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1, triangle, sizeof(Vertex));

注释

  1. ^ Direct3D Resources - Memory pool. [2010-03-22]. (原始内容存档于2008-05-09). 
  2. ^ Direct3D 9.0 pipeline diagram. [2008-11-14]. (原始内容存档于2007-10-31). 
  3. ^ Direct3D 10 pipeline stages. [2008-11-14]. (原始内容存档于2008-04-09). 
  4. ^ Direct3D 7 introduces DirectDraw Surface (.dds) format. [2010-03-22]. (原始内容存档于2010-03-07). 
  5. ^ HLSL in Direct3D 9.0. [2008-11-16]. (原始内容存档于2010-08-27). 
  6. ^ Microsoft Presents DirectX 10.1 Details at SIGGRAPH. 2007-08-07 [2007-08-27]. (原始内容存档于2007-09-09). 
  7. ^ DirectX SDK: Direct3D 10.1 Features. [2011-01-27]. (原始内容存档于2010-01-11). 

参见

外部链接