第三章 2D Rendering Texture Mapping (一)

Texture Mapping

正如我们早先提到的, texture 纹理, 是映射在 形状和固体表面的数据; 一般来说, 这些数据是 颜色信息, 通过调用成为 texture mapping 纹理映射的过程, 可以将包含颜色信息的 image 图片 map映射到到 (物体)表面. 除了颜色信息外, texture 数据还可以是 其他类型的数据, 如 用来 法向量映射normal mapping 的 法向量地图( 表面每点的法向量), 用来控制透明度的 alpha数据...

Texture 纹理和其他类型的 游戏数据一样, 一半在 runtime 运行时进行加载; 纹理处理 是 Direct3D的 不可缺少的 完整部分之一, 有现成的 built-in内置 函数足以让我们 进行 纹理处理.作为处理开始, 需要一个从硬盘加载纹理文件的 加载创建函数: D3DX11CreateTextureFromFile(), 其支持大量的 流行 图形图像文件格式: BMP, PNG 和 DDS. D3DX11CreateTextureFromFile() 函数 有6 个参数, 原型如下:

HRESULT D3DX11CreateTextureFromFile(
    ID3D11Device     *pDevice,            // 正如在 <swapchain ,context 和 device 的区别与联系>所说的, device 是创建对象的
    LPCTSTR         pSrcFile,             // 要加载的 纹理文件目录
    D3DX11_IMAGE_LOAD_INFO    *pLoadInfo,    // [可选]的 image 信息结构体, 指明 该函数控制 如何进行加载 纹理文件, 例如可设置CPU相关的存取标记, 内部格式, 宽度和高度等.
    ID3DX11ThreadPump         *pPump,        // 线程相关, 用于多线程的 asynchronously异步加载
    ID3D11Resource            **ppTexture,// 加载成功后的存储位置, 这时该参数会得到一个 ready-to-go 的纹理
    HRESULT                    *pHResult    // 呃.......
);

在 Direct3D 中, 各种函数可以加载的 image 图片格式如下:

Windows Bitmap ( BMP)
Joint Photographic Expert Group -- i.e., JPEG ( JPG)
Portable Network Graphics ( PNG)
Tagged Image Format ( TIFF)
Graphics Interchage Format ( GIF)
DirectDraw Surface ( DDS)
Windows Media Player ( WMP)

 

Texture Interface

Texture Interface 管理 image图像 数据, Direct3D中共有三种 类型:

> ID3D11Texture1D -- 处理 1D 或者 纹理图像分离 ?(暂无法翻译)

> ID3D11Texture2D -- 最常用的 纹理资源 类型

> ID3D11Texture3D -- 通量纹理?(3D 纹理)(暂无法理解翻译)

每种 texture resource 纹理资源都包含一种或多种的 子资源; 子资源 代表着 不同的 MIP 等级, 我们会在 下一节讨论. 游戏中使用的纹理 大部分是 2D类型, 需要转变 车工 ID3D11Texure2D 资源. 图形图像编辑器( 例如 Adobe Photoshop) 能够 生成创建 2D 纹理, 和 1D纹理( shader 使用的 查找表, 此时就是一个数组). 除简单 的纹理映射外, 1D 和 3D 纹理还用在 表现 高级特殊特效使用. 

2D 纹理 采用简单值 表示其 纹理坐标. 纹理坐标可以想成是  对 纹理图表进行索引的 索引数组. 在此 2D 纹理使用两个值表示 纹理坐标( texture coordinate): TU 和 TV ( 简写 U 和 V); 而 3D 纹理采用 三个值 ( TU , TV 和 TR ); 立体地图( 我们将在会在 "Texture Details" 小结讨论)也是用 三个纹理坐标, 因为它也只是简单的三维通量.

 MIP Maps

纹理中的 每一个像素都是一个 texel( 纹素? 图素? 无法翻译); texel 在 color map 颜色地图中就是一个 颜色值, 通常在 图形图像格式中的 0 到 255 范围内. 32位的图像 有 4个 8位组成, 分别分配成 红色, 绿色, 蓝色 和 alpha 值( 有时用来控制透明), 每种颜色各占一个字节byte, 32位包含4个字节; 这样的话, RGB图片, 将需要 3个字节共24位.

大部分图形图像编辑器使用 0到 255 表示颜色范围, 如 Adobe Photoshop的颜色板的拾取器中的RBG颜色都固定在 0到 255 范围内.

一张图片的 分辨率描述 了它的 宽度和高度( 在texel角度来看); 例如一张 分辨率为1024 * 768 的图片表示 在宽度上有 1024个 texel 高度上 768 个texel, 相当于一个 有 1024 行, 每行 768列 的表的大小; 那么1024 * 768 分辨率就共有 786,432 个texel; 如果每个 texel的大小为 4个字节 (32 位), 那这张图片的呃大小为 786,432 * 4 = 3,145,728个字节 = 3072 kb, 即未压缩的 3M 大小.

