2017-09-29 95 views
2

我读的书, “实用渲染和计算用的Direct3D 11” 来看,在DirectX 11的样品:的DirectX 11如何操作顶点和像素着色工作

CPP: https://github.com/walbourn/directx-sdk-samples/blob/master/Direct3D11Tutorials/Tutorial02/Tutorial02.cpp

HLSL: https://github.com/walbourn/directx-sdk-samples/blob/master/Direct3D11Tutorials/Tutorial02/Tutorial02.fx

这是什么?

D3D11_INPUT_ELEMENT_DESC layout[] = 
{ 
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 
}; 

更重要的是着色器 - 凡在节目它设置这个“正”?

float4 VS(float4 Pos : POSITION) : SV_POSITION 
{ 
    return Pos; 
} 

我只能看到你通过结合顶点数据:

// Create vertex buffer 
SimpleVertex vertices[] = 
{ 
    XMFLOAT3(0.0f, 0.5f, 0.5f), 
    XMFLOAT3(0.5f, -0.5f, 0.5f), 
    XMFLOAT3(-0.5f, -0.5f, 0.5f), 
}; 
D3D11_BUFFER_DESC bd; 
ZeroMemory(&bd, sizeof(bd)); 
bd.Usage = D3D11_USAGE_DEFAULT; 
bd.ByteWidth = sizeof(SimpleVertex) * 3; 
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; 
bd.CPUAccessFlags = 0; 
D3D11_SUBRESOURCE_DATA InitData; 
ZeroMemory(&InitData, sizeof(InitData)); 
InitData.pSysMem = vertices; 
hr = g_pd3dDevice->CreateBuffer(&bd, &InitData, &g_pVertexBuffer); 
if(FAILED(hr)) 
    return hr; 

// Set vertex buffer 
UINT stride = sizeof(SimpleVertex); 
UINT offset = 0; 
g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset); 

// Set primitive topology 
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 

然后你要设置的着色器,然后绘制3个verticies:

// Render a triangle 
g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0); 
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0); 
g_pImmediateContext->Draw(3, 0); 

这一切都有道理。但是我对这个Pos输入是什么,它是如何生成的以及为什么使用它感到困惑?此外,还有其他一些例子可以做同样的事情......(样本7)他们使用了位置和纹理,但我看不到这些信息来自哪里。例如...

struct VS_INPUT 
{ 
    float4 Pos : POSITION; 
    float2 Tex : TEXCOORD0; 
}; 

谢谢你的时间!

+0

在这种情况下,POSITION是物体空间中的顶点位置 – Asesh

回答

1

D3D11_INPUT_ELEMENT_DESC的数组决定了将从顶点缓冲区读取的数据的布局。该数组传递给ID3D11Device::CreateInputLayout调用,以便可以使用它。然后通过调用ID3D11DeviceContext::IASetInputLayout(未显示,但在您链接的代码中)在渲染上下文中设置它。

如果看一下的D3D11_INPUT_ELEMENT_DESC成员,所述第一构件是SemanticName(设置为"POSITION"),这是顶点缓冲器的元件如何被匹配到在着色器输入。它还包含有关数据偏移量和格式的数据(在这种情况下,偏移量为零,格式DXGI_FORMAT_R32G32B32_FLOAT对应于3x 32位浮点数)。您会注意到,在着色器中,Pos之后有一个冒号,然后是"POSITION" - 这是语义,并且与输入布局相匹配。着色器然后知道它应该从零偏移读取位置数据以及该数据的格式。

数据本身是从顶点缓冲区读取的,使用ID3D11DeviceContext::IASetVertexBuffers调用进行设置。参数stride告诉输入汇编器从一个顶点到下一个顶点缓冲区的距离,所以它知道从哪里开始读下一个顶点。传入的g_pVertexBuffer已从vertices数据初始化,您可以看到这是一组3x 32位浮点数。

对于具有附加输入(例如TEXCOORD0)的着色器,D3D11_INPUT_ELEMENT_DESC数组中会有更多的条目,与着色器中使用的语义相对应。

+0

好吧!如果你想使用自定义变量呢?您将不得不将其编码到纹理或顶点缓冲区中?谢谢! – Mike5050

+0

只要匹配输入布局和着色器,您就可以使用任何您喜欢的语义。 – MuertoExcobito

+0

https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx#VS - 所以你必须使用语义是什么即时通讯尝试说?你不能自己制作?我猜这个语义告诉HLSL它将如何表现?例如,您可以在POSITION(3 32位值)内有TEXCOORD0(2 32位值)并忽略z。正确? – Mike5050

相关问题