Direct3D 11 Tutorial 5: 3D Transformation_Direct3D 11 教程5:3D转型

概述

在上一个教程中,我们从模型空间到屏幕渲染了一个立方体。 在本教程中,我们将扩展转换的概念并演示可以通过这些转换实现的简单动画。

本教程的结果将是围绕另一个轨道运行的对象。 展示转换以及如何将它们组合以实现期望的效果将是有用的。 在我们介绍新概念时,未来的教程将在此基础上构建。

资源目录

(SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial05

Github

转型

在3D图形中,变换通常用于对顶点和矢量进行操作。 它还用于将它们在一个空间中转换为另一个空间。 通过与矩阵相乘来执行变换。 通常有三种类型的原始变换可以在顶点上执行:平移(相对于原点位于空间中),旋转(相对于x,y,z帧的方向)和缩放(距离 起源)。 除此之外,投影变换用于从视图空间到投影空间。 XNA Math库包含的API可以方便地构建矩阵,用于多种用途,例如平移,旋转,缩放,世界到视图转换,视图到投影转换等。 然后,应用程序可以使用这些矩阵来转换其场景中的顶点。 需要对矩阵变换有基本的了解。 我们将简要介绍下面的一些示例。

平移

平移是指在空间中移动或移位一定距离。 在3D中,用于翻译的矩阵具有形式。

    1  0  0  0
    0  1  0  0
    0  0  1  0
    a  b  c  1

其中(a,b,c)是定义移动方向和距离的向量。 例如,要沿X轴(负X方向)移动顶点-5单位,我们可以将其与此矩阵相乘:

    1  0  0  0
    0  1  0  0
    0  0  1  0
   -5  0  0  1

如果我们将此应用于以原点为中心的立方体对象,则结果是该框向负X轴移动5个单位,如图5所示,在应用平移之后。

图1.平移的影响

在3D中,空间通常由原点和来自原点的三个唯一轴定义:X,Y和Z.计算机图形中通常使用多个空间:对象空间,世界空间,视图空间,投影空间和屏幕空间。

图2.在对象空间中定义的立方体

旋转

旋转是指围绕穿过原点的轴旋转顶点。 三个这样的轴是空间中的X,Y和Z轴。 2D中的示例是逆时针旋转矢量[1 0] 90度。 旋转的结果是向量[0 1]。 用于围绕Y轴顺时针旋转1度的矩阵看起来像这样:

    cos?  0  -sin?   0
     0    1     0    0
    sin?  0   cos?  0
     0    0     0    1

图6显示了围绕Y轴旋转以原点为中心45度的立方体的效果。

图3.围绕Y轴旋转的效果

缩放

缩放是指沿轴方向放大或缩小矢量分量的大小。 例如,矢量可以沿所有方向按比例放大或仅沿X轴按比例缩小。 为了扩展,我们通常在下面应用缩放矩阵:

    p  0  0  0
    0  q  0  0
    0  0  r  0
    0  0  0  1

其中p,q和r分别是沿X,Y和Z方向的比例因子。 下图显示了沿X轴缩放2并沿Y轴缩放0.5的效果。

图4.缩放的效果

多重转换

要将多个变换应用于矢量,我们可以简单地将矢量乘以第一个变换矩阵,然后将得到的矢量乘以第二个变换矩阵,依此类推。 因为向量和矩阵乘法是关联的,我们也可以先将所有矩阵相乘,然后将向量乘以乘积矩阵,得到相同的结果。 下图显示了如果我们将旋转和平移转换结合在一起,立方体将如何结束。

图5.旋转和平移的效果

创建轨道

在本教程中,我们将转换两个多维数据集。 第一个将旋转到位,而第二个将围绕第一个旋转,同时在其自己的轴上旋转。 这两个立方体将具有与其关联的自己的世界变换矩阵,并且该矩阵将在渲染的每个帧中重新应用于该矩阵。

XNA Math中有一些函数可以帮助创建旋转,平移和缩放矩阵。

  • 围绕X,Y和Z轴执行的旋转分别使用函数XMMatrixRotationX,XMMatrixRotationY和XMMatrixRotationZ来完成。 它们创建围绕主轴之一旋转的基本旋转矩阵。 围绕其他轴的复杂旋转可以通过将它们中的几个相乘来完成。
  • 可以通过调用XMMatrixTranslation函数来执行转换。 此函数将创建一个矩阵,用于转换参数指定的点。
  • 使用XMMatrixScaling完成缩放。 它仅沿主轴缩放。 如果需要沿任意轴缩放,则可以将缩放矩阵与适当的旋转矩阵相乘以实现该效果。

第一个立方体将旋转到位,并作为轨道的中心。 立方体沿Y轴旋转,应用于相关的世界矩阵。 这是通过调用以下代码中显示的XMMatrixRotationY函数来完成的。 立方体每帧旋转一定量。 由于立方体被假设为连续旋转,因此旋转矩阵所基于的值随每帧递增。

// 1st Cube: Rotate around the origin
    g_World1 = XMMatrixRotationY( t );

  

第一个立方体将旋转到位,并作为轨道的中心。 立方体沿Y轴旋转,应用于相关的世界矩阵。 这是通过调用以下代码中显示的XMMatrixRotationY函数来完成的。 立方体每帧旋转一定量。 由于立方体被假设为连续旋转,因此旋转矩阵所基于的值随每帧递增。

// 2nd Cube:  Rotate around origin
    XMMATRIX mSpin = XMMatrixRotationZ( -t );
    XMMATRIX mOrbit = XMMatrixRotationY( -t * 2.0f );
    XMMATRIX mTranslate = XMMatrixTranslation( -4.0f, 0.0f, 0.0f );
    XMMATRIX mScale = XMMatrixScaling( 0.3f, 0.3f, 0.3f );
    g_World2 = mScale * mSpin * mTranslate * mOrbit;

  

需要注意的一点是,这些操作不是可交换的。 应用转换的顺序很重要。 试验转化顺序并观察结果。

由于所有变换函数都将根据参数创建新矩阵,因此它们旋转的量必须递增。 这是通过更新“时间”变量来完成的。

// Update our time
    t += XM_PI * 0.0125f;

  

在进行渲染调用之前,必须为着色器更新常量缓冲区。 请注意,世界矩阵对于每个多维数据集都是唯一的,因此会为每个传递给它的对象进行更改。

//
    // Update variables for the first cube
    //
    ConstantBuffer cb1;
    cb1.mWorld = XMMatrixTranspose( g_World1 );
    cb1.mView = XMMatrixTranspose( g_View );
    cb1.mProjection = XMMatrixTranspose( g_Projection );
    g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb1, 0, 0 );

    //
    // Render the first cube
    //
    g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
    g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer );
    g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
    g_pImmediateContext->DrawIndexed( 36, 0, 0 );

    //
    // Update variables for the second cube
    //
    ConstantBuffer cb2;
    cb2.mWorld = XMMatrixTranspose( g_World2 );
    cb2.mView = XMMatrixTranspose( g_View );
    cb2.mProjection = XMMatrixTranspose( g_Projection );
    g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb2, 0, 0 );

    //
    // Render the second cube
    //
    g_pImmediateContext->DrawIndexed( 36, 0, 0 );

  

