DirectX绘制流水线

使用DirectX可以让在Windows平台上运行的游戏或多媒体程序获得更高的执行效率,掌握DirectX的基本概念和技术是虚拟现实技术、计算机仿真和3D游戏程序开发的基础。

DirectX概述

DirectX是微软的一个多媒体应用编程接口(API)工具包,用于为Windows操作系统开发交互式软件。
DirectX主要包含两方面:

  1. DirectX软件开发包(DirectX Software Development Kit,DirectX SDK):一整套开发Windows应用程序所需的相关文件、范例和工具的工具包
  2. DirectX Runtime:一组动态链接库,用于开发和运行DirectX应用程序。

DirectX中的API可以按照功能性质分为以下4个部分:

  1. 显示部分:Direct Graphics负责图形处理,也称为Direct3D,包含DirectDraw和Direct3D。
    1. DirectDraw主要负责2D图像加速。
    2. Direct3D主要负责3D效果的显示。
  2. 输入部分:DirectInput接口对象可以处理游戏用户输入事件的快速响应,支持多种游戏设备的输入。DirectInput提供了大量接口函数处理游戏杆以及鼠标、键盘和力反馈游戏控制器等其他相关设备的输入,由于其直接与硬件驱动程序打交道,因此可较快地处理用户的输入。
  3. 声音部分:DirectAudio是声音处理的主要API,包括DirectSound和DirectMusic两部分。
    1. DirectSound可实现多个声音的混合播放,并提供3D声效和录音功能。
    2. DirectMusic组件用来处理数字音频,.wav文件或其他音频资源可以由DirectMusic加载器加载。
  4. 网络部分:DirectPlay支持具有网络功能的游戏开发,提供了多种连接方式,如TCP/IP、IPX、MODEM和串口等,玩家可以用各种联网方式进行对战,也提供网络对话功能及保密措施。

应用程序、Direct3D以及硬件间的关系

在这里插入图片描述应用程序调用Direct3D(D3D)方法,D3D方法通过HAL层指示设备完成某些操作,最终实现对设备的操作。
显卡品种具有丰富的多样性,为了让D3D能够始终按照统一的规范进行编程,因此各设备制造商将产品支持的功能写入HAL层中,供Direct3D 调用。HAL是Direct3D和图形设备之间的中间环节硬件抽象层(Hardware Abstraction Layer,HAL),封装了指示设备完成某些操作的代码。

DirectX的发展史

DirectX的第1个版本发布于1995年,最早是作为openGL的替代品被加入windows操作系统中。
1996年,DirectX2.0发布,并提供了其标志性产品Direct draw。1997年,Direct3.0和3D加速卡开始出现。
2001年,微软发布了DirectX 8.0,首次引入“像素渲染”概念,还提供Pixel Shader(像素渲染)引擎和 Vertex Shader(顶点渲染)引擎,可实现动态光影效果。而此时 OpenGL的功能改进十分有限,逐渐落后于图形硬件的发展。
2004年OpenGL版本更新,改善了其功能,但随着 DirectX 的不断发展和完善,OpenGL的优势逐渐丧失。
2005年,微软发布Windows Vista 系统,Vista内置 DirectX 10,而且向下兼容,显卡的画质和速度有了革命性的提升,所有的显卡GPU管线被赋予更加完善的 Shader 功能运算。
2009年,微软发布Windows 7,DirectX11作为DirectX 10的加强版集成在其中。DirectX 11拥有Tessellation(拆嵌式细分曲面技术)、Multi-Threading(多线程)、DirectCompute(通用计算)、Shader Model5.0(渲染引擎5.0)以及 Texture Compression(纹理压缩)5个重要特性。

Direct3D基础知识

左手坐标系

Direct3D默认使用左手坐标系,左手手背朝自己,手掌向上竖直。坐标系中的 +x 轴 朝向为左手大拇指的指向, +z 轴 朝向从手心穿进, +y 轴 朝向为四指朝向。如图所示,+z方向指向屏幕里,+y方向竖直向上,+x方向向右。

顶点缓存与索引缓存

顶点缓存是包含顶点数据的连续内存空间。索引缓存是包含索引数据的连续内存空间。顶点缓存和索引缓存可以被放置在显存或内存中。绘制时,使用显存中的数据比使用内存中的数据要快得多。

深度缓存

