第三章 2D Rendering Texture Mapping (二) 【已完成】【附带源码】

在上个小节中, 我们已经概括了足够的内容, 现在让我们来实现一个纹理映射的实例;同时本章的前半部分涉及过但未讨论完的都将会有所详细讨论.. 这个demo 可以在原书上的 Chapter3/TextureMapping 目录找到.

我们从修改 TriangleDemo 代码已开始我们的demo设计( 因为大部分代码和 TriangleDemo一样, 这里仅仅是添加了一大块的 sampler相关代码). TextureDemo 类的工作中, 我们将天添加两个新的事物:

ID3D11ShaderResourceView colorMap_; // shader resource view 着色器资源视图 ?
ID3D11SamplerState colorMapSampler_ ; // sampler state 采样器状态描述?

 

不要呀, 打住!太乱了, 眨眼前我才刚折腾完 inputlayout, IASetxxx 那些鬼东西, 现在这些又是什么? 我需要总结下, 看看这到底是啥, 用在哪个方面, 当前已开发的代码版本中的各项概念又是如何分布及组织的.

 

由此可以推断, colorMap_ colorMapSampler shader资源, 自然在render()渲染阶段使用, 创建当然在初始时( 注意, 我们的demo中会涉及到至少两个初始化, 一个是基类Dx11DemoBase::Initialize() 用以创建基本的 device, context, swapchain等每个 directx应用程序都需要的基本对象; 另外一个则是子类的 LoadContent()初始化内, 因为不同的directx应用程序项目实用的资源/运行方式不同; 本例的初始化 colorMap_ colorMapSampler子类的LoandCotent() ).

 

那么究竟什么 shader resource view? 是一个用来存取资源shader相关的对象( data manager for shader ?) 当我们加载纹理到内存的时候, 我们必须创建爱你一个 shader resource view, 这样才能通过 shader 存取数据, 这个 shader resource view 也必须绑定到 input assembler. 当然, shader resource view 还有其他用途, 例如并行计算时提供数据给 DirectCompute ; 但是我们这一章还是集中讨论如何运用在纹理texture. 概括一下吧:

ID3D11Texture2D  : 数据缓冲器
shader(s)     : 一个函数
shader resource view : shader( 即函数) 通过 shader resource view 访问 ID3DTexture2D 的缓冲数据

 

 

Sampler state 呢?  Sampler state 定义了 纹理数据使用 纹理地址模式, 过滤 和 细节(精度)等级的时候, 如何对纹理进行采样的.将会在后面解析.

 

增加了 colorMap_ 和 colorMapSampler_ 后, 我们的 demo类将会变成以下方式:

#ifndef _EVL_TEXTUREMAPPING_H_
#define _EVL_TEXTUREMAPPING_H_

#include "Dx11DemoBase.h"

class TextureMapping : public Dx11DemoBase
{
public:
    TextureMapping();
    virtual ~TextureMapping();

    bool LoadContent();
    void UnloadContent();

    void Update( float dt);
    void Render();

private:
    ID3D11VertexShader    *solidColorVS_;
    ID3D11PixelShader    *solidColorPS_;

    ID3D11InputLayout     *inputLayout_;
    ID3D11Buffer        *vertexBuffer_;

    ID3D11ShaderResourceView    *colorMap_;
    ID3D11SamplerState            *colorMapSampler_;

};

#endif

 

 

很明显, 我们是在展示 纹理映射, 理所应该的要修改  vertex 结构体, 以包含 两个 float 类型数据表示 纹理坐标的 TU 和 TV; 这有 XMFLOAT2 结构体可以胜任.正如前面所说, 在初始化阶段的LoadContent() 内, 需要进行 对这两个成员的 信息设置: 创建了 input layout 后, 我们需要添加 纹理坐标 texture coordinate 到 input 描述信息 D3D11_INPUT_ELEMENT_DESC内, semantic name 为 "TEXCOORD"表示 纹理坐标, 格式为 DXGI_FORMAT_R32G32_FLOAT( 因为我嫩只使用了两个 坐标表示 纹理坐标, 这里只需要使用 两个指). 在这里我得先 概括以下 vertexBuffer-inputElementDesc-inputLayout 之间的关系:

 

 

 

