DirectX12 3D 游戏开发与实战第一章内容
DirectX12 3D 第一章内容
学习目标
1、学习向量在几何学和数学中的表示方法
2、了解向量的运算定义以及它在几何学中的应用
3、熟悉DirectXMath库中与向量有关的类和方法
1.1 向量
向量是一种兼具大小和方向的量,具有这两种的量都称为向量值物理量,在几何学中我们一般用一条有向线段来表示一个向量
1.1.1 向量与坐标系
前提:计算机无法直接处理以几何方法表示的向量,所以需要寻求一种用数学方法来表示向量
在这里我们会引入一种3D空间坐标系,通过平移操作使向量的尾部位于原点,然后我们就可以通过向量头部的坐标来确定该向量了,可以记作 v = (x,y,z),xyz分别为计算机程序中的浮点数。一个向量如果用数学方法表示的话,它对应的坐标总是相对于某一种参考系而言的,因此,在计算机图形学中,我们会用到较多的参考系,因此我们要记录向量在每一种坐标系中的对应坐标,也需要掌握将向量坐标在不同标架之间进行转换
1.1.2 左手坐标系和右手坐标系
左手坐标系:伸出你的左手,使大拇指,食指和中指之间两两垂直,其中大拇指为x轴正方向,食指为y轴正方向,中指为z轴正方向
右手坐标系:同上。
1.1.3 向量的基本运算
简单的向量加减法
1.2 长度和单位向量
前提:向量大小的几何意义是对应有向线段的长度,3D向量的模长可以通过运用两次毕达哥拉斯定理得出,单位向量是指长度为1的向量
向量的规范化:在某些情况下,我们不关心向量的长度,仅用它来表示方向。对此我们希望此向量的长度为1,所以我们可以将向量的每一个分量/该向量的模长。把一个向量的长度变为单位长度便是向量的规范化了。
1.3 点积
点积的定义点积是一种计算结果为标量值的向量乘法运算,因此也称为标量积。点积就是向量之间对应分量的乘积之和。
点积的几何意义:uv = ||u||||v||*cos0(0为两向量的夹角)。
正交投影:p = (vn)n(p,v,n都是向量,其中p为向量v在向量n上的正交投影,n为单位向量)
利用点积进行正交化:略
1.4 叉积
叉积的计算结果和点积不同,叉积的计算结果也是向量。只有3D向量有叉积,2D向量没有叉积。假设向量u和向量v的叉积为w,则w既正交与u,也正交与v。
计算方式:w = u x v = (UyVz-UzVy,-(UxVz-UzVx),UxVy-UyVx)
叉积不符合交换律,但符合反交换律,即u x v = -v x u
利用叉积进行正交化:略
1.5 点
通过一个处于标准位置的向量就能表示出3D空间中的特定位置,这种向量称为位置向量,在这种情况下,向量箭头的位置才是主要特征,方向和大小都无足轻重。
标准位置:向量通过平移使向量的尾部位于原点的向量。即从原点出发的向量
注意点:位置向量和点这两个术语可以互相替代,但是用向量表示点有缺点也有优点
1.6 利用DirectXMath库进行向量运算
前言:DirectXMath库是一款为Direct3D应用程序专门设计的一个3D数学库,它也是Windows SDK的一部分,该数学库可以利用一条SIMD指令对4个32位浮点数或整数进行运算,可以加大的提高效率。
为了使用DirectXMath库,我们要添加头文件
#include <DirectXMath.h>
为了使用一些相关的数据类型,我们要添加头文件
#include <DirectXPackVector.h>
其中DirectXMath文件的代码都存在DirectX的命名空间中,DirectXPackVector文件中的代码都位于DirectX::packVector的命名空间中。
1.6.1 向量类型
DirectXMath中最核心的数据类型就是XMVECTOR,它会被映射到SIMD硬件寄存器中
1、局部变量和全局变量建议使用XMVECTOR数据类型,因为XMVECTOR类型的数据需要按16字节对齐,在局部变量和全局变量中这都会自动实现
2、对于类中的成员,建议使用XMFLOAT2,XMFLOAT3或者XMFLOAT4.
3、在运算之前,建议使用加载函数将XMFLOATn类型转换为XMVECTOR类型(可以加快运算速率)
4、用XMVECOTR实例进行运算
5、通过存储函数将XMVECTOR类型转换为XMFLOATn类型
1.6.2 加载方法和存储方法
加载方法:
XMMATRIX XM_CALLCONV XMLoadFloatn(const XMFLOATn * pSource);
存储方法:
void XM_CALLCONV XMStoreFloatn(XMFLOATn * pDestination,FXMVECTOR V);
1.6.3 参数的传递
为了提高效率,可以将XMVECTOR类型的值作为函数的参数,直接传送到SSR/SSE2寄存器里,而不存在栈中。单数为了使代码更具通用性,不受到平台和编译器的影响,我们将利用FXMVECTOR,GXMVECTOR,HXMVECTOR和CXMVECTOR类型来传递XMVECTOR类型的参数。
1.6.4 常向量
XMVECTOR类型的常量实例应当用XMVECTORF32类型来表示。例如
static const XMVECTORF32 g_vHaifVector ={ 0.5f,0.5f,0.5f,0.5f };
static const XMVECTORF32 g_vZero = { 0.0f,0.0f,0.0f,0.0f };
基本上我们在运用初始化语法的时候就要使用XMVECTORF32类型了
1.6.5 重载运算符
XMVECTOR类型针对向量的加减运算以及标量的乘法运算都提供了对应的重载运算符
1.6.6 杂项
DirectXMath定义了一组觉pi有关的常用数学常量近似值,如:
XM_CONST float XM_PI= 3.141592654f;
XM_CONST float XM_2PI = 6.283185307f;
XM_CONST float XM_1DIVPI= 0.318309886f;
XM_CONST float XM_1DIV2PI = 0.159154943f;
XM_CONST float XM_PIDIV2= 1.570796327f;
XM_CONST float XM_PIDIV4= 0.785398163f;
还有弧度和角度相互转换的内联函数,求两个数之间最大值和最小值的内联函数等等
1.6.7 Setter函数
DirectXMath库提供了下列函数以设置XMVECTOR类型中的数据
//返回0向量
XMVECTOR XM_CALLCONV XMVectorZero();
//返回(1,1,1,1)向量
XMVECTOR XM_CALLCONV XMVectorSplatone();
//返回(x,y,z,w)向量
XMVECTOR XM_CALLCONV XMVectorSet(float x,float y,float z,float w);
//返回(Value,Value,Value,Value)向量
XMVECTOR XM_CALLCONV XMVectorReplicate(float Value);
//返回(Vx,Vx,Vx,Vx)向量
XMVECTOR XM_CALLCONV XMVectorSplatX(FXMVECTOR V);
//返回(Vy,Vy,Vy,Vy)向量
XMVECTOR XM_CALLCONV XMVectorSplatY(FXMVECTOR V);
//返回(Vz,Vz,Vz,Vz)向量
XMVECTOR XM_CALLCONV XMVectorSplatZ(FXMVECTOR V);
1.6.8 向量函数
DriectXMath库提供了一些函数用来执行各种向量运算,比如计算向量的模长,计算模长的平方,叉积,两向量之间的夹角等等,这里不一一列举函数原型。
1.6.9 浮点数误差
在用计算机处理有关向量的工作时,我们应该要了解,比较浮点数时是存在误差的,在计算机中,相等的两个浮点数时有细微的差别的,比如在数学上规范化的向量的模长是1,但是在计算机上,规范化的向量的模长只能是接近1。
小结
1、向量的几何和数学表达方式
向量可以用来模拟同时具有大小和方向的物理量,在几何学上,我们用有向线段来表示向量,对向量进行标准化(将向量平移至尾部与坐标原点重合的位置)之后,我们便可以把向量的
2、向量的运算
加法,减法,标量乘法,求向量的模(长度),规范化向量,点积,叉积
3、XMVECTOR类型
DirectX一般用DirectXMath库中的XMVECTOR类型来描述向量,这样就可以利用SIMD技术进行高效的运算,对于类中的成员来说,要使用XMFLOAT2,XMFLOAT3,XMFLAOT4等等来表示向量。我们可以通过加载方法和存储方法实现XMFLOATn和XMVECTOR之间的相互转换。如果要使用常向量的初始化语法时,要使用XMVECTORF32类型
4、XMVECTOR类型做函数参数注意点(括号后面的数字为函数中对应的第几个参数)
为了提高效率,当XMVECTOR作为参数时,可以将它直接存入SSE/SSE2寄存器中而不是栈上,如果要使代码与平台无关,我们可以使用FXMVECTOR(1-3),GXMVECTOR(4),HXMVECTOR(5-6)和CXMVECTOR(其余)类型来传递XMVECTOR参数
5、一些常用运算符和方法
XMVECTOR类型重载了一些运算符用来实现向量的加法、减法、标量乘法
DirectXMath库还提供了一些便捷的方法用来计算向量的模、,模的平方、两个向量的点积、两个向量的叉积、对向量进行规范化处理。
DirectX12 3D 游戏开发与实战第一章内容的更多相关文章
- DirectX12 3D 游戏开发与实战第九章内容(上)
仅供个人学习使用,请勿转载. 9.纹理贴图 学习目标: 学习如何将局部纹理映射到网格三角形上 探究如何创建和启用纹理 学会如何通过纹理过滤来创建更加平滑的图像 探索如何使用寻址模式来进行多次纹理贴图 ...
- DirectX12 3D 游戏开发与实战第九章内容(下)
仅供个人学习使用,请勿转载.谢谢! 9.纹理贴图 学习目标 学习如何将局部纹理映射到网格三角形中 探究如何创建和启用纹理 学会如何通过纹理过滤来创建更加平滑的图像 探索如何使用寻址模式来进行多次贴图 ...
- DirectX12 3D 游戏开发与实战第二章内容
矩阵代数 学习目标 理解矩阵及其相关运算的定义 探究为何能把向量和矩阵的乘法视为一种线性组合 学习单位矩阵.转置矩阵.行列式以及矩阵的逆等概念 逐步熟悉DirectXMath库中提供的关于矩阵计算的类 ...
- DirectX12 3D 游戏开发与实战第八章内容(下)
DirectX12 3D 游戏开发与实战第八章内容(下) 8.9.材质的实现 下面是材质结构体的部分代码: // 简单的结构体来表示我们所演示的材料 struct Material { // 材质唯一 ...
- DirectX12 3D 游戏开发与实战第八章内容(上)
8.光照 学习目标 对光照和材质的交互有基本的了解 了解局部光照和全局光照的区别 探究如何用数学来描述位于物体表面上某一点的"朝向",以此来确定入射光照射到表面的角度 学习如何正确 ...
- DirectX12 3D 游戏开发与实战第十章内容(上)
仅供个人学习使用,请勿转载.谢谢! 10.混合 本章将研究混合技术,混合技术可以让我们将当前需要光栅化的像素(也称为源像素)和之前已经光栅化到后台缓冲区的像素(也称为目标像素)进行融合.因此,该技术可 ...
- DirectX12 3D 游戏开发与实战第十章内容(下)
仅供个人学习使用,请勿转载.谢谢! 10.混合 本章将研究混合技术,混合技术可以让我们将当前需要光栅化的像素(也称为源像素)和之前已经光栅化到后台缓冲区的像素(也称为目标像素)进行融合.因此,该技术可 ...
- DirectX12 3D 游戏开发与实战第五章内容
渲染流水线 学习目标: 了解用于在2D图像中表现出场景立体感和空间深度感等真实效果的关键因素 探索如何用Direct3D表示3D对象 学习如何建立虚拟摄像机 理解渲染流水线,根据给定的3D场景的几何描 ...
- DirectX12 3D 游戏开发与实战第四章内容(上)
Direct3D的初始化(上) 学习目标 了解Direct3D在3D编程中相对于硬件所扮演的角色 理解组件对象模型COM在Direct3D中的作用 掌握基础的图像学概念,例如2D图像的存储方式,页面翻 ...
随机推荐
- ThinkPHP 跟踪日志设置、默认分组设置
跟踪日志: 做配置 ‘SHOW_PAGE_TRACE’ => true 默认分组: 做配置 ‘MODULE_ALLOW_LIST’ => array(‘Home’,’Admin’)
- Ubuntu下安装php7.1的gd,mysql,pdo_mysql扩展库
执行以下命令 # apt-get install php7.1-gd # apt-get install php7.0-mysql 重新启动 php7.1-fpm(因为我是安装的 Nginx 和 ph ...
- 前端小知识-html5
一.伪类与伪元素 为什么css要引入伪元素和伪类:是为了格式化文档树以外的信息,也就是说,伪类和伪元素是用来修饰不在文档树中的部分 伪类用于当已有元素处于的某个状态时,为其添加对应的样式,这个状态是根 ...
- Django+Vue前后端分离项目的部署
部署静态文件: 静态文件有两种方式 1:通过django路由访问 2:通过nginx直接访问 方式1: 需要在根目录的URL文件中增加 url(r'^$', TemplateView.as_view( ...
- 基于ZooKeeper的三种分布式锁实现
[欢迎关注公众号:程序猿讲故事 (codestory),及时接收最新文章] 今天介绍基于ZooKeeper的分布式锁的简单实现,包括阻塞锁和非阻塞锁.同时增加了网上很少介绍的基于节点的非阻塞锁实现,主 ...
- [Flowable] - 工作流是什么?BPM是什么?
工作流管理系统基本概念 近两年随着电子商务环境不断演进(例如阿里巴巴的B2B电子商务平台),从原来支持企业内部单系统的业务流程.到企业内部应用.服务的集成,再进一步向企业与合作伙伴之间业务交互,工作流 ...
- js学习重点难点知识总结 (巩固闭包、原型、原型链)
学习重点知识总结 1.闭包知识点巩固 闭包函数: 1.可以实现函数外部访问函数内部的变量 2.在Java ...
- java多线程理解及实现
其实多线程也很好理解,就好比我们坐高铁.飞机过安检一样,过安检的时候一个入口只有一个安检口,而多线程就是为安检开启了多个安检口,话不多说贴代码 线程实现的三种方式: 一.继承Thread类创建线程类 ...
- Docker学习总结(七)--Docker私有仓库
创建私有仓库 1) 拉取私有仓库镜像 docker pull registry 2)启动私有仓库容器 docker run -di --name-registry -p 5000:5000 regis ...
- Leetcode之回溯法专题-77. 组合(Combinations)
Leetcode之回溯法专题-77. 组合(Combinations) 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输 ...