深度缓存算法是由Catmull在1975年提出的,基本思想是对当前点(x,y)保持到目前为止遇到的最小z值,以求出具有最小z值的点。
深度缓存是一个后台缓存,缓存中只存储场景深度信息,而不包含图像数据的表面信息。绘制图元时,将图元的深度信息和深度缓存中的内容加以比较,如果深度信息小于深度缓存中的内容(该图元更靠近视点),就更新深度缓存和颜色缓存的内容;如果深度信息大于深度缓存,则该像素不可见,直接抛弃。
深度缓存通过对每一个图元给予一个深度值的方式,来判断哪些图元被遮住。

模型表示

Direct3D的图形绘制是通过一个称作 Direct3D 渲染流水线的过程来完成的。在整个绘制过程中,首先提供描述三维物体模型的顶点数据及其他的场景元素,然后经过Direct3D渲染流水线的处理,最终得到能够显示在屏幕上的像素。

图元

所有的物体模型都是通过多边形网格逼近表示,这些多边形网格是构成物体模型的基本单元,可以是三角形或四边形,通常选用的几何图形种类是三角形。通常这些构成物体模型的三角形为三角形图元,此外还有点图元。
Direct3D在描述三角形图元时,需要指定三角形单元的3个顶点的列表,该列表包含顶点的位置以及其他一些信息(如颜色等)。在描述由三角形图元构成的物体时,需要指定构成该物体的三角形图元列表。
![[Pasted image 20231013144557.png|750]]

FVF灵活顶点格式

顶点结构定义好之后,需要用FVF(灵活顶点格式,Flexible Vertex Format)来描述在顶点缓冲区的顶点存储格式中包含哪些属性。灵活顶点格式的作用是,使应用程序只使用它需要的顶点数据,排除那些它不需要的组成成分。通过D3DFVF的组合,可以描述图元顶点的格式。
顶点格式指定:

![[Pasted image 20231013153543.png|700]]
顶点格式指定的顺序要求:
![[Pasted image 20231013153624.png|700]]

三角形图元

