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). 

参见

外部链接