深度缓冲区

本教程还有另外一个重要的补充,那就是深度缓冲区。 没有它,较小的轨道立方体在围绕后者的后部时仍会被绘制在较大的中心立方体的顶部。 深度缓冲区允许Direct3D跟踪绘制到屏幕的每个像素的深度。 Direct3D 11中深度缓冲区的默认行为是检查屏幕上绘制的每个像素与屏幕空间像素的深度缓冲区中存储的值。 如果正在渲染的像素的深度小于或等于深度缓冲器中已经存在的值,则绘制像素并且将深度缓冲器中的值更新为新绘制的像素的深度。 另一方面,如果正在绘制的像素的深度大于深度缓冲器中已经存在的值,则丢弃该像素并且深度缓冲器中的深度值保持不变。

示例中的以下代码创建深度缓冲区(DepthStencil纹理)。 它还创建深度缓冲区的DepthStencilView,以便Direct3D 11知道将其用作深度模板纹理。

 // Create depth stencil texture
    D3D11_TEXTURE2D_DESC descDepth;
    ZeroMemory( &descDepth, sizeof(descDepth) );
    descDepth.Width = width;
    descDepth.Height = height;
    descDepth.MipLevels = 1;
    descDepth.ArraySize = 1;
    descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    descDepth.SampleDesc.Count = 1;
    descDepth.SampleDesc.Quality = 0;
    descDepth.Usage = D3D11_USAGE_DEFAULT;
    descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    descDepth.CPUAccessFlags = 0;
    descDepth.MiscFlags = 0;
    hr = g_pd3dDevice->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil );
    if( FAILED(hr) )
        return hr;

    // Create the depth stencil view
    D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
    ZeroMemory( &descDSV, sizeof(descDSV) );
    descDSV.Format = descDepth.Format;
    descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    descDSV.Texture2D.MipSlice = 0;
    hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView );
    if( FAILED(hr) )
        return hr;

  

为了使用这个新创建的深度模板缓冲区,教程必须将其绑定到设备。 这是通过将深度模板视图传递给OMSetRenderTargets函数的第三个参数来完成的。

g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, g_pDepthStencilView );

  

与渲染目标一样,我们还必须在渲染之前清除深度缓冲区。 这可确保先前帧的深度值不会错误地丢弃当前帧中的像素。 在下面的代码中,教程实际上是将深度缓冲区设置为最大量(1.0)。

    //
    // Clear the depth buffer to 1.0 (max depth)
    //

  

最终效果

原文地址:https://www.cnblogs.com/OctoptusLian/p/9752062.html

时间: 2024-11-06 07:21:32

Direct3D 11 Tutorial 5: 3D Transformation_Direct3D 11 教程5:3D转型的相关文章

30分钟学会iOS 11开发环境xcode 9图文教程

