采样器对象定义了采集纹理时所用的过滤器和寻址模式。
1.创建描述符堆
创建采样器堆,用以存储采样器描述符。
下例中创建1个类型为采样器描述符的堆,并使之在着色器中可见(即可供着色器使用)。
D3D12_DESCRIPTOR_HEAP_DESC heapSampler = {};
heapSampler.NumDescriptors = 1;
heapSampler.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
heapSampler.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
ComPtr<ID3D12DescriptorHeap> mSamplerDes;
ThrowIfFailed(md3dDevice->CreateDescriptorHeap(&heapSampler,__uuidof(ID3D12DescriptorHeap), (void**)(&mSamplerDes)));
2.创建采样器
通过结构体D3D12_SAMPLER_DESC指定采样器的寻址模式,过滤器类型等参数。
typedef struct D3D12_STATIC_SAMPLER_DESC
{
D3D12_FILTER Filter; //采样纹理时的过滤方式
D3D12_TEXTURE_ADDRESS_MODE AddressU; //U方向的寻址模式
D3D12_TEXTURE_ADDRESS_MODE AddressV; //V方向的寻址模式
D3D12_TEXTURE_ADDRESS_MODE AddressW; //W方向的寻址模式
FLOAT MipLODBias; //mipmap层级的偏置值
UINT MaxAnisotropy; //最大各向异性值
D3D12_COMPARISON_FUNC ComparisonFunc; //实现阴影贴图这类特殊应用的选项
D3D12_STATIC_BORDER_COLOR BorderColor; //border寻址模式下的边框颜色
FLOAT MinLOD; //可供选择的最小mipmap层级
FLOAT MaxLOD; //可供选择的最大mipmap层级
UINT ShaderRegister;
UINT RegisterSpace;
D3D12_SHADER_VISIBILITY ShaderVisibility;
} D3D12_STATIC_SAMPLER_DESC;
下例中创建采样器,它采用线性过滤和重复寻址方式。
D3D12_SAMPLER_DESC des = {};
des.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
des.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
des.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
des.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
des.MinLOD = 0;
des.MaxLOD = D3D12_FLOAT32_MAX;
des.MipLODBias = 0.0f;
des.MaxAnisotropy = 1;
des.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
md3dDevice->CreateSampler(&des, mSamplerDes->GetCPUDescriptorHandleForHeapStart());
3.将采样器绑定到流水线
首先,看一下根签名,它的槽1获取了一个描述符表,此表中存有一个采样器描述符。
CD3DX12_DESCRIPTOR_RANGE descRange[2];
descRange[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV,1,0);
descRange[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);
CD3DX12_ROOT_PARAMETER para[2];
para[0].InitAsDescriptorTable(1,&descRange[0], D3D12_SHADER_VISIBILITY_PIXEL);
para[1].InitAsDescriptorTable(1, &descRange[1], D3D12_SHADER_VISIBILITY_PIXEL);
CD3DX12_ROOT_SIGNATURE_DESC rootSignature;
rootSignature.Init(2,para,0,nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
将采样器描述符绑定到根签名参数槽1,以供着色器使用。
mCommandList->SetGraphicsRootDescriptorTable(1,mSampler->GetGPUDescriptorHandleForHeapStart());