三角形图元是构成3D物体的基本组成部分,在 Direct3D中,所有物体均可以由三角形逼近拟合来构成。
一个完整的模型通常是由多个三角形图元构成的三角形网格,需要使用三角形图元列表来存储。每个三角形图元由3个顶点构成。
如图所示,一个正方形共有6个顶点,需要两个三角形图元来构成,顶点列表为Vertex vertexList[6].(v0,v1,v2,v3,v4,v5),其中有两个顶点重复。当物体形状复杂、描述物体用到的三角形数目非常大时,重复的顶点会占用大量的存储空间,造成资源浪费。为防止这种情况发生,引入了[[#顶点索引列表]]。
三角形顶点的指定顺序称为绕序(Winding Order)。Direct3D 中规定:

  1. 顶点排列顺序为顺时针的三角形单元是朝向正面的。
  2. 顶点排列顺序为逆时针的三角形单元是朝向背面的。

顶点索引列表

顶点索引链表是为了避免共用顶点数较多时,重复顶点的储存占用大量的储存空间。顶点的索引在三维形体绘制中尤为重要,索引列表决定了三角形单元的构成与朝向。
首先为需要绘制的图形建立顶点列表,再建立一个指向该顶点列表的索引列表,这些索引规定了三角形单元的顶点组织方式,当Direct3D绘制图形时,会根据这些索引结构创建三角形列表,并进一步构建三角形网络。
以左图的五边形网格体为例,其顶点结构、和索引链表如右图。
![[Pasted image 20231013220804.png|inl|209]]![[Pasted image 20231013220748.png|inl|675]]

Direct3D绘制流水线

在 Direct3D中,在屏幕上绘制任何物体都要通过一系列变换的流水线,Direct3D绘制流水线主要包括变换和照明(T&L阶段)、光栅化处理两个阶段:

  1. 变换和照明阶段:将每个对象的顶点从局部坐标系变换到基于像素的屏幕坐标系,并考虑虚拟摄像机的属性。另外还可以对顶点应用照明、裁剪、视口缩放等效果。从原始模型顶点数据到添加了照明效果的顶点数据的处理过程如下图所示,图中的非T&L顶点就是原始模型顶点数据。

![[Pasted image 20231013223546.png|525]]

  1. 光栅化处理阶段:将这些经过转化并添加了照明效果的顶点组织为点、线和三角形,由光栅化处理程序将绘制结果显示在屏幕上,同时应用纹理映射并添加多种属性。光栅化处理程序同时决定深度缓冲的结果,判断哪些像素是用户可见的,哪些被其他像素所遮挡。

局部坐标系

局部坐标系描述了模型的方向及构成物体的元素(点、三角形、子模型)相对于物体中心的位置。在创建模型时,模型各顶点的坐标是相对于局部坐标系描述的,当模型旋转或移动时,与该模型相关联的局部坐标系将随之旋转或移动。

世界坐标系

将模型放置在要绘制的场景中,整个场景的坐标系就是世界坐标系,场景中的每个模型的坐标系就是自己独立的局部坐标系。场景中的所有模型都必须从自己的局部坐标系变换到世界坐标系中,用以定义场景中模型之间的空间相对关系。场景中光源的坐标使用世界坐标系定义。
对于一个在场景中不断运动的模型,就需要为该模型定义一个随时间变化的变化序列,以便在每一帧中确定该模型在世界坐标系中的不同位置。
将位于局部坐标系中的物体变换到世界坐标系中,需要通过世界变换运算。该变换通常包括平移、旋转和比例缩放,分别用于设置物体在世界坐标系中的位置、方向和大小。

平移矩阵

设某点P坐标值为(x,y,z),将该点向x轴方向移动dx,向y轴方向移动 dy,向z轴方向移动 dz,变换后P’点坐标值为(x’,y’,z’),则有x’=x+dx;y’=y+dy;z’=z+dz。将点的平移以矩阵表示:

![[Pasted image 20231013225250.png|450]]

旋转矩阵

将旋转矩阵传给 Direct3D,经过坐标转换后就可以看到模型旋转效果。Direct3D提供了D3DXMatrixRotationXD3DXMatrixRotationYD3DXMatrixRotationZ函数来计算模型绕x、y和z三个坐标轴旋转的矩阵。

绕z轴旋转

模型绕z轴旋转时,z坐标值不会发生变化,仅有x和y坐标值发生变化。等同于在z=0平面上绕原点的旋转变换。设空间中任意一点 P(x,y,z)z 轴旋转 θ角,变为P'(x',y',z'),如下图所示:
![[Pasted image 20231014214646.png|400]]在这里插入图片描述

![[Pasted image 20231014192500.png|550]]

绕x轴旋转

模型绕x轴旋转时,x坐标值不会发生变化,仅有y和z坐标值发生变化。设空间中任意一点 P(x,y,z)x 轴旋转 θ角,变为P'(x',y',z'),有:
![![[Pasted image 20231014194310.png|475]](https://img-blog.csdnimg.cn/7c41f99c75504e6aa36a2f27e5af8ae7.png)

绕y轴旋转

模型绕y轴旋转时,y坐标值不会发生变化,仅有x和z坐标值发生变化。设空间中任意一点 P(x,y,z)y 轴旋转 θ角,变为P'(x',y',z'),有:

在这里插入图片描述

缩放矩阵

设某点P坐标值为(x,y,z),在x、y、z轴方向扩大S倍后,变换后P'点坐标值为(x',y',z'),则有x'=S*x,y'=S*y,z'=S*z,则用矩阵表示如下:

在这里插入图片描述

观察坐标系

观察坐标系(或相机坐标系)指定了从何种方向和位置对三维空间中的物体展开观察,以及摄像机的屏幕可视区域。通常情况下,观察坐标系指定了摄像机(观察视角)的位置,从而能够将三维空间中的物体投影到屏幕可视区域的二维平面中。
当摄像机旋转时,为了简化运算将进行取景变换(view space transformation),设置摄像机的视线方向与世界坐标系z轴的正方向一致,同时将世界坐标系中的所有几何体都随着摄像机一同进行旋转,来保持摄像机视场的恒定。变换后的几何体被称为“位于观察坐标系中的几何体”。

![[Pasted image 20231014201330.png|475]]

消隐

消隐的目的是剔除那些处于屏幕背面或物体内部的面,具体哪些面需要隐藏与观察位置有密切关系,即相对于观察位置,前面的面可见、背面或被其他面遮挡的面则不可见。
早期的面消隐算法是深度排序法,这种方法是把屏幕设成背景色,再把各个面按照离视点的远近进行排序,按照由远到近的顺序逐层绘制。
现在常用的消隐算法是z-缓冲算法,z-缓冲算法对显示设备上每一个像素进行判断,对每一个像素检查所有的三角形面,判断其在该像素上是否可见。z-缓冲算法使用更新缓冲存储器存储屏幕上所有点的像素值,使用Z缓冲存储器存储屏幕上所有点的z值。
每当有一个新的图元被转换到屏幕坐标系中,在开始着色之前,GPU会计算新像素到摄像机之间的距离,并与已经存储在z-缓冲存储器中的z值进行比较。如果新的像素离摄像机更近,就把旧的像素替换掉,把新的深度值记入z-缓冲存储器,把新像素的颜色值记入更新缓冲存储器。
在消隐阶段,还会对图元的朝向进行判断。

