0
我想畫一個obj文件的實例。在我實現Instancing而不是通過自己的draw()函數繪製每個對象(工作得很好)之後,Instances定位不正確。可能來自InstanceBuffer的數據未正確設置在着色器中。DX11 C++着色器無法接收實例緩衝區內容
D3DMain.cpp - 創建輸入佈局
struct INSTANCE {
//D3DXMATRIX matTrans;
D3DXVECTOR3
};
/***/
// create the input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
//vertex buffer
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
//instance buffer
{"INSTTRANS", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1},
//{"INSTTRANS", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
//{"INSTTRANS", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
//{"INSTTRANS", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
};
if (FAILED(d3ddev->CreateInputLayout(ied, 4, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout))) throw(std::string("Input Layout Creation Error"));
d3ddevcon->IASetInputLayout(pLayout);
World.cpp - 建立實例緩衝器
std::vector<INSTANCE> instanceBuffer;
INSTANCE insertInstance;
D3DXMATRIX scaleMat, transMat;
D3DXMatrixScaling(&scaleMat, 50.0f, 50.0f, 50.0f);
int i=0;
for (std::list<SINSTANCES>::iterator it = sInstances.begin(); it != sInstances.end(); it++) {
if ((*it).TypeID == typeId) {
//do something
D3DXMatrixTranslation(&transMat, (*it).pos.x, (*it).pos.y, (*it).pos.z);
insertInstance.matTrans = (*it).pos;//scaleMat * transMat;
instanceBuffer.push_back(insertInstance);
i++;
}
}
instanceCount[typeId] = i;
//create new IB
D3D11_BUFFER_DESC instanceBufferDesc;
ZeroMemory(&instanceBufferDesc, sizeof(instanceBufferDesc));
instanceBufferDesc.Usage = D3D11_USAGE_DEFAULT;
instanceBufferDesc.ByteWidth = sizeof(INSTANCE) * i;
instanceBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
instanceBufferDesc.CPUAccessFlags = 0;
instanceBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA instanceData;
ZeroMemory(&instanceData, sizeof(instanceData));
instanceData.pSysMem = &instanceBuffer[0];
if (FAILED(d3ddev->CreateBuffer(&instanceBufferDesc, &instanceData, &instanceBufferMap[typeId]))) throw(std::string("Failed to Update Instance Buffer"));
OpenDrawObj.cpp - 圖紙obj文件
UINT stride[2] = {sizeof(VERTEX), sizeof(INSTANCE)};
UINT offset[2] = {0, 0};
ID3D11Buffer* combinedBuffer[2] = {meshVertBuff, instanceBuffer};
d3ddevcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
d3ddevcon->IASetVertexBuffers(0, 2, combinedBuffer, stride, offset);
d3ddevcon->IASetIndexBuffer(meshIndexBuff, DXGI_FORMAT_R32_UINT, 0);
std::map<std::wstring, OBJMATERIAL>::iterator fit;
for (std::vector<DRAWLIST>::iterator it = drawList.begin(); it != drawList.end(); it++) {
fit = objMaterials.find((*it).material);
if (fit != objMaterials.end()) {
if ((*fit).second.texture != NULL) {
d3ddevcon->PSSetShaderResources(0, 1, &((*fit).second.texture));
}
d3ddevcon->DrawIndexedInstanced((*it).indexCount, instanceCount, (*it).startIndex, 0, 0);
}
}
繪圖函數(上面)在這裏被調用:我傳遞實例緩衝區(map(int,ID3D11Buffer *)和實例號)
(*it).second->draw(0.0f, 0.0f, 0.0f, 0, instanceBufferMap[typeId], instanceCount[typeId]);
在最後一個文件shader.hlsl
struct VIn
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD;
//row_major float4x4 instTrans : INSTTRANS;
float4 instTrans : INSTTRANS;
uint instanceID : SV_InstanceID;
};
VOut VShader(VIn input)
{
VOut output;
//first: transforming instance
//output.position = mul(input.instTrans, input.position);
output.position = input.position;
output.position.xyz *= 50.0; //scale
output.position.z += input.instTrans.z; //apply only z value
float4 transPos = mul(world, output.position); //transform position with world matrix
output.position = mul(view, transPos); //project to screen
的 「input.instTrans」 是不正確的,包含ramdom數據。 你有什麼想法嗎?
沒有什麼突出顯然是錯誤的。我想到的一個問題是,D3D11_APPEND_ALIGNED_ELEMENT可能不適用於多個頂點流,也許它不會像您所期望的那樣將INSTTRANS元素的偏移量設置爲0,16,32,48。 另一件嘗試將通過一個單一的float4(不是一個矩陣),只是嘗試和翻譯工作,然後移動到整個矩陣與規模英寸 –
我試圖通過只是翻譯向量,只適用於x分量到頂點位置。我也將'D3D11_APPEND_ALIGNED_ELEMENT'更改爲手動偏移。這就是調整之後的樣子:有趣的是,當相機移動時,這個「條」的長度會發生變化。 是否有可能通過多個函數傳遞實例緩衝區作爲參數造成任何損害? – cbacon
您是否使用PIX For Windows,VS2012/2013的Pro +版本,AMD GPU PerfStudio,Nvidia nSight或Intel GPA內置的圖形調試器?他們都應該能夠向您展示頂點緩衝區,並告訴您錯誤的位置。 或者,如果您可以提供可執行文件或可編譯/可運行的項目,那麼我們可能有更好的機會進入它的底部。 –