Consultas de predicação
O exemplo D3D12PredicationQueries demonstra o abate de oclusão usando heaps de consulta do DirectX 12 e a precação. O passo a passo descreve o código adicional necessário para estender o exemplo HelloConstBuffer para lidar com consultas de pré-indicação.
- Criar um heap de descritor de estêncil de profundidade e um heap de consulta de oclusão
- Habilitar a mesclagem alfa
- Desabilitar gravações de cor e profundidade
- Criar um buffer para armazenar os resultados da consulta
- Desenhar os quadriciclos e executar e resolve a consulta de oclusão
- Execute o exemplo
- Tópicos relacionados
Criar um heap de descritor de estêncil de profundidade e um heap de consulta de oclusão
No método LoadPipeline , crie um heap de descritor de estêncil de profundidade.
// Describe and create a depth stencil view (DSV) descriptor heap.
D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
dsvHeapDesc.NumDescriptors = 1;
dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
ThrowIfFailed(m_device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));
Fluxo de chamada | Parâmetros |
---|---|
D3D12_DESCRIPTOR_HEAP_DESC |
[D3D12_DESCRIPTOR_HEAP_FLAG] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_descriptor_heap_flags) |
CreateDescriptorHeap |
No método LoadAssets , crie um heap para consultas de oclusão.
// Describe and create a heap for occlusion queries.
D3D12_QUERY_HEAP_DESC queryHeapDesc = {};
queryHeapDesc.Count = 1;
queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
ThrowIfFailed(m_device->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&m_queryHeap)));
Fluxo de chamada | Parâmetros |
---|---|
D3D12_QUERY_HEAP_DESC | D3D12_QUERY_HEAP_TYPE |
CreateQueryHeap |
Habilitar a mesclagem alfa
Este exemplo desenha dois quadriciclos e ilustra uma consulta de oclusão binária. O quad na frente anima-se pela tela, e o na parte de trás ocasionalmente será occluded. No método LoadAssets, a mesclagem alfa está habilitada para este exemplo para que possamos ver em que ponto d3D considera o quad in back occluded.
// Enable alpha blending so we can visualize the occlusion query results.
CD3DX12_BLEND_DESC blendDesc(CD3DX12_DEFAULT);
blendDesc.RenderTarget[0] =
{
TRUE, FALSE,
D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
D3D12_LOGIC_OP_NOOP,
D3D12_COLOR_WRITE_ENABLE_ALL,
};
Fluxo de chamada | Parâmetros |
---|---|
CD3DX12_BLEND_DESC |
[D3D12_BLEND] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_blend) [D3D12_BLEND_OP] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_blend_op) [D3D12_LOGIC_OP] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_logic_op) [D3D12_COLOR_WRITE_ENABLE] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_color_write_enable) |
Desabilitar gravações de cor e profundidade
A consulta de oclusão é executada renderizando um quad que abrange a mesma área que o quadriciclo cuja visibilidade queremos testar. Em cenas mais complexas, a consulta provavelmente seria um volume delimitado, em vez de um quad simples. Em ambos os casos, um novo estado de pipeline é criado que desabilita a gravação no destino de renderização e o buffer z para que a consulta de oclusão em si não afete a saída visível da passagem de renderização.
No método LoadAssets, desabilite gravações de cor e gravações de profundidade para o estado da consulta de oclusão.
// Disable color writes and depth writes for the occlusion query's state.
psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = 0;
psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_queryState)));
Fluxo de chamada | Parâmetros |
---|---|
D3D12_GRAPHICS_PIPELINE_STATE_DESC | D3D12_DEPTH_WRITE_MASK |
CreateGraphicsPipelineState |
Criar um buffer para armazenar os resultados da consulta
No método LoadAssets , um buffer precisa ser criado para armazenar os resultados da consulta. Cada consulta requer 8 bytes de espaço na memória de GPU. Este exemplo executa apenas uma consulta e, para simplificar e legibilidade, cria um buffer exatamente desse tamanho (embora essa chamada de função aloque uma página de 64K de memória de GPU – a maioria dos aplicativos reais provavelmente criaria um buffer maior).
// Create the query result buffer.
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_DEFAULT);
auto queryBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(8);
ThrowIfFailed(m_device->CreateCommittedResource(
&heapProps,
D3D12_HEAP_FLAG_NONE,
&queryBufferDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&m_queryResult)
));
Fluxo de chamada | Parâmetros |
---|---|
CreateCommittedResource |
[D3D12_HEAP_TYPE] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_heap_type) [D3D12_HEAP_FLAG] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_heap_flags) [CD3DX12_RESOURCE_DESC] (cd3dx12-resource-desc.md) [D3D12_RESOURCE_STATES] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_resource_states) |
Desenhar os quadriciclos e executar e resolve a consulta de oclusão
Após a instalação, o loop main é atualizado no método PopulateCommandLists.
- 1. Desenhe os quadriciclos de trás para frente para fazer com que o efeito de transparência funcione corretamente. Desenhar o quadriciclo de trás para frente é baseado no resultado da consulta do quadro anterior e é uma técnica bastante comum para isso.
2. Altere o PSO para desabilitar as gravações de estêncil de destino e profundidade de renderização.
3. Execute a consulta de oclusão.
4. Resolver a consulta de oclusão.
// Draw the quads and perform the occlusion query.
{
CD3DX12_GPU_DESCRIPTOR_HANDLE cbvFarQuad(m_cbvHeap->GetGPUDescriptorHandleForHeapStart(), m_frameIndex * CbvCountPerFrame, m_cbvSrvDescriptorSize);
CD3DX12_GPU_DESCRIPTOR_HANDLE cbvNearQuad(cbvFarQuad, m_cbvSrvDescriptorSize);
m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
// Draw the far quad conditionally based on the result of the occlusion query
// from the previous frame.
m_commandList->SetGraphicsRootDescriptorTable(0, cbvFarQuad);
m_commandList->SetPredication(m_queryResult.Get(), 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
m_commandList->DrawInstanced(4, 1, 0, 0);
// Disable predication and always draw the near quad.
m_commandList->SetPredication(nullptr, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
m_commandList->SetGraphicsRootDescriptorTable(0, cbvNearQuad);
m_commandList->DrawInstanced(4, 1, 4, 0);
// Run the occlusion query with the bounding box quad.
m_commandList->SetGraphicsRootDescriptorTable(0, cbvFarQuad);
m_commandList->SetPipelineState(m_queryState.Get());
m_commandList->BeginQuery(m_queryHeap.Get(), D3D12_QUERY_TYPE_BINARY_OCCLUSION, 0);
m_commandList->DrawInstanced(4, 1, 8, 0);
m_commandList->EndQuery(m_queryHeap.Get(), D3D12_QUERY_TYPE_BINARY_OCCLUSION, 0);
// Resolve the occlusion query and store the results in the query result buffer
// to be used on the subsequent frame.
m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_queryResult.Get(), D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_COPY_DEST));
m_commandList->ResolveQueryData(m_queryHeap.Get(), D3D12_QUERY_TYPE_BINARY_OCCLUSION, 0, 1, m_queryResult.Get(), 0);
m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_queryResult.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ));
}
Fluxo de chamada | Parâmetros |
---|---|
CD3DX12_GPU_DESCRIPTOR_HANDLE | GetGPUDescriptorHandleForHeapStart |
IASetPrimitiveTopology | D3D_PRIMITIVE_TOPOLOGY |
IASetVertexBuffers | |
SetGraphicsRootDescriptorTable | |
SetPredication | D3D12_PREDICATION_OP |
DrawInstanced | |
SetPredication | D3D12_PREDICATION_OP |
SetGraphicsRootDescriptorTable | |
DrawInstanced | |
SetGraphicsRootDescriptorTable | |
SetPipelineState | |
BeginQuery | D3D12_QUERY_TYPE |
DrawInstanced | |
EndQuery | D3D12_QUERY_TYPE |
ResourceBarrier |
[D3D12_RESOURCE_STATES] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_resource_states) |
ResolveQueryData | D3D12_QUERY_TYPE |
ResourceBarrier |
[D3D12_RESOURCE_STATES] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_resource_states) |
Execute o exemplo
Não cluído:
Obscurecidas:
Parcialmente ocluído:
Tópicos relacionados