如图所示, vertex buffer 包含的是所有的 将要创建 input layout的数据源, 而 input element desc 是对这些数据源的 简要信息描述, 描述信息用以 创建 input layout( input layout 无非就是 更大数据源的 管理中介).

那么我们的纹理坐标shader 坐标信息也需要添加近 input layout中, 而除了这个坐标外, input layout 还包含了 position的描述信息,总共的信息如下:

// 输入布局信息

D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = {
  { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
  { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,    0,12, D3D11_INPUT_PER_VERTEX_DATA, 0}
};

但是 上述的 "12" 又是什么呢? 这得看这个 "描述" ( 即D3D11_INPUT_ELEMENT_DESC)是如何描述的.

首先, 是用来描述点的; 我们先来看上个小结 << 第三章 2D Rendering Drawing a 2DTriangle(绘制三角形) 【已完成】【附带源码】>> 的 demo:

这个三角形的坐标, 我们的代码中是这样定义的:

 

// 几何体信息

VertexPos vertices[] = {
  XMFLOAT3( 0.5f,  0.5f, 0.5f),
  XMFLOAT3( 0.5f, -0.5f, 0.5f),
  XMFLOAT3(-0.5f, -0.5f, 0.5f)
};

这个数组的 类型是 VertexPos, 定义为:

struct VertexPos
{
    XMFLOAT3 pos;
};

 

即是说 vertices数组的每个元素 如 vertices[0], vertices[1] 和 vertices[2] 都是一个 XMFLOAT3 数据元( 含三个浮点数), 在 TriangleDemo 中描述这个 vertices 为 :

// 创建输入布局信息
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = {
  {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
};

 

是吧 , "POSITION" 表示这是用来表示顶点的( 当然, 如果你想的的话可以强制作为其他用途, 就如 即使是 int 的数值 可以 转换成 char , 再输出其对应的assicc 字符: 数值的类型不在于其内部是否标记为什么类型意义,而在于其如何被使用. ); DXGI_FORMAT_R32G32B32_FLOAT 表示 是 由 三个浮点数组成的 数据元. 这样 描述_DESC 和 实际对象 vertices 就完全一致了, 就是 前面章节中提到的  Signature 签名相同了. 但如果描述为 :

// 创建输入布局信息
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = {
  { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
};

 

就签名不同了, 因为DXGI_FORMAT_R32G32_FLOAT表示只有两个float的数据元, 会导致后续读取vertices信息出现不可预知的错误.

 

好的, 回到本例, 我们为什么要 _DESC 定义成:

// 输入布局信息
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = {
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},   { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,    0,12, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
因为我们将要使用的 顶点集是这样的:
  // 几何体信息
    VertexPos vertices[] = {
        { XMFLOAT3( 1.0f, 1.0f, 1.0f), XMFLOAT2( 1.0f, 1.0f)}, 
        { XMFLOAT3( 1.0f, -1.0f, 1.0f), XMFLOAT2( 1.0f, 0.0f)}, 
        { XMFLOAT3( -1.0f, -1.0f, 1.0f), XMFLOAT2( 0.0f, 0.0f)},

        { XMFLOAT3( -1.0f, -1.0f, 1.0f), XMFLOAT2( 0.0f, 0.0f)},
        { XMFLOAT3( -1.0f, 1.0f, 1.0f), XMFLOAT2( 0.0f, 1.0f)}, 
        { XMFLOAT3( 1.0f, 1.0f, 1.0f), XMFLOAT2( 1.0f, 1.0f)},
    };

vertices数组的每个元素数据类型为 :

struct  VertexPos
{
    XMFLOAT3 pos;
    XMFLOAT2 tex0;
};

即前三个 数据 表示 三维坐标, 后两个数表示 纹理坐标.

其中的 "POSITION"     表示 那是一组三维坐标 , 格式为 DXGI_FORMAT_R32G32B32_FLOAT;

其中的 "TEXTCOORD"表示那是一组 纹理坐标,  格式为 DXGI_FORMAT_R32G32_FLOAT;

" 12" 适应为在 struct VertexPos 中 纹理坐标 偏离 vertices数组元素的开始位置( 如 &vertices[2] )有 12个字节 = sizeof( R32) + sizeof( G32) + sizeof( B32) = 4 byte + 4byte + 4byte = sizeof( XMFLOAT3) .

 

 

好, 我们现在可以的到 TextureMapping的 vertex struct, LoadContent() 和 UnloadContent() 函数的定义了:

struct VertexPos
{
    XMFLOAT3 pos;
    XMFLOAT2 tex0;
};


bool TextureMapping::LoadContent()
{
    ...

    // 第二步, 创建 inputlayout等信息
    D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, 
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,    0,12, D3D11_INPUT_PER_VERTEX_DATA, 0}
    };

    unsigned int totalLayoutElements = ARRAYSIZE( solidColorLayout);
    d3dResult = d3dDevice_->CreateInputLayout( solidColorLayout, totalLayoutElements, vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), &inputLayout_);
    vsBuffer->Release();

    if( FAILED( d3dResult))
    {
        return false;
    }


    ... load pixel shader

    // 要绘制的几何体
    VertexPos vertices[] = {

        { XMFLOAT3( 0.5f, 0.5f, 1.0f), XMFLOAT2( 1.0f, 0.0f)}, 
        { XMFLOAT3( 0.5f, -0.5f, 1.0f), XMFLOAT2( 1.0f, 1.0f)}, 
        { XMFLOAT3( -0.5f, -0.5f, 1.0f), XMFLOAT2( 0.0f, 1.0f)},

        { XMFLOAT3( -0.5f, -0.5f, 1.0f), XMFLOAT2( 0.0f, 1.0f)},
        { XMFLOAT3( -0.5f, 0.5f, 1.0f), XMFLOAT2( 0.0f, 0.0f)}, 
        { XMFLOAT3( 0.5f, 0.5f, 1.0f), XMFLOAT2( 1.0f, 0.0f)},
        
    };

    ... create vertex buffer ...


    d3dResult = D3DX11CreateShaderResourceViewFromFile( d3dDevice_, "decal2.dds", 0, 0, &colorMap_, 0);
    if( FAILED( d3dResult))
    {
        DXTRACE_MSG( "Failed to load the texture image!");
        return false;
    } 

    D3D11_SAMPLER_DESC colorMapDesc;
    ZeroMemory( &colorMapDesc, sizeof( colorMapDesc));
    colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;

    d3dResult = d3dDevice_->CreateSamplerState( &colorMapDesc, &colorMapSampler_);
    if( FAILED( d3dResult))
    {
        DXTRACE_MSG( "Failed to create color map sampler state!");
        return false;
    }

    return true;
}
void TextureMapping::UnloadContent()
{
    if( colorMapSampler_ ) colorMapSampler_->Release();
    if( colorMap_ ) colorMap_->Release();
    if( solidColorVS_ ) solidColorVS_->Release();
    if( solidColorPS_ ) solidColorPS_->Release();
    if( inputLayout_ ) inputLayout_->Release();
    if( vertexBuffer_ ) vertexBuffer_->Release();

    colorMapSampler_ = 0;
    colorMap_ = 0;
    solidColorVS_ = 0;
    solidColorPS_ = 0;
    inputLayout_ = 0;
    vertexBuffer_ = 0;
}

 

UnloadContent() 函数释放我们的创建的新对象, LoadContent() 函数的剩下部分就是 加载纹理图片了. Direct3D的 功能函数 D3DX11CreateShaderResourceViewFromFile() 可以 连带一起 夹杂后纹理并 创建 shader resource view.

这个函数 在 我们项一次性加载并创建 shader时 很方便; D3DX11CreateShaderResourceViewFromFile() 函数的原型如下( 和 D3DX11CreateTextureFromFile() 很相似):

HRESULT D3DX11CreateShaderResourceViewFromFile(
    ID3D11Device        *pDevice,
    LPCTSTR                        pSrcFile,
    D3DX11_IMAGE_LOAD_INFO        *pLoadInfo,
    ID3DX11ThreadPump                *pPump,
    ID3D11ShaderResourceView        **ppShaderResourceView,
    HRESULT        *pHResult
);

 

LoadContent()函数的剩下部分是 sampler state 的创建, Direct3D device CreateSamplerState() 函数将完成这一任务, 该函数输入 sampler 描述 , 输出创建好的shader state对象的地址, shader state创建信息描述结构体定义如下:

typedef struct D3D11_SAMPLER_DESC{
    D3D11_FILER   Filter; 
    D3D11_TEXTURE_ADDRESS_MODE    AddressU;
    D3D11_TEXTURE_ADDRESS_MODE    AddressV;
    D3D11_TEXTURE_ADDRESS_MODE    AddressW;
    FLOAT                 MipLODBias;
    UINI                MaxAnisotropy;
    D3D11_COMPARISON_FUNC    ComparisonFunc;
    FLOAT                 BorderColor[ 4];
    FLOAT                 MinLOD;
    FLOAT                 MaxLOD;
} D3D11_SAMPLER_DESC;

D3D11_SAMPLER_DESC 的第一个成员 D3D11_FILTER 确定如何进行 对 纹理采样进行 过滤.  因为纹理被映射到 三维图形表面时, 三维图形表面上的 pixel中心 未必和 纹理上的 texel中心一直, 大小也未必一致, 这就需要在 MIP中 的 同一level 或 不同levels之间进行 过滤, 以找出 最合适效果最好的 texel值;所以 纹理过滤 决定着 如何从纹理中读取及合并产生合理纹理到 shade;纹理过滤, 能够提高 纹理映射的效果 但是 也会消耗一定的性能, 因为一些过滤类型需要 读取并运算组合产生出一个能够进行着色的 颜色值.在Direct3D 11准哦功能 有各种 过滤类型:

typedef enum D3D11_FILTER{
    D3D11_FILTER_MIN_MAX_MIP_POINT
    D3D11_FILTER_MIN_MAX_POINT_LINEAR
    D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT
    D3D11_FILTER_POINT_MAG_MIP_LINEAR
    D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT
    D3D11_FILTER_MIN_LINEAR_MAG_POINT
    D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR
    D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT
    D3D11_FILTER_MIN_MAG_MIP_LINEAR 
    D3D11_FILTER_ANISOTROPIC 

    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_TEXT_IBIT
}D3D11_FILTER;

D3D11_FILTER的各种枚举值, 是由纹理的 MIN, MAG MIP levels 组合而成的. The comparison versions of these values are used to tell Direct3D to interpolate using the Boolean result of a comparison value with the value being fetched(其中的"comparison" 版本系列的枚举值告诉 Direct3D 使用 Boolean布尔值进行差值. .... 无法翻译了).

 

点采样, 也叫最近点采样, 对过滤来说, 是最快的采样类型, 因为是直接从纹理中取值, 不会进行其他的修改; 它是在纹理中找到一个距离 ( 将要映射到三维表面上 ) pixel 中心最近的一个 texel( 纹理采样点)作为最终的采样值.

当纹理的大小被贴图的三维图形大小差不多时, 这种方法确实非常有效和快速; 但是如果大小不同时 , 纹理就需要进行放大或者缩小, 这样的效果就会显得变胖, 变形或者模糊.

 

二线性过滤, 是取 pixel坐标对应在 texture 坐标的四个最近的texel, 然后再取平均值作为采样值, 这样的采样效果会更加平滑; 但他只能作用与同一个 MipMap Level, 他选取 texel pixel 之间大小最近的那一层 MipMap 作为采样层. texel 大小 pixel 大小都匹配的的 Mipmap level有两层时, 双线性过滤有些情况效果就不太好了, 这就诞生了三线性过滤.

 

三线性过滤, 以双线性过滤为基础的, 即现在 pixel 大小都匹配的 texel所在两层 mipmap, 各自进行双线性过滤, 各自产生一个值, 再对这两个只进行差值运算, 最终得到的值作为采样值.没错, 三线性过滤确实在一般情况下能够产生非常理想的效果, 但是但是, 我们现在所讨论的三线性过滤包括双线性过滤都是假设被贴图三维平面是各向同性的, 当表面是各向一行时, 效果还是不太理想的, 这就需要各向异性过滤 Anisotropic Filter.( 如果将要贴图的三维平面是平行与屏幕的, 那就是说该平面是各向同性, 否则是各向异性).

 

各向异性过滤, 是充分考虑了被贴图三维平面的不同方向问题的采用过滤, 效果要比三线性过滤好.

 

 

D3D11_SAMPLER_DESC 下三个成员 :

D3D11_TEXTURE_ADDRESS_MODE    AddressU;
D3D11_TEXTURE_ADDRESS_MODE    AddressV;
D3D11_TEXTURE_ADDRESS_MODE    AddressW;

定义 纹理的地址模式. 纹理坐标是  每个维度 范围是 0.0 到 1.0 ; 纹理地址模式  定义 Direct3D 如何处理那些超过这个 范围的 坐标; U,V 和 R的纹理地址模式 可以是下面的值:

typedef enum D3D11_TEXTURE_ADDRESS_MODE {
    D3D11_TEXTURE_ADDRESS_WRAP ,
    D3D11_TEXTURE_ADDRESS_MIRROR ,
    D3D11_TEXTURE_ADDRESS_CLAMP ,
    D3D11_TEXTURE_ADDRESS_BORDER ,
    D3D11_TEXTURE_ADDRESS_MIRROR_ONCE ,
}D3D11_TEXTURE_ADDRESS_MODE;
在此, 对照TextureMapping::LoadContent()函数来解析部分效果:
// 要绘制的几何体
    VertexPos vertices[] = {

        { XMFLOAT3( 0.5f, 0.5f, 1.0f), XMFLOAT2( 1.0f, 0.0f)}, 
        { XMFLOAT3( 0.5f, -0.5f, 1.0f), XMFLOAT2( 1.0f, 1.0f)}, 
        { XMFLOAT3( -0.5f, -0.5f, 1.0f), XMFLOAT2( 0.0f, 1.0f)},

        { XMFLOAT3( -0.5f, -0.5f, 1.0f), XMFLOAT2( 0.0f, 1.0f)},
        { XMFLOAT3( -0.5f, 0.5f, 1.0f), XMFLOAT2( 0.0f, 0.0f)}, 
        { XMFLOAT3( 0.5f, 0.5f, 1.0f), XMFLOAT2( 1.0f, 0.0f)},
        
    };

几何体( 本例就是 一个 正方形)的顶点集采用 三角形列表形式表示:

 XMFLOAT3( 0.5f, 0.5f, 1.0f),
XMFLOAT3( 0.5f, -0.5f, 1.0f),
XMFLOAT3(
-0.5f, -0.5f, 1.0f), 指示右下角的三角形 XMFLOAT3( -0.5f, -0.5f, 1.0f), XMFLOAT3( -0.5f, 0.5f, 1.0f), XMFLOAT3( 0.5f, 0.5f, 1.0f), 指示 左上角的三角形

这两个三角形构成的 矩形范围在 [-0.5, -0.5] 和 [ 0.5, 0.5] 构成的范围.

 纹理的取值范围 为 [0.0, 0.0] 到 [ 1.0, 1.0]

        { XMFLOAT3( 0.5f, 0.5f, 1.0f)  <----->     XMFLOAT2( 1.0f, 0.0f)}
        { XMFLOAT3( 0.5f, -0.5f, 1.0f)  <----->     XMFLOAT2( 1.0f, 1.0f)} 
        { XMFLOAT3( -0.5f, -0.5f, 1.0f)  <----->     XMFLOAT2( 0.0f, 1.0f)}

        { XMFLOAT3( -0.5f, -0.5f, 1.0f)  <----->   XMFLOAT2( 0.0f, 1.0f)}
        { XMFLOAT3( -0.5f, 0.5f, 1.0f)   <----->    XMFLOAT2( 0.0f, 0.0f)}
        { XMFLOAT3( 0.5f, 0.5f, 1.0f)    <----->    XMFLOAT2( 1.0f, 0.0f)}
        

映射关系为 

最终效果为:

不过这效果的 纹理坐标模式为 

    colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;

现在调整为 :

    colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_MIRROR;

并且纹理地址范围调整为:

     { XMFLOAT3( 0.5f, 0.5f, 1.0f)  <----->     XMFLOAT2( 2.0f, 0.0f)}
        { XMFLOAT3( 0.5f, -0.5f, 1.0f)  <----->     XMFLOAT2( 2.0f, 4.5f)} 
        { XMFLOAT3( -0.5f, -0.5f, 1.0f)  <----->     XMFLOAT2( 0.0f, 4.5f)}

        { XMFLOAT3( -0.5f, -0.5f, 1.0f)  <----->   XMFLOAT2( 0.0f, 4.5f)}
        { XMFLOAT3( -0.5f, 0.5f, 1.0f)   <----->    XMFLOAT2( 0.0f, 0.0f)}
        { XMFLOAT3( 0.5f, 0.5f, 1.0f)    <----->    XMFLOAT2( 2.0f, 0.0f)}

表示, 在纹理的U方向(横向)采取 *2 的映射范围, V方向(纵向)采取 *4.5的映射范围; 纹理的坐标范围是 [ (0,0) , (1, 1) ] 的矩形范围, U向的 (1.0, 2.0] 如何处理呢? 

colorMapDesc.AddressU =D3D11_TEXTURE_ADDRESS_WRAP;表示 直接进行"复制填充"; V向的 (1.0, 4.5] 由
colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_MIRROR; 表示 采用镜像方式绘制:

colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP 效果为( V向 不足部分使用做下边的 色值进行填充):

colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;

colorMapDesc.BorderColor[0] = 0.25f;

将 V方向 纹理坐标不在[ 0.0, 1.0] 范围内的采用 0.25f 猪红颜色填充, 像是边框颜色, 故名 D3D11_TEXTURE_ADDRESS_BORDER :

colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE 呢? 呃.... 稍微复杂点, 引用  迈克老狼2012 的 http://www.cnblogs.com/mikewolf2002/archive/2012/04/08/2437818.html 来说:

D3D11_TEXTURE_ADDRESS_MIRROR_ONCE,则会是下面的效果。对负的u,v坐标取绝对值,所以左,上是镜像的效果,对超过[0,1]范围的正的坐标,使用clamp方式。

 

D3D11_SAMPLER_DESC 的下一个成员 MipLODBias 表示 MIP 的 细节级别偏移量; 例如, 如果 Direct3D当前的 MIP level 为 2 , 偏移 3后, Direct3D就会使用 level=5  的 MIP.

 

下一个值 MaxAnisotropy 是 使用各向异性过滤 时的组大值...( 接下来的暂无法翻译 )

D3D11_COMPARISON_FUNC        ComparisonFunc;

 

BorderColor 是 使用 D3D11_TEXTURE_ADDRESS_BORDER 纹理地址模式时, 设定的 边缘填充颜色.

MinLOD 和 MaxLOD 暂无法理解 和 翻译.

 

下面是 源码TextureMapping 

 

posted @ 2012-12-04 00:58  Wilson-Loo  阅读(2444)  评论(0编辑  收藏  举报