DirectX11学习笔记四 纹理入门

  纹理这东西经常玩游戏的多少都应该听说过,以前我经常把纹理、材质、贴图、模型、图片等等混为一谈,学了计算机图形学之后终于有些眉目了。对于基础入门来说(比如我),纹理可以理解为把一张图片贴在模型上。

加载纹理资源

  原来的龙书所推荐的读取贴图文件的方法已经被弃用,微软的说明文档上推荐使用DirectXTK提供的库,用来读取DDS文件。
函数定义

HRESULT CreateDDSTextureFromFile(
    ID3D11Device* d3dDevice,                // [In]D3D设备
    const wchar_t* szFileName,              // [In]dds图片文件名
    ID3D11Resource** texture,               // [Out]输出一个指向资源接口类的指针,也可以填nullptr
    ID3D11ShaderResourceView** textureView, // [Out]输出一个指向着色器资源视图的指针,也可以填nullptr
    size_t maxsize = 0,                     // [In]忽略
    DDS_ALPHA_MODE* alphaMode = nullptr);  // [In]忽略

调用示例

// 初始化木箱纹理
	HR(CreateDDSTextureFromFile(m_pd3dDevice.Get(), L"Texture\\WoodCrate.dds", nullptr, m_pWoodCrate.GetAddressOf()));

  显然,这里用到了一个叫ID3D11ShaderResourceView的类对象m_pWoodCrate,微软的定义如下。

A shader-resource-view interface specifies the subresources a shader can access during rendering. Examples of shader resources include a constant buffer, a texture buffer, and a texture.

  读着很熟悉,用来绑定常量缓冲区、纹理缓冲区和纹理等,提供着色器在渲染时的访问,可是我们之前渲染光照或者渲染立方体的时候也用到了常量缓冲区,但是并没有用到ShaderResourceView,这是怎么回事呢?
复习一遍常量缓冲区的绑定流程

  • D3D11_BUFFER_DESC和m_pd3dDevice->CreateBuffer()来创建常量缓冲区
  • D3D11_MAPPED_SUBRESOURCE和Map方法映射对应的缓冲区动态修改
  • m_pd3dImmediateContext->VSSetConstantBuffers() 将缓冲区与渲染管线绑定

  而反观ComPtr<ID3D11ShaderResourceView> m_pWoodCrate; // 木盒纹理

  • CreateDDSTextureFromFile()
  • m_pd3dImmediateContext->PSSetShaderResources();
    好像缺少了Create这个步骤,可能是封装到了CreateDDSTextureFromFile方法中。
    读取完后绑定到渲染管线。
	m_pd3dImmediateContext->PSSetShaderResources(0, 1, m_pWoodCrate.GetAddressOf());

初识纹理

  纹理分为三种,一维,二维和三维,只讨论二维纹理,也就是图片。通过纹理映射,设置相应的坐标与顶点坐标对应,来将一张图片“钉”在三角形面上,因此在顶点着色器中纹理坐标不需要做类似法线变换。根据透视的不同,纹理不可能保持原始大小,所以必须要进行插值,插值原理跟像素着色器插值类似。
  这就要求在传入的顶点输入格式中再定义一个TEXCOORD,并设置相应与纹理对应的数值,如何对应?这就引入了纹理坐标系
在这里插入图片描述
  纹理坐标系的轴用u和v表示,范围[0,1]用来规范化坐标系。以立方体中正对着摄像机的面为例
在这里插入图片描述
  三个数值依次是顶点序列、顶点坐标(省略z)、纹理坐标,顶点索引是1、2、3和3、4、1,处在同一个平面的两个三角形,两个三角形面“共享”同一张纹理。那么一张纹理是如何精确的贴到两个面上的呢?
  这就要引入采样器的概念。

采样器

  要创建采样器(Sampler),首先需要采样器描述(D3D11_SAMPLER_DESC),这与之前创建缓冲区的步骤类似,都需要DESC描述
示例代码

// 初始化采样器状态
	D3D11_SAMPLER_DESC sampDesc;
	ZeroMemory(&sampDesc, sizeof(sampDesc));
	sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
	sampDesc.MinLOD = 0;
	sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
	HR(m_pd3dDevice->CreateSamplerState(&sampDesc, m_pSamplerState.GetAddressOf()));
