Directx11教程(31) 纹理映射(1)
在前面的例子中,我们要么是直接给顶点赋颜色值,要么是在顶点属性中设置Diffuse和Specular系数,从而根据光照参数计算得到物体表面颜色,但这样得到的颜色真实感要差很多。如果我们直接把一副图像映射到三角形面上,从而得到物体表面颜色值,效果会好很多,比如下面的两幅图,右边的图是把一副图片映射到2个三角形上。

甚至,我们还可以直接使用图像的颜色值做为顶点(或者pixel)的diffuse值,融合光照计算公式,得到最终的表面颜色值,这样会有更好的效果。
通常,我们把图像映射到三角形面上的技术称作纹理映射(texture mapping)。在纹理映射过程中,我们使用纹理坐标的方式(或称u、v坐标),把纹理进行划分,如下图,假设图像为256*256像素,则左上角纹理坐标为(0,0),右上角为(1,0),左下角为(0,1),右下角为(1,1)。
之所以使用这种归一化的uv坐标,主要是要使得uv坐标值和纹理图像大小没有关系,比如对下面的图,uv坐标(0.5, 0.5),其实就是映射到纹理上的像素(128,128),如果换成一个更大的纹理图像(1024*1024),则(0.5,0.5)就映射到(512,512)。

对于一个三角形,我们要为每一个顶点指定uv坐标,如下图的2个三角形,我们按照图上标的纹理坐标指定uv坐标,则左边的2个三角形则会被完整的映射成右边的纹理形状。

下面了解几个和纹理采样有关的概念:
Magnification与Minification:
如果光栅化后的三角形正好是256*256像素,这和纹理的大小正好相等,那么映射关系就是一个像素对应纹理的一个单元(texel),但实际情况可能更复杂。
比如:纹理大小为256*256,但我们的两个三角形组成的quad却是512*512,则一个纹理单元要对应quad上的四个像素,一个纹理单元对应多个光栅化后的像素的情况通常称作Magnification,

在magnification情况下如何进行纹理映射呢?通常是用双线性插值的方式,比如下面左边的图中红色的pixel,没有对应的纹理texel,则它的颜色值用它的上下左右的pixel颜色插值得到,当然我们也可以选择最接近的纹理单元颜色做为其颜色,具体要视纹理滤波中设置的MAG值。

和magnification的情况相反,minification表示三角形面小,而纹理大的情况,就是一个pixel如何在多个纹理单元中选择颜色的问题。这时可以选择最接近的纹理单元,也可以把上下左右纹理单元进行双线性插值,再和pixel映射起来。比如下图128*128的quad面和256*256纹理映射的情况:

mipmap层:
通常,我们创建纹理的时候,可以选择创建mipmp层,这时,系统就自动会为我们创建一系列下采样的图像,每个图像都是前面一个图像的1/4(如下图所示),我们可以自己选择mipmap的层数。如果使用dds文件的话,其中已经包含了mipmap层,所以最好把自己需要的纹理转化成dds格式,预处理得到需要mipmap层数。

在使用mipmap层的情况下,如何做纹理映射呢?
比如纹理原始大小是256*256,我们的三角形是178*178,那么这时会做三线性插值,四边形先和128*128纹理执行magnificaiton插值得到一个结果,再和256*256纹理做minification插值得到一个结果,最后再对这2个结果进行线性插值,得到的颜色为最终的pixel颜色。

纹理的寻址模式:
通常我们顶点的纹理坐标在[0,1]范围内,这样光栅化后的三角形pixel总能从纹理中找到对应的纹理单元。
我们也可以通过设置纹理寻址模式,来扩展纹理映射,对于不在[0,1]之间的纹理坐标,也可以找到对应的纹理单元。
通常的纹理寻址模式包括:
wrap方式:
对于不在[0,1]之间的纹理坐标,采用缠绕的方式来对应纹理单元,比如下面图所示,这样的方式特别适合用小纹理来贴一个大的平面,比如在地面铺瓷砖,在地面上铺草地等等。这也要求我们设计纹理图片时,把左右、上下的边缘部分,最好能无缝的连接起来。

border方式:
把不在[0,1]范围的纹理坐标设置为一些指定的颜色,比如下图,指定为红色

Clamp方式:
把不在[0,1]范围的纹理坐标指定为离其最近的纹理单元颜色。

Mirror方式:
就是把不在[0,1]范围的纹理坐标按镜像的方式指定纹理单元,如下图所示:

