在前面的部落格,我們看到除了紋理資料之外,還有兩個與使用紋理相關的關鍵概念:紋理過濾和定址模式。 取樣紋理資源時使用的過濾器和定址模式由取樣器物件定義, 應用程式通常需要多個取樣器物件以不同方式對紋理進行取樣。
正如我們將在下面看到的,取樣器用於著色器, 為了將取樣器繫結到著色器以供使用,我們需要將描述符繫結到取樣器物件。 以下**顯示了示例根簽名,以便第二個槽採用繫結到取樣器暫存器槽0的乙個取樣器描述符的表。
cd3dx12_descriptor_range descrange[3];
descrange[0].init(d3d12_descriptor_range_type_srv, 1, 0);
descrange[1].init(d3d12_descriptor_range_type_sampler, 1, 0);
descrange[2].init(d3d12_descriptor_range_type_cbv, 1, 0);
cd3dx12_root_parameter rootparameters[3];
rootparameters[0].initasdescriptortable(1, &descrange[0], d3d12_shader_visibility_pixel);
rootparameters[1].initasdescriptortable(1, &descrange[1], d3d12_shader_visibility_pixel);
rootparameters[2].initasdescriptortable(1, &descrange[2], d3d12_shader_visibility_all);
cd3dx12_root_signature_desc descrootsignature;
descrootsignature.init(3, rootparameters, 0, nullptr,
d3d12_root_signature_flag_allow_input_assembler_input_layout);
如果我們要設定sampler描述符,我們需要乙個取樣器堆, 通過填寫d3d12_descriptor_heap_desc例項並指定堆型別d3d12_descriptor_heap_type_sampler來建立取樣器堆:
d3d12_descriptor_heap_desc descheapsampler = {};
descheapsampler.numdescriptors = 1;
descheapsampler.type = d3d12_descriptor_heap_type_sampler;
descheapsampler.flags = d3d12_descriptor_heap_flag_shader_visible;
comptrmsamplerdescriptorheap;
throwiffailed(mdevice->createdescriptorheap(&descheapsampler,
__uuidof(id3d12descriptorheap), (void**)&msamplerdescriptorheap));
一旦我們有乙個取樣器堆,我們就可以建立取樣器描述符。 在這裡我們通過填寫d3d12_sampler_desc物件來指定定址模式和過濾器型別以及其他引數:
typedef struct d3d12_sampler_desc
d3d12_sampler_desc;
我們可以在sdk文件中查詢d3d12_filter列舉型別,以下示例說明如何為堆中的取樣器建立描述符,該取樣器使用線性過濾,換行定址模式和其他引數的典型預設值:
d3d12_sampler_desc samplerdesc = {};
samplerdesc.filter = d3d12_filter_min_mag_mip_linear;
samplerdesc.addressu = d3d12_texture_address_mode_wrap;
samplerdesc.addressv = d3d12_texture_address_mode_wrap;
samplerdesc.addressw = d3d12_texture_address_mode_wrap;
samplerdesc.minlod = 0;
samplerdesc.maxlod = d3d12_float32_max;
samplerdesc.miplodbias = 0.0f;
samplerdesc.maxanisotropy = 1;
samplerdesc.comparisonfunc = d3d12_comparison_func_always;
md3ddevice->createsampler(&samplerdesc,
msamplerdescriptorheap->getcpudescriptorhandleforheapstart());
以下**顯示如何將取樣器描述符繫結到根簽名引數槽以供著色器程式使用:
commandlist->setgraphicsrootdescriptortable(1,
samplerdescriptorheap->getgpudescriptorhandleforheapstart());
事實證明,圖形應用程式通常只使用少數取樣器, 因此,direct3d提供了乙個特殊的快捷方式來定義乙個取樣器陣列並設定它們,而無需經歷建立取樣器堆的過程。 cd3dx12_root_signature_desc類的init函式有兩個引數,允許我們定義應用程式可以使用的所謂靜態取樣器陣列。 靜態取樣器由d3d12_static_sampler_desc結構描述, 此結構與d3d12_sampler_desc非常相似,但有以下例外:
1、border color 可能有一些限制,具體來說,靜態取樣器的border color必須是以下成員:
enum d3d12_static_border_color
d3d12_static_border_color;
2、它包含用於指定著色器暫存器,暫存器空間和著色器可見性的其他字段,通常將其指定為取樣器堆的一部分。
此外,只能定義2032個靜態取樣器,這對於大多數應用來說已經足夠了。
但是,如果確實需要更多,則可以使用非靜態取樣器並通過取樣器堆。
我們在演示中使用靜態取樣器, 以下**顯示了我們如何定義靜態取樣器。 請注意,我們在演示中不需要所有這些靜態取樣器,但我們仍然定義它們,以便在需要它們時它們就在那裡。 無論如何,它只是少數,定義一些可能使用或不使用的額外取樣器並沒有什麼壞處。;}
throwiffailed(hr);
throwiffailed(md3ddevice->createrootsignature(
0,serializedrootsig->getbufferpointer(),
serializedrootsig->getbuffersize(),
iid_ppv_args(mrootsignature.getaddressof())));
}
D3D12渲染技術之渲染管線
渲染管線指的是通過虛擬相機看到的內容生成2d影象的整個步驟序列,在部落格d3d12渲染技術概述中介紹過渲染管線,本篇部落格具體講解各個模組的作用,先看下圖所示 上圖中input assembler stage表示的是從儲存器讀取幾何資料 頂點和索引 並使用它來組裝幾何圖元 例如,三角形,線條 簡單地...
D3D12渲染技術之在著色器中取樣
我們直奔主題,紋理物件在hlsl中定義,並使用以下語法分配給紋理暫存器 texture2d gdiffusemap register t0 這個換成在unity引擎或者ue4引擎中就是提供的視覺化操作介面,而在dx中的表示是按照上面的寫法,這樣可以通過引擎對其進行賦值操作。請注意,紋理暫存器使用由t...
D3D12渲染技術之紋理案例
我們現在回顧一下將紋理新增到箱子模型上面,就跟以前的部落格中提到的那樣。下面我們詳細介紹如何實現?geometrygenerator createbox生成箱子的紋理座標,以便將整個紋理影象對映到箱子的每個面上。為簡潔起見,我們僅顯示正面,背面和頂面的頂點定義。另請注意,我們省略了頂點建構函式中法線...