关注微信公众号[异步图书]每周送书 Xcode是一款功能全面的应用程序,通过此工具可以轻松输入.编译.调试并执行Objective-C程序.如果想在Mac上快速开发iOS应用程序,则必须学会使用这个强大的工具的方法.在本文容中,将详细讲解Xcode 9开发工具的基本知识,为读者步入本书后面知识的学习打下基础. 1.1 基本面板介绍 使用Xcode 9打开一个iOS 11项目后的效果如图1-1所示. 图1-1 打开一个iOS 11项目后的效果(1)调试区域:左上角的这部分功能是控制程序编译调试或者

室外设计 3D室外效果图教程 Sketchup园林景观教程 室外漫游动画实例教程 景观设计手绘教程

热门推荐电脑办公计算机基础知识教程 Excel2010基础教程 Word2010基础教程 PPT2010基础教程 五笔打字视频教程 Excel函数应用教程 Excel VBA基础教程 WPS2013表格教程 更多>平面设计PhotoshopCS5教程 CorelDRAW X5视频教程 Photoshop商业修图教程 Illustrator CS6视频教程 更多>室内设计3Dsmax2012教程 效果图实例提高教程 室内设计实战教程 欧式效果图制作实例教程 AutoCAD2014室内设计 Aut

在rhel6上安装11.2.0.3 or 11.2.0.4 db sofrware时报缺少"elfutils-libelf-devel-0.97" And "pdksh-5.2.14"

Installing 11.2.0.3 Or 11.2.0.4 (32-bit (x86) or 64-bit (x86-64) ) On RHEL6 Reports That Packages "elfutils-libelf-devel-0.97" And "pdksh-5.2.14" Are Missing (PRVF-7532) (Doc ID 1454982.1) Applies to: Oracle Universal Installer - Versi

ArcGIS教程:3D Analyst基础知识

创建3D视图 以三维形式查看数据能为您提供一个全新的认识.通过三维视图可以深入了解通过相同数据的平面地图不易察觉的内容.例如,您不必根据配置等值线来推断是否存在山谷,您能够实际看到山谷和感到谷底和谷脊的高度差异. ArcGlobe 和 ArcScene 可用于构建多图层 3D 环境,并控制如何对各图层进行符号化.渲染各图层和在 3D 空间中定位各图层.还可以控制 3D 视图的全局属性,如照明度或垂直夸大.可以通过以下方式选择要素:使用要素的属性或要素相对于其他要素的位置,或者在场景或地球中单击各

[连载]Tutorial series: learning how to write a 3D soft engine from scratch in C#, TypeScript or JavaScript[英]

MSDN中的一篇博文链接:Tutorial series: learning how to write a 3D soft engine from scratch in C#, TypeScript or JavaScript This tutorial is part of the following series: 1 – Writing the core logic for camera, mesh & device object (this article) 2 – Drawing li

PSU 从11.2.0.3.0 -> 11.2.0.3.11 遇冲突解决全程

Oracle rdbms 打psu从11.2.0.3.0升级到11.2.0.3.11 参考patch :18522512 停应用,停监听与DB,将db的oracle_home下的OPatch目录加到环境变化PATH路径下,因为接下来要用opatch工具. 报错,说这个opatch工具太旧,要下载新的. The OPatch version being used (11.2.0.1.7) doesn't meet the minimum version required by the patch(

800元组装一台3D打印机全教程流程-零件清单

继前面的教程800元组装一台3D打印机全教程流程 k800是一台根据kosselmini改进的低成本3d打印机,通过改变设计,降低了成本,但损失较少性能,取得性价比. 主要改动是:底部支架改为->通用支架行星步进改为->小比例齿轮步进直线滑轨改为->滑车鱼眼关节并联臂->强磁并联臂 电机部分:43mm长的42步进电机X4个,42步进负责k800(kosselmini)3d打印机的“驱动”以及“送丝”工作.某宝价格基本在45元左右,负责“送丝”的42步进,如果要求比较高可以购买63m

800元组装一台3D打印机全教程流程

我最近正好要组装一台新的reprap的kossel delta型开源3d打印机,这台机器性价比非常高,具有速度快,静音,三臂并联结构,扩展性强,便宜的特点.图纸啥的都有,只是用到mega2560和ramps1.4,和吧友交流感觉吧里需要3d机制作arduino结构件的朋友很多,淘宝上卖的很黑,普遍4~5000,1万多的也有.所以我在考虑是否要开个帖子专门来说明如何800元左右搞定这台机器.大家有兴趣吗?有毅力自己做完这台机器码? 20140326:reprap的开源delta三臂3d打印机kos

11.1 LAMP架构介绍 11.2 MySQL、MariaDB介绍 11.3/11.4/11.5 MySQL安装

11.1 LAMP架构介绍 11.2 MySQL.MariaDB介绍 11.3/11.4/11.5 MySQL安装 扩展 mysql5.5源码编译安装 http://www.aminglinux.com/bbs/thread-1059-1-1.html mysql5.7二进制包安装(变化较大) http://www.apelearn.com/bbs/thread-10105-1-1.html 11.1 LAMP架构介绍 Linux + Apache(httpd)+ MySQL + PHP  PH