SV_PrimitiveID 和 direct3D 11 中的图元
SV_PrimitiveID and primitives in direct3D 11
我在文档中看到 SV_PrimitiveID 语义,它说它为每个原语创建一个 ID
在每次绘制调用中都是独一无二的。
我在几何着色器中看到了这种语义,但我对术语 primitive 感到困惑。
我有一个带有立方体和球体顶点的顶点缓冲区,SV_PrimitiveID 索引立方体顶点 0 和球体 1 或者对于顶点缓冲区中的每个三角形它给出一个数字(想象 GS输入三角形列表)。
我也不知道第一种情况是否正确,当它们都在一个顶点缓冲区中时,如何区分立方体和球体。
SV_PrimitiveID
的含义由D3D11_PRIMITIVE_TOPOLOGY
决定(由ID3D11DeviceContext::IASetPrimitiveTopology
设置)。每个绘图调用都会为每个图元分配一个编号,以便绘制图元。
例如:
// buffers that will be copied to the gpu
struct Vertex { float X, Y, Z; } VertexData[6] =
{
{ 0, 0, 0 },
{ 1, 0, 0 },
{ 1, 1, 0 },
{ 1, 1, 0 },
{ 0, 1, 0 },
{ 0, 0, 0 },
};
struct Triangle { int A, B, C; } IndexData[2] =
{
{ 0, 1, 2 },// SV_PrimitiveID == 0
{ 2, 4, 0 },// SV_PrimitiveID == 1
};
struct Instance { float X, Y, Z; } InstanceData[2] =
{
{ 0, 0, 0 },// SV_InstanceID == 0
{ 0, 0, 1 },// SV_InstanceID == 1
};
...
pDeviceConstext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
pDeviceConstext->Draw(6, 0);// would result in two triangles numbered (value of SV_PrimitiveID) 0 and 1
pDeviceConstext->DrawIndexed(2 * 3, 0, 0);// same thing
pDeviceConstext->DrawInstanced(6, 2, 0, 0);// now 4 triangles, 2 for the 0th instance and 2 for the 1st; SV_PrimitiveID restarts from zero for every instance!
...
我不确定几何着色器和 SV_PrimitiveID 之间的交互,但 DirectX 有详细的文档记录。以下是一些链接:
https://docs.microsoft.com/en-us/windows/win32/direct3d11/geometry-shader-stage
https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-geometry-shader
我个人认为直观地显示任何我可能会感到困惑的信息很有用。例如设置像这样的像素着色器:
float4 main(uint pid : SV_PrimitiveId) : SV_Target
{
static const uint N = 16;
float3 color = float3(((pid / uint3(1, N, N * N)) % N) / (float)N);
return float4(color, 1);
}
我在文档中看到 SV_PrimitiveID 语义,它说它为每个原语创建一个 ID 在每次绘制调用中都是独一无二的。
我在几何着色器中看到了这种语义,但我对术语 primitive 感到困惑。 我有一个带有立方体和球体顶点的顶点缓冲区,SV_PrimitiveID 索引立方体顶点 0 和球体 1 或者对于顶点缓冲区中的每个三角形它给出一个数字(想象 GS输入三角形列表)。 我也不知道第一种情况是否正确,当它们都在一个顶点缓冲区中时,如何区分立方体和球体。
SV_PrimitiveID
的含义由D3D11_PRIMITIVE_TOPOLOGY
决定(由ID3D11DeviceContext::IASetPrimitiveTopology
设置)。每个绘图调用都会为每个图元分配一个编号,以便绘制图元。
例如:
// buffers that will be copied to the gpu
struct Vertex { float X, Y, Z; } VertexData[6] =
{
{ 0, 0, 0 },
{ 1, 0, 0 },
{ 1, 1, 0 },
{ 1, 1, 0 },
{ 0, 1, 0 },
{ 0, 0, 0 },
};
struct Triangle { int A, B, C; } IndexData[2] =
{
{ 0, 1, 2 },// SV_PrimitiveID == 0
{ 2, 4, 0 },// SV_PrimitiveID == 1
};
struct Instance { float X, Y, Z; } InstanceData[2] =
{
{ 0, 0, 0 },// SV_InstanceID == 0
{ 0, 0, 1 },// SV_InstanceID == 1
};
...
pDeviceConstext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
pDeviceConstext->Draw(6, 0);// would result in two triangles numbered (value of SV_PrimitiveID) 0 and 1
pDeviceConstext->DrawIndexed(2 * 3, 0, 0);// same thing
pDeviceConstext->DrawInstanced(6, 2, 0, 0);// now 4 triangles, 2 for the 0th instance and 2 for the 1st; SV_PrimitiveID restarts from zero for every instance!
...
我不确定几何着色器和 SV_PrimitiveID 之间的交互,但 DirectX 有详细的文档记录。以下是一些链接:
https://docs.microsoft.com/en-us/windows/win32/direct3d11/geometry-shader-stage https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-geometry-shader
我个人认为直观地显示任何我可能会感到困惑的信息很有用。例如设置像这样的像素着色器:
float4 main(uint pid : SV_PrimitiveId) : SV_Target
{
static const uint N = 16;
float3 color = float3(((pid / uint3(1, N, N * N)) % N) / (float)N);
return float4(color, 1);
}