光照

光源定义在世界坐标系中,变换到观察坐标系中进行计算。

裁剪

裁剪就是将视域外的几何体剔除掉的过程,Direct3D 的裁剪过程被包含在投影过程中,在定义投影变换矩阵的同时,定义取景体的范围,Direct3D通过裁剪过称剔除位于取景体外的物体模型部分,并将剩下的三维场景投影到一个二维平面上。

投影

投影,是把n维空间中的点投射到小于n维的空间中的变换过程。把摄像机观察到的三维景象显示在二维的平面上,这种三维到二维的变换就是投影变换。正交投影和透视投影是两种常见的投影变换:

  1. 在正交投影中,投影向量与观察平面垂直,模型坐标沿观察坐标系的z轴平行投影到观察平面上,观察点和观察平面的距离不影响物体的大小。正交投影在现实世界中是不存在的,在现实世界中,越远的物体看起来会越小。正交投影主要应用于工程制图,通常所说的三视图就是用三种常见的正交投影(正视投影、顶视投影和侧视投影)得到的。
  2. 在透视投影中,三维物体在二维空间中呈现出近大远小的特征,符合人眼的视觉投影规律。

视口变换

视口变换(viewport transform)是空间变换的最后一步,视口变换就是通过定义屏幕显示区域的实际宽、高等参数,将顶点从投影坐标转换为以像素为单位的屏幕坐标,最终完成从投影窗口到屏幕中某一区域的变换,这一区域也被称为视口。
在游戏中,视口通常是整个屏幕,但视口也可以是屏幕上的某一块矩形区域。视口与其所在的窗口相关,并且通过所在窗口的相对坐标来进行描述。

![[Pasted image 20231014212225.png|300]]

其中X、Y表示视口矩形相对于屏幕的位置,Width、Height表示视口区域的大小,MinZ、MaxZ表示深度缓存中的最小深度值和最大深度值,深度范围设置在[0,1]区间内。
虚拟摄像机的可见视域模型如下图所示,可见视域外的物体都是不可见的。视椎体的主要参数包括视角的水平范围、垂直范围、投影窗口和远、近裁剪面。其中,投影窗口是一个二维区域,位于视域体中的三维几何体通过投影映射到该区域中,从而实现三维物体的二维显示。在 Direct3D中,将投影平面定义为平面z=1。

![[Pasted image 20231014213228.png|475]]

渲染

渲染也称光栅化,渲染的目的是计算每个三角形图元像素的颜色值,并最终绘制三角形图元,渲染的最终结果是显示在屏幕上的2D图像。光栅化的本质是矢量图像素化的过程,或者说是将连续的图像用像素点阵来表示,并显示在屏幕上的过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/106316.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EfficientDet: Scalable and Efficient Object Detection

CVPR2020 V7 Mon, 27 Jul 2020 引用量:243 机构:Google 贡献:1>提出了多尺度融合网络BiFPN 2>对backbone、feature network、box/class prediction network and resolution进行复合放缩,有着不同的…

在 VSCode 中使用 PlantUML

最近,因为工作需要绘制一些逻辑图,我自己现在使用的是 PlantUML 或者 mermaid,相比之下前者更加强大。不过它的环境也麻烦一些,mermaid 在一些软件上已经内置了。但是 PlantUML 一般需要自己本地安装或者使用远程服务器&#xff0…

Unity中Shader不同灯光类型的支持与区分

文章目录 前言一、在开始之前做一些准备1、在上一篇文章的场景基础上,增加一个Unity默认的球体作为对照组2、创建一个点光源,用来看点光源的影响 对 Unity默认的Shader效果 和 我们实现的Shader效果 之间的不同 二、点光源的适配把上一篇文章中 ForwardB…

R语言的计量经济学实践技术应用

计量经济学通常使用较小样本,但这种区别日渐模糊,机器学习在经济学领域、特别是经济学与其它学科的交叉领域表现日益突出,R语言是用于统计建模的主流计算机语言,在本次培训中,我们将从实际应用出发,重点从数…

【arm实验2】按键中断事件控制实验

设置按键中断,按键1按下,LED亮,再次按下,灭 按键2按下,蜂鸣器叫,再次按下,停 按键3按下,风扇转,再次按下,停 主函数: linuxlinux:~/study/08-c$…

【基础篇】四、本地部署Flink