现在我们了解一些纹理采样的设置,在D3D11中使用纹理前我们必须设定采样状态,主要就是通过下面的的函数:
// 创建纹理采样状态描述符.
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0;
samplerDesc.BorderColor[1] = 0;
samplerDesc.BorderColor[2] = 0;
samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
// 创建纹理状态.
result = device->CreateSamplerState(&samplerDesc, &m_sampleState);
if(FAILED(result))
{
return false;
}
本篇教程中,我们了解D3D11纹理使用中的一些基本概念,下一篇日志,要开始写代码了…
Directx11教程(31) 纹理映射(1)的更多相关文章
- Directx11教程(43) 纹理映射(13)-动态纹理映射
原文:Directx11教程(43) 纹理映射(13)-动态纹理映射 本篇教程中,我们将在前面基于光照的地形与水面程序里面加上纹理映射,而且我们会基于时间动态改变水面的纹理坐标,实现水面纹理 ...
- Directx11教程(42) 纹理映射(12)-简单的bump mapping
原文:Directx11教程(42) 纹理映射(12)-简单的bump mapping 有时候,我们只有一个粗糙的模型,但是我们想渲染纹理细节,比如一个砖墙,我们如何在只有一个平面的时候 ...
- Directx11教程41 纹理映射(11)
原文:Directx11教程41 纹理映射(11) 1.第一副图我们采用各性异性的滤波方式,并设置最大各性异性值为8. samplerDesc.Filter = D3D11_FILT ...
- Directx11教程40 纹理映射(10)
原文:Directx11教程40 纹理映射(10) 本章尝试使用纹理行列式,或者说纹理数组,在ps中,使用2个纹理,最终的像素颜色,是光照颜色*纹理1采样颜色*纹理2采样颜色,主要是想达到如 ...
- Directx11教程39 纹理映射(9)
原文:Directx11教程39 纹理映射(9) 在myTutorialD3D11_32中,我们在PlaneModelClass中增加一个纹理TextureClass* m_Texture;读 ...
- Directx11教程38 纹理映射(8)
原文:Directx11教程38 纹理映射(8) 上篇日志中,我们用纹理和光照颜色调制的方式得到最终颜色,本章我们尝试用纹理采样的颜色,直接做为材质的漫反射系数Kd,并用它来做光照计算,最后 ...
- Directx11教程37 纹理映射(7)
原文:Directx11教程37 纹理映射(7) 本章是在教程35.36的基础上来实现一个光照纹理结合的程序,就是把场景中旋转的cube加上纹理. lighttex.vs中顶点的结构现在 ...
- Directx11教程36 纹理映射(6)
原文:Directx11教程36 纹理映射(6) 本章主要是整理代码,做以下两件事情: 1.把世界坐标矩阵的计算,放在GraphicsClass的渲染函数中,之前放在D3DClass中,而且只是 ...
- Directx11教程(35) 纹理映射(5)
原文:Directx11教程(35) 纹理映射(5) 到现在为止,我们的TextureClass初始化函数非常简单,说白了就是一行代码: result = D3DX11CreateShader ...
随机推荐
- 享元模式(Flyweight、FlyweightFactory)(围棋棋子共享)
(使用共享对象可有效地支持大量的细粒度的对象.) 假设开发一个围棋程序,围棋程序的围棋的棋子包含了颜色.大小.位置等信息.在定义一个棋盘容器来存放这些棋子. 我们可以发现,棋盘的成员变量包含了一个棋子 ...
- php5.3中namespace的说明,帮助初次接触namespace的phper快速理解
命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误.这种情况下只要避免命名重复就可以解决,最常见的一种做法是约定一个前缀,但是方法名变的很长 ...
- 007-使用python统计代码行数,空行以及注释
# 自己写过的程序,统计一下你写过多少行代码.包括空行和注释,但是要分别列出来 1.打开文件方法 1.1 以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符 f ...
- 解决github下载慢的终极方法
直接用ssr代理,使用全局代理. 下载墙外的软件,都可以,比如 GithubDsktop
- Python各种转义符
文章来源:https://www.cnblogs.com/luckyplj/p/9792658.html 谢谢作者:雨后观山色
- 华为RH2288 V3服务器进入BIOS并设置iBMC地址
服务器重启后 第一个画面 提示Ctrl+H或Ctrl+S进入相关配置 其中, Ctrl+H进入WebBIOS初次安装系统可在此做RAID配置 此画面不做操作,等待跳过 进入第二画面 可以选择BootM ...
- python 数据组合
- 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- 洛谷P1774 最接近神的人_NOI导刊2010提高(02) [2017年6月计划 线段树03]
P1774 最接近神的人_NOI导刊2010提高(02) 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门 ...
- Codeforces 1150D(字符串dp)
反思 三维的dp压根没看出来,看题解以后思路又很直观,找几道字符串dp练练才行 序列自动机和优化一维略 /* __ __ * ____| |_____| |____ * | | * | __ | * ...