0
votes

I have a vertex and index buffer and I am rendering a mesh to just one pixel and I want to know which triangle of the mesh is rendered and access its index in index buffer on cpu for further process(Base on my mesh only one triangle can rendered to that pixel).

I first implement it with SV_PrimitiveId and I hope it would generate 0 for first three indexes of index buffer (first triangle) and generate 1 for second three indexes and so on.This way I could copy data from gpu and read that id and find the triangle but the problem was that ids did not correspond to my index buffer(ie. As I run the program it gives for example third triangle id 7, the other time 10 and so on).

I want to know is there anyway to determine which triangle is pixel shader drawing and find its index in index buffer to find it on cpu?

1
Since this is a very specific problem, in order to provide adequate assistance, I would require seeing your code, as well as the contents of the vertex and index buffers.beothunder
I wrote some code that does what I think you want to do, and it works perfectly. So there is probably just a bug in your code.beothunder
Did you implement it with sv_primitiveID?Arshia Tahayori
Yes. How else would I implement it?beothunder
Thanks a lot beothunder I checked it again and it worked. I thought my gpu would do early-z divide but it seems it does not so I just fixed that thank you.Arshia Tahayori

1 Answers

0
votes

This should work:

C++:

    ...
    Microsoft::WRL::ComPtr<ID3D11Texture2D>           pPrimitiveIDs;
    Microsoft::WRL::ComPtr<ID3D11RenderTargetView>    pPIDsRTV;
    Microsoft::WRL::ComPtr<ID3D11Texture2D>           pPIDsStaging;
    ...
    const int number_of_rtvs = 2;
    ID3D11RenderTargetView* rtvs[number_of_rtvs] =
    {
        pScreenRTV.Get(),
        pPIDsRTV.Get(),
    };
    pDeviceContext->OMSetRenderTargets(number_of_rtvs, rtvs, pDepthStencilView.Get());
    ...
    pDeviceContext->CopyResource(pPIDStaging.Get(), pPrimitiveIDs.Get());
    D3D11_MAPPED_SUBRESOURCE MappedResource;
    pDeviceContext->Map(pPIDStaging.Get(), 0, D3D11_MAP_READ, 0, &MappedResource);
    // here is the pid
    // in case of a 1x1 back buffer you would just read the first value
    UINT pid = *((UINT*)MappedResource.pData + MouseX + WindowWidth * MouseY);
    pDeviceContext->Unmap(pPIDStaging.Get(), 0);
    ...

Pixel Shader:

struct PSOutput
{
    float4 color : SV_Target0;
    uint pid : SV_Target1;
};

PSOutput main(..., uint pid : SV_PrimitiveId)
{
    ...
    PSOutput output =
    {
        color,
        pid,
    };
    return output;
}