zoukankan      html  css  js  c++  java
  • D3D学习总结基础篇(二)从古墓丽影的画面设置了解基础概念

    上一篇文章比较理论,讲的都是数学,这一篇呢。。。讲的还是基础理论-。-

    虽然编程上,实践非常重要,但由于D3D编程有太多的理论知识沉淀,所以,在弄清楚这些概念之后,再开始coding也不迟。

    相信很多玩家和我一样,当年曾因为电脑配置差而不能流畅运行一些大型3D游戏,不得已在画面设置上做出许多让步,通过不断的实验得到画面和流畅度的平衡点。这篇文章就从画面设置菜单开始,来介绍3D图形学中的基础概念。顺便再说下,本文中的理论大部分来自Introduction to 3D Game Programming with DirectX 10一书,越来越觉得自己像技术翻译了。。。

    =========================================分割线==

    首先看上面这张图,是古墓丽影的display setting(google上随便找的,不知道是哪个版本的古墓,反正不是地下世界就是传奇)。这里列出了几个典型的设置项,我们就从这些item中挑几个来分析吧:

    1. Anti Aliasing 全屏抗锯齿:

    这是非常常见的技术,在Direct X中,抗锯齿技术叫做multisampling,下面来具体讲下这个技术。

    由于一个像素点在屏幕上并非是无限小的,因此,任意线条都不可能完美现实在屏幕上。举个简单的例子:

    上图中,上面的那条线呈明显的阶梯状,也就是我们所说的"锯齿",下图,通过对每个点和周围点进行取样,生成一些相似颜色的点,来实现抗锯齿的效果(不确认我这样说是否准确),这就是D3D用到的multisampling(多抽样)技术。当然,提高分辨率可以将锯齿现象减少,通常也会带来较大的性能损失,不过抗锯齿技术也是相当吃性能的。。。

    在D3D中,通过改变下面这个结构的值来设抗锯齿效果:

     

    typedef struct DXGI_SAMPLE_DESC { 

    UINT Count;
    //对每一个像素生成几个取样 

    UINT Quality; 

    } DXGI_SAMPLE_DESC, 
    *LPDXGI_SAMPLE_DESC;

    如果要开发成熟的3D应用,要考虑到不同级别硬件的要求,可以通过以下代码来check硬件设备是否支持某个级别的抗锯齿:

    HRESULT ID3D10Device::CheckMultisampleQualityLevels(
      DXGI_FORMAT Format, UINT SampleCount, UINT 
    *pNumQualityLevels);

    如果硬件不支持,该函数返回0。(DXGI_FORMAT会在后面提到,如果没忘记的话。。。)

    2. Texture 纹理

    纹理质量对3D游戏的显示效果有着至关重要的作用,这里就具体讲一下D3D中的Textures。

    我们通常认为,纹理就是一张2D图片,微观的说,就是一个矩阵,每个矩阵元素对应一个像素点的颜色,事实上,早期的游戏确实就是这么实现的。不过,到了3D时代,事情变的复杂了很多,纹理的用途很多,在矩阵中的每一个元素不仅对应着一个像素点的颜色,可还可能对应一个数字,一个向量,或者一个数组。有点抽象,具体的说,比如,有种技术叫"mipmap"(这里就不详细解释了,可以去google下),实现这种技术的某种方法就是在纹理中存放mipmap level。当然,同一个纹理文件不可能包含任意信息,同一种纹理类型里存放的数据是固定的。D3D中,通过枚举类型DXGI_FORMAT来设定纹理的类型,下随便举几种纹理类型:

    DXGI_FORMAT_R32G32B32_FLOAT: 每个元素包含三个32位浮点数。

    DXGI_FORMAT_R16G16B16A16_UNORM: 每个元素包含4个16位组件对应[0,1],一般用来做阴影。

    这里就不再往细的写了,因为这块具体的算法很多我也不理解,有兴趣的朋友参看http://msdn.microsoft.com/en-us/library/ee418116(VS.85).aspx

    对于类型中的R, G, B, A分别对应red, green, blue, and alpha,前三个是三原色,最后一个代表着透明度,术语叫做阿尔法通道,用过3DMax或者Maya等建模工具的人应该不会陌生。另外需要说明的是,纹理并不一定要存放颜色的信息,比如DXGI_FORMAT_R32G32B32_FLOAT,可以存放一个三维的向量。

    3. Triple Buffering 三倍缓冲

    我们经常看到游戏设置里会有双倍缓冲(double buffering),三倍缓冲(triple buffering)之类的选项。具体是什么意思呢,无论硬件有多快,渲染一个画面都是需要花费一定时间的,一般来说,渲染一个画面是从上往下垂直的顺序渲染的,这样给用户的体验就很不好,我没应该没看过游戏把渲染过程展现给用户的吧,这样画面可是会很闪。。。Swap Chain就是为了避免这种情况设计的技术,实现很简单,就是用一个缓冲区存储下一帧需要渲染的内容,这样,"画"的过程就不会让用户看见了。

    具体过程看下面的图解:

    Buffer A和Buffer B是两个缓冲区(double buffering),有两个指针指向他们,Front Buffer Ptr始终指向现实给用户的那一帧画面,Back Buffer Ptr则始终指向下一帧,就是要在背后渲染的那一帧,然后通过不断的调换指针指向,来实现swap chain。

    如果有三个Buffer,就称为Triple buffering。

    Swap chain技术被封装在接口IDXGISwapChain中,具体的后面再说。

    4. Depth Buffering 深度缓冲

    最后说下这个深度缓冲,事实上,他是一种特殊的纹理,不保存图像信息,保存的是depth信息。事实上,深度信息就是一个0到1的浮点数(0表示该像素离屏幕最近,1最远),每个像素点对应一个depth项。他是用来让3D引擎知道该把哪个像素画在前面,如下图:

    四个图形重叠在了同一快位置,但并没有出现前后的错位,具体是怎么实现的呢,虽然不难,但描述有些困难,下面还是有图示先:

    上图展示了一种情况,p1,p2,p3分别为三个图形上的三个点,他们重合到了一起,对应到界面上的p点,那p点到底该渲染啥呢,显然是p1嘛,但要让计算机明白这个,需要一个比较麻烦的推导过程(笔者再小小的偷下懒,借用下书上的表格):

    Operation

    P

    d

    Description

    Clear operation

    Black

    1.0

    Pixel and corresponding depth entry initialized.

    Draw cylinder

    P3

    d3

    Since d3d = 1.0, the depth test passes and we update the buffers by setting P = P3 and d = d3.

    Draw sphere

    P1

    d1

    Since d1d = d3, the depth test passes and we update the buffers by setting P = P1 and d = d1.

    Draw cone

    P1

    d1

    Since d2 > d = d1, the depth test fails and we do not update the buffers.

    推导步骤:

    1. 清空屏幕:将D 设置为1,也就是最远,然后用一种单一的颜色来填充整个屏幕。假设三个图形的渲染顺序是,圆柱,球和圆锥。
    2. 不断的判断所需要画的像素的depth值dx,如果他小于当前的D ,就让D=dx,P=当前像素;否则,不做任何处理。
    3. 一切需要渲染的元素判断完了,讲当前的P渲染。

    今天就写到这里吧,其实偶很菜,写这些博文也是为了加深自己对基础的印象,欢迎大牛拍砖。

    Raiden Cheng
  • 相关阅读:
    下拉菜单年月日
    把某些字符替换成**;
    单击向下滚动,单击停止滚动,下拉显示top,点击top返回顶部
    去除网页中的选中和右键菜单
    表单验证必须为6-12位英文字母去除首尾空格
    免费的海量编程中文书籍索引-都是干货【强烈建议收藏】
    图标搜索网站
    表单验证
    HDU 6319 Problem A. Ascending Rating(单调队列)
    Palindrome Function HDU
  • 原文地址:https://www.cnblogs.com/raidencheng/p/1682941.html
Copyright © 2011-2022 走看看