那么什么是 MIP map 呢? 先谈 MIP level( MIP 等级? MIP阶级? ), MIP levels 是 同一张纹理按照分辨率递减的 不同版本( 的纹理); MIP levels 的存在, 可以使系统根据 要处理的surface表面的距离, 自主的选择合适 分辨率的 纹理, (下面就是 MIP levels:), 这是出于一种考量:

(现实中也是)越是距离远的 物体, 越是没有办法看清楚它的细节, 因为我们不够近, 在进行纹理映射表面时, 也没有必要采用高分辨率的纹理, 否则反而会影响效果, 以下图解说, 

越是远离我们视野的 物体, 绘制到屏幕上的像素就越少, 如果还是采用高分率去映射的话, 会导致过多的 texel 绘制在用一个位置上, 不仅浪费还会产生叠加; 同样, 为了能够产生高质量的显示效果, 越是近的物体表面, 我们需要映射(贴上)高分辨率的贴图, 以显示更多的细节. 

这是一种很重要的机制, 越少数据进行拷贝移动, 运算越快, 游戏性能就能得到潜在性的提高; 如果很多物体远离我们的视野, 并且采用 低一些分辨率的texture而 看起来很正常, 跟高分辨率贴上的效果 一样的话, 为什么还要使用高分辨率的texture呢. 举个我自己的例子来说, 我在<<Dx11DemoBase 基类(二) 初始化 DirectX11 的 4个基本步骤>>中插入了下面这张图片, 分辨率为 2560 * 1920, 文件大小为 1.34MB, 屏幕摆放尺寸为 800 * 600, 每次当我预览本随笔/或者刷新页面访问本随笔, 使用滚动条 快速滚到这里时, ( 我的网速是较慢的e加宽, 内存2G) 画面会暂停, 一卡卡的, 我才这时应该在 加载 1.34 MB文件, 再变换缩小到 800 * 600 现实尺寸时 要处理 2560 * 1920 个texel; 而再快速滚动到 本随笔最底部的 分辨率为 800 * 600, 文件大小为 126KB, 屏幕摆放大小 也为 800 * 600的 相同一张图片时, 会加载显示快一些, 这是因为只需要处理 800 * 600 个texel, 也能达到相同的效果( 呃, 这里所谓的效果就是指 仅仅查看这两张示意图, 不做放大缩小).

那么, 这个处理机制, 被称为 mipmapping, 而 D3D11CreateTextureFeomFile() 函数默认会生成一整套的 MIP levels ; 使用 MIP map的另外一好处是减少走样.

MIP 还引入了两个新的概念 MIN 和 MAG. Minification 发生在 textured surface( 已映射的? 已贴图的)表面 远离我们的视野, 当物体远离时, 表面变小, 更多的texel将会合并到 一个相同的屏幕像素上; 而当物体靠近我们时, 表面变大, 反过来 更多的 像素 绘制相同的一个 texel , 产生 Magnification. 而如果 一个 像素刚好 一一对应到 一个 texel上是, Minification 和 Magnification 就不会发生, 不幸的一个现实是, 在3D游戏中, 总是有各种不同尺寸的不同距离物体表面需要映射贴图.

Texture Detail

有时候, 我们可能希望能够获取刚刚加载的 纹理文件 的 维度 和 像素格式, 这个需求可以 让ID3D11Texture2D::GetDesc() 函数 返回一个 D3D11_TEXTURE2D_DESC 结构体 填充信息 取得.

D3D11_TEXTURE2D_DESC 是 描述 纹理信息的结构体中的一种特定 描述2D 纹理的结构体, Direct3D 也提供了 D3D11_TEXTURE1D_DESC 和 D3D11_TEXTURE3D_DESC 分别 描述 1D 和 3D 纹理; 但 D3D11_TEXTURE2D_DESC 提供了如下额外的 信息:

typedef struct D3D11_TEXTURE2D_DESC{
    UINT                Width;
    UINT                Height;
    UINT                MipLevels;
    UINT                ArraySize;
    DXGI_FORMAT         Format;
    DxGI_SAMPLE_DESC     SampleDesc;
    D3D11_USAGE            Usage;
    UINT                BindFlags;
    UINT                CPUAccessFlags;
    UINT                MiscFlags;
}D3D11_TEXTURE2D_DESC;

D3D11_TEXTURE2D_DESC 结构体中的每个成员都可以在 context中访问到, 处理 ArraySize( 呃, 翻译有些不清晰): Each of the members of the D3D11_TEXTURE2D_DESC structure has been seen in on context or another, with the exception of ArraySize. 在我们描述 ArraySize 之前, 我们先讨论下 cube maps 立体地图, 立体地图 由 一组 2D 纹理组成, 用以产生一种 (立体)环境, 这种地图一般 有 上,下,左,右,前 和 后 这些方向, 如下图所示, D3D11_TEXTURE2D_DESC 的 ArraySize 将会是 6 , 表示6个立方体的面, 需要 6张图片.

 

 

 

 

下图是 解释 高低分辨率对相同显示效果物体的表面贴图的影响低分辨率图:

转载于:https://www.cnblogs.com/Wilson-Loo/archive/2012/12/02/2797918.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值