D3D11_SAMPLER_DESC成员 描述
D3D11_FILTER Filter 过滤器 它指定被采样的纹理怎样过滤。纹理过滤描述从源数据怎样被读取和联合,使得用于着色器。过滤能够提升画质但是在纹理采样时会有更多的性能开销,因为一些过滤类型是由于读取和结合多个纹理元素值来产生一个在着色器中看到的单一的颜色值。
D3D11_TEXTURE_ADDRESS_MODE AddressU 纹理寻址模式
D3D11_TEXTURE_ADDRESS_MODE AddressV 纹理寻址模式
D3D11_TEXTURE_ADDRESS_MODE AddressW 纹理寻址模式
FLOAT MipLODBias 用于 MIP 的级别细节(level-of-detail,简称 LOD)偏移。该值是一个通过 Direct3D 使用的 MIP 级别机制的偏移量。例如,如果 Direct3D 指定使用第 2 级别的 MIP 并且偏移量为 3,则实际上 MIP 使用的是第 5 级别。
UINT MaxAnisotropy 最大各向异性值,用于各向异性过滤和比较函数。该值范围是 1-16 之间的整数,它不用于点和双线性过滤。
D3D11_COMPARISON_FUNC ComparisonFunc COMPARISON函数的返回值用于判定贴图过滤标识的比较。比较标识在D3D11_COMPARISON_FUNC 中指定,其比较状态的本质是比较两个值之间的等于,大于小于关系。
FLOAT BorderColor[ 4 ] 如果贴图地址模式使用了D3D11_TEXTURE_ADDRESS_BORDER,这个成员就可以指定颜色值(RGBA值必须在0~1)。
FLOAT MinLOD 若mipmap等级低于MinLOD,则使用等级MinLOD。最小允许设为0。
FLOAT MaxLOD 若mipmap等级高于MaxLOD,则使用等级MaxLOD。必须比MinLOD大。

过滤器 D3D11_FILTER

参考这篇博客

由于纹理实际上是由多个离散的颜色值组成的,因此,对于一张256256尺寸的纹理,如果它正好投影在屏幕上256256尺寸的区域内,那么一个像素对应一个纹理值,这是最理想的情形。但是,当这些颜色值与屏幕上的像素不能够一一对应时,如何计算特定像素处的颜色值?在这种情况下,就需要用到纹理过滤。设想如下两种情形:
1. 当照相机与一张纹理不断靠近时,即使该纹理尺寸远小于屏幕,当距离足够近时,该纹理也有可能投影在整个屏幕上。这时,纹理上的一个元素将覆盖很多个屏幕像素。
2. 当照相机不断远离时,纹理在屏幕上的投影会越来越小,当距离足够远时,有可能带个纹理会投影在一个屏幕像素内。
在这两种情况下,如果计算纹理在屏幕投影范围内对应各个像素的值,即需要纹理过滤。
纹理过滤分为两种:一种为放大,即Magnification; 一种为缩小,即Minification。当一个纹理元素覆盖屏幕上多个像素时,使用的过滤为Magnification,对应于上述第一种情形;当多个纹理元素投影在一个屏幕像素内时,使用的过滤为Minification,对应于上述第二个例子。

过滤器类型 描述
D3D11_FILTER_MIN_MAG_MIP_POINT Use point sampling for minification, magnification, and mip-level sampling.
D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR Use point sampling for minification and magnification; use linear interpolation for mip-level sampling.
D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT Use point sampling for minification; use linear interpolation for magnification; use point sampling for mip-level sampling.
D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR Use point sampling for minification; use linear interpolation for magnification and mip-level sampling.
D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT Use linear interpolation for minification; use point sampling for magnification and mip-level sampling.
D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR Use linear interpolation for minification; use point sampling for magnification; use linear interpolation for mip-level sampling.
D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT Use linear interpolation for minification and magnification; use point sampling for mip-level sampling.
D3D11_FILTER_MIN_MAG_MIP_LINEAR Use linear interpolation for minification, magnification, and mip-level sampling.
D3D11_FILTER_ANISOTROPIC Use anisotropic interpolation for minification, magnification, and mip-level sampling.
D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT
D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR
D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT
D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR
D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT
D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR
D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT
D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR
D3D11_FILTER_COMPARISON_ANISOTROPIC
D3D11_FILTER_MINIMUM_MIN_MAG_MIP_POINT
D3D11_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR
D3D11_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT
D3D11_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR
D3D11_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT
D3D11_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR
D3D11_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT
D3D11_FILTER_M
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值