文章目录 1、本地独立部署会话模式的Flink2、本地独立部署会话模式的Flink集群3、向Flink集群提交作业4、Standalone方式部署单作业模式5、Standalone方式部署应用模式的Flink Flink的常见三种部署方式: 独立部署(Standalone部署)基于K8S部署…

使用Tortoisegit界面拉起master主分支以副分支以及命令行操作

文章目录 1、Gui操作界面2、命令行操作3、合并分支到master分支上面 1、Gui操作界面 "小乌龟"通常指的是Git的图形用户界面(GUI)工具,其中比较常见的是TortoiseGit。下面是使用TortoiseGit来拉取(checkout)一…

数据结构(一)—— 数据结构简介

文章目录 一、基本概念和术语?1.1、数据1.2、数据元素1.3、数据项(属性、字段)1.4、数据对象1.5、数据结构 二、逻辑结构和物理结构(存储结构)2.1、逻辑结构1、定义2、分类(线性结构和非线性结构&#xff0…

Netty 入门 — 亘古不变的Hello World

这篇文章我们正式开始学习 Netty,在入门之前我们还是需要了解什么是 Netty。 什么是 Netty 为什么很多人都推崇 Java boy 去研究 Netty?Netty 这么高大上,它到底是何方神圣? 用官方的话说:Netty 是一款异步的、基于事…

vue绑定style和class 对象写法

适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。 绑定 class 样式【对象写法】: .box{width: 100px;height: 100px; } .aqua{background-color: aqua; } .border{border: 20px solid red; } .radius{bor…

【动态库】Ubuntu 添加动态库的搜索路径

在运行程序时,经常遇到下面这种动态库加载失败的情况,这时往往是系统在动态库的搜索路径下没有找到对应的库文件导致的。 目录 一、使用 LD_LIBRARY_PATH 二、修改 /etc/ld.so.conf 一、使用 LD_LIBRARY_PATH 环境变量 LD_LIBRARY_PATH是动态库的搜索…

Jenkins集成newman

一、Docker环境准备 二、Jenkins环境准备 三、登录Jenkins 安装NodeJs插件 四、Jenkins全局工具配置Nodejs 五、创建Jenkins自由风格项目 构建步骤1:选择Execute NodeJS script构建步骤2:选择执行shell脚本 六、将postman相关的脚本、环境变量数据、全局…

Java反射调用jar包

反射作为托管语言的特性,很多框架都依赖反射来实现容器和面向接口编程,对架构程序很重要,首先试验Java的反射部分。 首先创建一个ZLZJar的工程,让他打包成jar包,代码如下 public class Test {//加两个整数public int…

ELK 日志分析系统介绍与部署

目录 一、ELK 简介: 1.开源工具介绍: 2.其它组件: 2.1 Filebeat: 2.2 Fluentd: 2.3 缓存/消息队列(redis、kafka、RabbitMQ等): 3. filebeat 结合 logstash 带来好处: 二、为什么要…

[0xGameCTF 2023] web题解

文章目录 [Week 1]signinbaby_phphello_httprepo_leakping [Week 2]ez_sqli方法一&#xff08;十六进制绕过&#xff09;方法二&#xff08;字符串拼接&#xff09; ez_upload [Week 1] signin 打开题目&#xff0c;查看下js代码 在main.js里找到flag baby_php <?php /…

云安全——云计算基础

0x00 前言 学习云安全&#xff0c;那么必然要对云计算相关的内容进行学习和了解&#xff0c;所以云安全会分为两个部分来进行&#xff0c;首先是云计算先关的内容。 0x01 云计算 广泛传播 云计算最早大范围传播是2006年&#xff0c;8月&#xff0c;在圣何塞【1】举办的SES&a…

【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;vue要做权限管理该怎么做…

【Java 进阶篇】JavaScript电灯开关案例:从原理到实现

JavaScript是一门强大的编程语言&#xff0c;它可以用来创建各种交互式网页应用。在这篇博客中&#xff0c;我们将通过一个简单的电灯开关案例来深入了解JavaScript的基础概念&#xff0c;包括HTML、CSS和JavaScript的结合使用。我们将从头开始构建这个案例&#xff0c;逐步引入…

PYTHON进阶-面向对象编程

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

windows计划任务的配置文件

界面操作 创建计划 依次设置 命令行操作 SCHTASKS 命令简介 SCHTASKS 命令是由微软公司开发并内置于 Windows 系统中的一个命令行工具。该命令可用于设置、修改、查询和删除计划任务&#xff0c;或启动计划任务中所定义的程序或脚本。 SCHTASKS 命令的基本语法 SCHTASKS 命…